-- Todo App Database Schema -- Phase II + Phase III - Full-Stack Web Application with AI Chatbot -- Execute this script in Neon PostgreSQL Console -- ============================================ -- Phase II: Core Tables -- ============================================ -- Users table (managed by Better Auth) CREATE TABLE IF NOT EXISTS users ( id TEXT PRIMARY KEY, email TEXT UNIQUE NOT NULL, name TEXT, hashed_password TEXT NOT NULL, created_at TIMESTAMP DEFAULT NOW() ); -- Tasks table (our application) CREATE TABLE IF NOT EXISTS tasks ( id SERIAL PRIMARY KEY, user_id TEXT NOT NULL, title VARCHAR(200) NOT NULL, description TEXT, completed BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW(), FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ); -- ============================================ -- Phase III: AI Chatbot Tables -- ============================================ -- Conversations table CREATE TABLE IF NOT EXISTS conversations ( id SERIAL PRIMARY KEY, user_id TEXT NOT NULL, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW(), FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ); -- Messages table CREATE TABLE IF NOT EXISTS messages ( id SERIAL PRIMARY KEY, user_id TEXT NOT NULL, conversation_id INTEGER NOT NULL, role VARCHAR(20) NOT NULL CHECK (role IN ('user', 'assistant')), content TEXT NOT NULL, tool_calls TEXT, created_at TIMESTAMP DEFAULT NOW(), FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE ); -- ============================================ -- Indexes for Performance -- ============================================ -- Phase II indexes CREATE INDEX IF NOT EXISTS idx_tasks_user_id ON tasks(user_id); CREATE INDEX IF NOT EXISTS idx_tasks_completed ON tasks(completed); -- Phase III indexes CREATE INDEX IF NOT EXISTS idx_conversations_user_id ON conversations(user_id); CREATE INDEX IF NOT EXISTS idx_messages_conversation_id ON messages(conversation_id); CREATE INDEX IF NOT EXISTS idx_messages_user_id ON messages(user_id); CREATE INDEX IF NOT EXISTS idx_messages_created_at ON messages(created_at); -- ============================================ -- Fix: Add missing column if needed -- ============================================ -- If conversations table exists but missing updated_at, add it: DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'conversations' AND column_name = 'updated_at' ) THEN ALTER TABLE conversations ADD COLUMN updated_at TIMESTAMP DEFAULT NOW(); END IF; END $$; -- ============================================ -- Verify Schema -- ============================================ SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' ORDER BY table_name;