Phase 3 scaffold: chat engine (WebSocket, FCM, pricing, timer, extension, history)
- Backend: WebSocket plugin, chat/pricing/timer/extension/closure/notification services - Client app: ChatBloc, pricing dialog, chat screen with message status, extension/goodbye flow, history - Mitra app: MitraChatBloc, ExtensionBloc, chat screen, extension accept/reject, history - Control center: free trial, extension timeout, early end config toggles - DB migration: chat_messages, session_closures, session_extensions, customer_transactions tables Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -142,6 +142,125 @@ const migrate = async () => {
|
||||
ON CONFLICT (key) DO NOTHING
|
||||
`
|
||||
|
||||
// --- Phase 3: Chat Engine ---
|
||||
|
||||
// Add session duration/pricing columns to chat_sessions
|
||||
await sql`
|
||||
ALTER TABLE chat_sessions
|
||||
ADD COLUMN IF NOT EXISTS duration_minutes INT,
|
||||
ADD COLUMN IF NOT EXISTS price INT DEFAULT 0,
|
||||
ADD COLUMN IF NOT EXISTS is_free_trial BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
ADD COLUMN IF NOT EXISTS expires_at TIMESTAMPTZ,
|
||||
ADD COLUMN IF NOT EXISTS extended_minutes INT NOT NULL DEFAULT 0
|
||||
`
|
||||
|
||||
// Add FCM token columns
|
||||
await sql`
|
||||
ALTER TABLE customers
|
||||
ADD COLUMN IF NOT EXISTS fcm_token VARCHAR(255)
|
||||
`
|
||||
|
||||
await sql`
|
||||
ALTER TABLE mitras
|
||||
ADD COLUMN IF NOT EXISTS fcm_token VARCHAR(255)
|
||||
`
|
||||
|
||||
await sql`
|
||||
CREATE TABLE IF NOT EXISTS chat_messages (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
session_id UUID NOT NULL REFERENCES chat_sessions(id),
|
||||
sender_type VARCHAR(10) NOT NULL,
|
||||
sender_id UUID NOT NULL,
|
||||
type VARCHAR(20) NOT NULL DEFAULT 'text',
|
||||
content TEXT NOT NULL,
|
||||
metadata JSONB,
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'sent',
|
||||
delivered_at TIMESTAMPTZ,
|
||||
read_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
)
|
||||
`
|
||||
|
||||
await sql`
|
||||
CREATE INDEX IF NOT EXISTS idx_chat_messages_session_created
|
||||
ON chat_messages (session_id, created_at)
|
||||
`
|
||||
|
||||
await sql`
|
||||
CREATE INDEX IF NOT EXISTS idx_chat_messages_session_status
|
||||
ON chat_messages (session_id, status)
|
||||
`
|
||||
|
||||
await sql`
|
||||
CREATE TABLE IF NOT EXISTS session_closures (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
session_id UUID NOT NULL REFERENCES chat_sessions(id),
|
||||
user_type VARCHAR(10) NOT NULL,
|
||||
user_id UUID NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
)
|
||||
`
|
||||
|
||||
await sql`
|
||||
CREATE TABLE IF NOT EXISTS session_extensions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
session_id UUID NOT NULL REFERENCES chat_sessions(id),
|
||||
requested_duration_minutes INT NOT NULL,
|
||||
requested_price INT NOT NULL,
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'pending',
|
||||
requested_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
responded_at TIMESTAMPTZ
|
||||
)
|
||||
`
|
||||
|
||||
await sql`
|
||||
CREATE TABLE IF NOT EXISTS customer_transactions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
customer_id UUID NOT NULL REFERENCES customers(id),
|
||||
session_id UUID NOT NULL REFERENCES chat_sessions(id),
|
||||
type VARCHAR(20) NOT NULL,
|
||||
amount INT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
)
|
||||
`
|
||||
|
||||
await sql`
|
||||
CREATE INDEX IF NOT EXISTS idx_customer_transactions_customer_id
|
||||
ON customer_transactions (customer_id)
|
||||
`
|
||||
|
||||
// Phase 3 config keys
|
||||
await sql`
|
||||
INSERT INTO app_config (key, value)
|
||||
VALUES ('free_trial_enabled', '{"value": true}')
|
||||
ON CONFLICT (key) DO NOTHING
|
||||
`
|
||||
|
||||
await sql`
|
||||
INSERT INTO app_config (key, value)
|
||||
VALUES ('free_trial_duration_minutes', '{"value": 5}')
|
||||
ON CONFLICT (key) DO NOTHING
|
||||
`
|
||||
|
||||
await sql`
|
||||
INSERT INTO app_config (key, value)
|
||||
VALUES ('extension_timeout_seconds', '{"value": 60}')
|
||||
ON CONFLICT (key) DO NOTHING
|
||||
`
|
||||
|
||||
await sql`
|
||||
INSERT INTO app_config (key, value)
|
||||
VALUES ('early_end_mitra_enabled', '{"value": false}')
|
||||
ON CONFLICT (key) DO NOTHING
|
||||
`
|
||||
|
||||
await sql`
|
||||
INSERT INTO app_config (key, value)
|
||||
VALUES ('early_end_customer_enabled', '{"value": false}')
|
||||
ON CONFLICT (key) DO NOTHING
|
||||
`
|
||||
|
||||
console.log('Migration complete.')
|
||||
await sql.end()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user