| |
| CREATE TABLE IF NOT EXISTS users ( |
| wa_id TEXT PRIMARY KEY, |
| name TEXT NOT NULL DEFAULT 'Unknown', |
| created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), |
| updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() |
| ); |
|
|
| |
| CREATE TABLE IF NOT EXISTS chat_sessions ( |
| id UUID PRIMARY KEY DEFAULT gen_random_uuid(), |
| wa_id TEXT NOT NULL REFERENCES users(wa_id) ON DELETE CASCADE, |
| started_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), |
| last_activity TIMESTAMP WITH TIME ZONE DEFAULT NOW(), |
| ended BOOLEAN DEFAULT FALSE |
| ); |
|
|
| |
| CREATE TABLE IF NOT EXISTS messages ( |
| id UUID PRIMARY KEY DEFAULT gen_random_uuid(), |
| session_id UUID NOT NULL REFERENCES chat_sessions(id) ON DELETE CASCADE, |
| wa_id TEXT NOT NULL REFERENCES users(wa_id) ON DELETE CASCADE, |
| wamid TEXT NOT NULL, |
| role TEXT NOT NULL CHECK (role IN ('user', 'assistant')), |
| content TEXT NOT NULL, |
| created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() |
| ); |
|
|
| |
| CREATE TABLE IF NOT EXISTS personas ( |
| wa_id TEXT PRIMARY KEY REFERENCES users(wa_id) ON DELETE CASCADE, |
| language TEXT, |
| tone TEXT, |
| intent TEXT, |
| budget TEXT, |
| size_preference_sqm TEXT, |
| location_preference TEXT, |
| must_have TEXT[], |
| created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), |
| updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() |
| ); |
|
|
| |
| CREATE INDEX IF NOT EXISTS idx_users_created_at ON users(created_at DESC); |
| CREATE INDEX IF NOT EXISTS idx_users_updated_at ON users(updated_at DESC); |
| CREATE INDEX IF NOT EXISTS idx_chat_sessions_wa_id ON chat_sessions(wa_id); |
| CREATE INDEX IF NOT EXISTS idx_chat_sessions_last_activity ON chat_sessions(last_activity DESC); |
| CREATE INDEX IF NOT EXISTS idx_chat_sessions_ended ON chat_sessions(ended); |
| CREATE INDEX IF NOT EXISTS idx_messages_session_id ON messages(session_id); |
| CREATE INDEX IF NOT EXISTS idx_messages_wa_id ON messages(wa_id); |
| CREATE INDEX IF NOT EXISTS idx_messages_created_at ON messages(created_at DESC); |
| CREATE INDEX IF NOT EXISTS idx_messages_wamid ON messages(wamid); |
| CREATE INDEX IF NOT EXISTS idx_personas_wa_id ON personas(wa_id); |
| CREATE INDEX IF NOT EXISTS idx_personas_updated_at ON personas(updated_at DESC); |
|
|
| |
| ALTER TABLE users ENABLE ROW LEVEL SECURITY; |
| ALTER TABLE chat_sessions ENABLE ROW LEVEL SECURITY; |
| ALTER TABLE messages ENABLE ROW LEVEL SECURITY; |
| ALTER TABLE personas ENABLE ROW LEVEL SECURITY; |
|
|
| |
| CREATE POLICY "Allow all operations on users" ON users |
| FOR ALL USING (true); |
|
|
| CREATE POLICY "Allow all operations on chat_sessions" ON chat_sessions |
| FOR ALL USING (true); |
|
|
| CREATE POLICY "Allow all operations on messages" ON messages |
| FOR ALL USING (true); |
|
|
| CREATE POLICY "Allow all operations on personas" ON personas |
| FOR ALL USING (true); |
|
|
| |
| CREATE OR REPLACE FUNCTION update_updated_at_column() |
| RETURNS TRIGGER AS $$ |
| BEGIN |
| NEW.updated_at = NOW(); |
| RETURN NEW; |
| END; |
| $$ language 'plpgsql'; |
|
|
| |
| CREATE TRIGGER update_users_updated_at |
| BEFORE UPDATE ON users |
| FOR EACH ROW |
| EXECUTE FUNCTION update_updated_at_column(); |
|
|
| |
| CREATE OR REPLACE FUNCTION update_last_activity_column() |
| RETURNS TRIGGER AS $$ |
| BEGIN |
| NEW.last_activity = NOW(); |
| RETURN NEW; |
| END; |
| $$ language 'plpgsql'; |
|
|
| CREATE TRIGGER update_chat_sessions_last_activity |
| BEFORE UPDATE ON chat_sessions |
| FOR EACH ROW |
| EXECUTE FUNCTION update_last_activity_column(); |
|
|
| |
| CREATE TRIGGER update_personas_updated_at |
| BEFORE UPDATE ON personas |
| FOR EACH ROW |
| EXECUTE FUNCTION update_updated_at_column(); |