-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmigration.sql
More file actions
executable file
·197 lines (173 loc) · 8.08 KB
/
migration.sql
File metadata and controls
executable file
·197 lines (173 loc) · 8.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
-- ChittyReception Database Schema Migration
-- Add to shared chittyos-core Neon PostgreSQL database
-- Run with: psql "$NEON_DATABASE_URL" < migration.sql
-- Enable UUID extension if not already enabled
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- ============================================================================
-- CHITTYRECEPTION TABLES
-- ============================================================================
-- Reception calls table
-- Tracks all inbound and outbound calls through OpenPhone
CREATE TABLE IF NOT EXISTS reception_calls (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
identity_id UUID NOT NULL REFERENCES identities(id) ON DELETE CASCADE,
call_id VARCHAR(255) NOT NULL UNIQUE, -- OpenPhone call ID
direction VARCHAR(10) NOT NULL CHECK (direction IN ('inbound', 'outbound')),
from_number VARCHAR(50) NOT NULL,
to_number VARCHAR(50) NOT NULL,
status VARCHAR(50) NOT NULL DEFAULT 'initiated', -- initiated, ringing, answered, completed, failed, no-answer
duration_seconds INTEGER, -- call duration in seconds
recording_url TEXT, -- URL to call recording if available
transcription TEXT, -- AI transcription of the call
metadata JSONB DEFAULT '{}', -- Additional OpenPhone metadata
started_at TIMESTAMPTZ DEFAULT NOW(),
answered_at TIMESTAMPTZ,
ended_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Reception messages table
-- Tracks all SMS messages through OpenPhone
CREATE TABLE IF NOT EXISTS reception_messages (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
identity_id UUID NOT NULL REFERENCES identities(id) ON DELETE CASCADE,
message_id VARCHAR(255) NOT NULL UNIQUE, -- OpenPhone message ID
direction VARCHAR(10) NOT NULL CHECK (direction IN ('inbound', 'outbound')),
from_number VARCHAR(50) NOT NULL,
to_number VARCHAR(50) NOT NULL,
body TEXT NOT NULL, -- Message content
status VARCHAR(50) DEFAULT 'sent', -- sent, delivered, read, failed
metadata JSONB DEFAULT '{}', -- Additional OpenPhone metadata
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Identity phone numbers table
-- Maps phone numbers to ChittyID identities for caller resolution
CREATE TABLE IF NOT EXISTS identity_phones (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
identity_id UUID NOT NULL REFERENCES identities(id) ON DELETE CASCADE,
phone_number VARCHAR(50) NOT NULL,
verified BOOLEAN DEFAULT false,
verified_at TIMESTAMPTZ,
primary_phone BOOLEAN DEFAULT false, -- Is this the primary phone for this identity
metadata JSONB DEFAULT '{}', -- Carrier info, etc.
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(identity_id, phone_number)
);
-- Reception sessions table
-- Tracks conversation sessions across multiple calls/messages
CREATE TABLE IF NOT EXISTS reception_sessions (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
identity_id UUID NOT NULL REFERENCES identities(id) ON DELETE CASCADE,
phone_number VARCHAR(50) NOT NULL,
status VARCHAR(50) DEFAULT 'active', -- active, closed, escalated
context JSONB DEFAULT '{}', -- AI context and conversation state
ai_summary TEXT, -- AI-generated summary of the session
last_interaction_at TIMESTAMPTZ DEFAULT NOW(),
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- ============================================================================
-- INDEXES FOR PERFORMANCE
-- ============================================================================
-- Reception calls indexes
CREATE INDEX IF NOT EXISTS idx_reception_calls_identity_id ON reception_calls(identity_id);
CREATE INDEX IF NOT EXISTS idx_reception_calls_call_id ON reception_calls(call_id);
CREATE INDEX IF NOT EXISTS idx_reception_calls_from_number ON reception_calls(from_number);
CREATE INDEX IF NOT EXISTS idx_reception_calls_to_number ON reception_calls(to_number);
CREATE INDEX IF NOT EXISTS idx_reception_calls_status ON reception_calls(status);
CREATE INDEX IF NOT EXISTS idx_reception_calls_started_at ON reception_calls(started_at DESC);
-- Reception messages indexes
CREATE INDEX IF NOT EXISTS idx_reception_messages_identity_id ON reception_messages(identity_id);
CREATE INDEX IF NOT EXISTS idx_reception_messages_message_id ON reception_messages(message_id);
CREATE INDEX IF NOT EXISTS idx_reception_messages_from_number ON reception_messages(from_number);
CREATE INDEX IF NOT EXISTS idx_reception_messages_to_number ON reception_messages(to_number);
CREATE INDEX IF NOT EXISTS idx_reception_messages_created_at ON reception_messages(created_at DESC);
-- Identity phones indexes
CREATE INDEX IF NOT EXISTS idx_identity_phones_identity_id ON identity_phones(identity_id);
CREATE INDEX IF NOT EXISTS idx_identity_phones_phone_number ON identity_phones(phone_number);
CREATE INDEX IF NOT EXISTS idx_identity_phones_verified ON identity_phones(verified);
-- Reception sessions indexes
CREATE INDEX IF NOT EXISTS idx_reception_sessions_identity_id ON reception_sessions(identity_id);
CREATE INDEX IF NOT EXISTS idx_reception_sessions_phone_number ON reception_sessions(phone_number);
CREATE INDEX IF NOT EXISTS idx_reception_sessions_status ON reception_sessions(status);
CREATE INDEX IF NOT EXISTS idx_reception_sessions_last_interaction ON reception_sessions(last_interaction_at DESC);
-- ============================================================================
-- TRIGGERS FOR UPDATED_AT
-- ============================================================================
-- Function to update updated_at timestamp
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- Apply updated_at trigger to all ChittyReception tables
CREATE TRIGGER update_reception_calls_updated_at
BEFORE UPDATE ON reception_calls
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_reception_messages_updated_at
BEFORE UPDATE ON reception_messages
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_identity_phones_updated_at
BEFORE UPDATE ON identity_phones
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_reception_sessions_updated_at
BEFORE UPDATE ON reception_sessions
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
-- ============================================================================
-- VIEWS FOR COMMON QUERIES
-- ============================================================================
-- View for call history with identity details
CREATE OR REPLACE VIEW reception_call_history AS
SELECT
c.id,
c.call_id,
c.direction,
c.from_number,
c.to_number,
c.status,
c.duration_seconds,
c.started_at,
c.ended_at,
i.did as identity_did,
i.metadata as identity_metadata
FROM reception_calls c
JOIN identities i ON c.identity_id = i.id
ORDER BY c.started_at DESC;
-- View for message history with identity details
CREATE OR REPLACE VIEW reception_message_history AS
SELECT
m.id,
m.message_id,
m.direction,
m.from_number,
m.to_number,
m.body,
m.status,
m.created_at,
i.did as identity_did,
i.metadata as identity_metadata
FROM reception_messages m
JOIN identities i ON m.identity_id = i.id
ORDER BY m.created_at DESC;
-- ============================================================================
-- GRANT PERMISSIONS (if using specific roles)
-- ============================================================================
-- Grant permissions to application role (adjust as needed)
-- GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO chittyos_app;
-- GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO chittyos_app;
-- ============================================================================
-- MIGRATION VERIFICATION
-- ============================================================================
-- Verify tables were created
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'reception_calls') THEN
RAISE NOTICE 'ChittyReception tables created successfully';
ELSE
RAISE EXCEPTION 'ChittyReception table creation failed';
END IF;
END $$;