Theia rip-out (parent):
- Remove theia submodule entry (the local fork, Gitea repo, Coolify app,
Cloud Run services, and Artifact Registry image are all gone)
- Drop README.md + INFRASTRUCTURE.md (obsolete "Project OS" snapshots
that also leaked API tokens) and setup.sh (Theia clone bootstrap)
- Delete UI-DESIGN-GUIDE.md, BACKEND_AGENTS_PLAN.md, VIBN_BUILD_PLAN.md,
VISUAL_EDITOR_PLAN.md, core-packages.md, ai-packages.md, tools-list.md
(all 100% Theia-specific or superseded)
- Surgical scrubs of remaining Theia mentions in
AGENT_EXECUTION_ARCHITECTURE.md and TURBOREPO_MIGRATION_PLAN.md
Submodule bumps:
- vibn-agent-runner: Theia rip-out + MCP refactor (api/wrapper/server
pattern across shell/file/git/memory/prd/search/agent/gitea/coolify)
- vibn-frontend: Theia rip-out + P5.1 attach E2E + Justine UI WIP
Retire platform/ scaffold:
- Remove platform/backend/ (control-plane, executors, mcp-adapter),
platform/client-ide/ (gcp-productos extension), platform/contracts/,
platform/infra/terraform/, platform/scripts/templates/turborepo/
(replaced by vibn-agent-runner + vibn-frontend + Coolify direct)
- Drop architecture.md, technical_spec.md, vision-ext.md,
"1.Generate Control Plane API scaffold.md" (same era)
Docs / planning snapshots (new):
- AI_CAPABILITIES.md, AI_CAPABILITIES_ROADMAP.md
- AGENT_TELEMETRY_STREAMING_PROJECT.md
- VIBN_PRD.md, product-idea-a.md
Design assets (new):
- branding/{coolify,gitea,ux-testing}/ static brand collateral
- justine/ HTML mockups for the new onboarding/build flows
- preview-assist-ui/ Vite scratch app
- master-ai.code-workspace
Infra helpers (new):
- setup-coolify-montreal.sh provisioner
- gitea-docker-compose.yml
- vibn-coolify-schema.sql for the Coolify Postgres extensions
- prd-agent-prompt.pdf, prompt, root.txt, remixed-9edec9e9.tsx scratch
- flatten.sh helper
.gitignore: ignore **/node_modules, **/.next, **/.turbo, **/coverage
Made-with: Cursor
497 lines
17 KiB
PL/PgSQL
497 lines
17 KiB
PL/PgSQL
-- ==================================================
|
|
-- VIBN UNIFIED SCHEMA FOR COOLIFY
|
|
-- Combines Firebase collections + Railway PostgreSQL
|
|
-- ==================================================
|
|
|
|
-- Extensions
|
|
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
|
|
|
-- ==================================================
|
|
-- USERS (replaces Firebase Auth + Firestore users)
|
|
-- ==================================================
|
|
CREATE TABLE users (
|
|
id SERIAL PRIMARY KEY,
|
|
uid VARCHAR(255) UNIQUE NOT NULL, -- Firebase UID or generated
|
|
email VARCHAR(255) UNIQUE NOT NULL,
|
|
password_hash VARCHAR(255), -- For email/password auth
|
|
display_name VARCHAR(255),
|
|
photo_url VARCHAR(500),
|
|
workspace VARCHAR(255) UNIQUE NOT NULL, -- URL slug: "marks-account"
|
|
|
|
-- OAuth providers
|
|
google_id VARCHAR(255) UNIQUE,
|
|
github_id VARCHAR(255) UNIQUE,
|
|
|
|
-- Metadata
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW(),
|
|
last_login TIMESTAMP,
|
|
settings JSONB DEFAULT '{}'::jsonb
|
|
);
|
|
|
|
CREATE INDEX idx_users_email ON users(email);
|
|
CREATE INDEX idx_users_workspace ON users(workspace);
|
|
|
|
-- ==================================================
|
|
-- CLIENTS (Organizations/Companies)
|
|
-- ==================================================
|
|
CREATE TABLE clients (
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR(255) NOT NULL,
|
|
slug VARCHAR(255) UNIQUE NOT NULL, -- URL-friendly
|
|
owner_user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
|
|
|
-- Subscription/Billing
|
|
subscription_tier VARCHAR(50) DEFAULT 'free', -- free, starter, pro, enterprise
|
|
stripe_customer_id VARCHAR(255),
|
|
max_users INTEGER DEFAULT 5,
|
|
max_projects INTEGER DEFAULT 10,
|
|
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW(),
|
|
metadata JSONB DEFAULT '{}'::jsonb
|
|
);
|
|
|
|
CREATE INDEX idx_clients_owner ON clients(owner_user_id);
|
|
CREATE INDEX idx_clients_slug ON clients(slug);
|
|
|
|
-- ==================================================
|
|
-- PROJECTS (replaces Firebase projects collection)
|
|
-- ==================================================
|
|
CREATE TABLE projects (
|
|
id SERIAL PRIMARY KEY,
|
|
firebase_id VARCHAR(255) UNIQUE, -- For migration compatibility
|
|
client_id INTEGER REFERENCES clients(id) ON DELETE CASCADE,
|
|
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE, -- Owner
|
|
|
|
-- Project Identity
|
|
name VARCHAR(255) NOT NULL,
|
|
slug VARCHAR(255) NOT NULL,
|
|
workspace VARCHAR(255) NOT NULL, -- User workspace slug
|
|
|
|
-- Product Details
|
|
product_name VARCHAR(255) NOT NULL,
|
|
product_vision TEXT,
|
|
project_type VARCHAR(50) DEFAULT 'scratch', -- scratch, existing
|
|
|
|
-- Status
|
|
status VARCHAR(50) DEFAULT 'active', -- active, on_hold, completed, archived
|
|
current_phase VARCHAR(50) DEFAULT 'collection', -- collection, extraction, vision, mvp, marketing
|
|
phase_status VARCHAR(50) DEFAULT 'not_started', -- not_started, in_progress, completed
|
|
|
|
-- Integrations
|
|
workspace_path VARCHAR(500), -- Local directory path
|
|
workspace_name VARCHAR(255),
|
|
is_for_client BOOLEAN DEFAULT false,
|
|
has_logo BOOLEAN DEFAULT false,
|
|
has_domain BOOLEAN DEFAULT false,
|
|
has_website BOOLEAN DEFAULT false,
|
|
has_github BOOLEAN DEFAULT false,
|
|
has_chatgpt BOOLEAN DEFAULT false,
|
|
github_repo VARCHAR(500),
|
|
chatgpt_project_id VARCHAR(255),
|
|
|
|
-- Git/Deployment
|
|
gitea_repo_url VARCHAR(500),
|
|
coolify_app_id VARCHAR(255),
|
|
coolify_project_uuid VARCHAR(255),
|
|
deployment_url VARCHAR(500),
|
|
|
|
-- Phase Data
|
|
phase_data JSONB DEFAULT '{}'::jsonb, -- Stores all phase artifacts
|
|
phase_history JSONB DEFAULT '[]'::jsonb,
|
|
phase_scores JSONB DEFAULT '{}'::jsonb,
|
|
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW(),
|
|
|
|
UNIQUE(client_id, slug)
|
|
);
|
|
|
|
CREATE INDEX idx_projects_client ON projects(client_id);
|
|
CREATE INDEX idx_projects_user ON projects(user_id);
|
|
CREATE INDEX idx_projects_workspace ON projects(workspace);
|
|
CREATE INDEX idx_projects_status ON projects(status);
|
|
CREATE INDEX idx_projects_firebase_id ON projects(firebase_id);
|
|
|
|
-- ==================================================
|
|
-- PROJECT_CONTRIBUTORS (Team collaboration)
|
|
-- ==================================================
|
|
CREATE TABLE project_contributors (
|
|
id SERIAL PRIMARY KEY,
|
|
project_id INTEGER REFERENCES projects(id) ON DELETE CASCADE,
|
|
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
|
|
|
role VARCHAR(50) DEFAULT 'developer', -- owner, admin, developer, viewer
|
|
permissions JSONB DEFAULT '{"read":true,"write":true,"admin":false}'::jsonb,
|
|
joined_at TIMESTAMP DEFAULT NOW(),
|
|
|
|
total_time_minutes INTEGER DEFAULT 0,
|
|
|
|
UNIQUE(project_id, user_id)
|
|
);
|
|
|
|
CREATE INDEX idx_contributors_project ON project_contributors(project_id);
|
|
CREATE INDEX idx_contributors_user ON project_contributors(user_id);
|
|
|
|
-- ==================================================
|
|
-- SESSIONS (replaces both Firebase sessions + Railway logs)
|
|
-- ==================================================
|
|
CREATE TABLE sessions (
|
|
id SERIAL PRIMARY KEY,
|
|
session_id VARCHAR(255) UNIQUE NOT NULL,
|
|
firebase_id VARCHAR(255), -- For migration
|
|
|
|
project_id INTEGER REFERENCES projects(id) ON DELETE CASCADE,
|
|
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
|
|
|
-- Timing
|
|
started_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
last_updated TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
ended_at TIMESTAMP,
|
|
duration_minutes INTEGER DEFAULT 0,
|
|
|
|
-- Status
|
|
status VARCHAR(50) DEFAULT 'active', -- active, idle, completed
|
|
needs_project_association BOOLEAN DEFAULT false,
|
|
|
|
-- Context
|
|
workspace_path VARCHAR(500),
|
|
workspace_name VARCHAR(255),
|
|
ide_name VARCHAR(50) DEFAULT 'Cursor', -- Cursor, VS Code, etc.
|
|
|
|
-- Content
|
|
conversation JSONB DEFAULT '[]'::jsonb, -- Full chat history
|
|
file_changes JSONB DEFAULT '[]'::jsonb, -- Files modified
|
|
files_modified TEXT[], -- Quick array for queries
|
|
|
|
-- Metrics
|
|
message_count INTEGER DEFAULT 0,
|
|
user_message_count INTEGER DEFAULT 0,
|
|
assistant_message_count INTEGER DEFAULT 0,
|
|
file_change_count INTEGER DEFAULT 0,
|
|
|
|
-- AI Usage & Cost
|
|
total_tokens INTEGER DEFAULT 0,
|
|
prompt_tokens INTEGER DEFAULT 0,
|
|
completion_tokens INTEGER DEFAULT 0,
|
|
estimated_cost_usd NUMERIC(10,6) DEFAULT 0,
|
|
model VARCHAR(100),
|
|
|
|
-- AI Insights
|
|
summary TEXT,
|
|
conversation_summary TEXT,
|
|
tasks_identified JSONB DEFAULT '[]'::jsonb,
|
|
decisions_made JSONB DEFAULT '[]'::jsonb,
|
|
technologies_used JSONB DEFAULT '[]'::jsonb,
|
|
|
|
metadata JSONB DEFAULT '{}'::jsonb
|
|
);
|
|
|
|
CREATE INDEX idx_sessions_project ON sessions(project_id);
|
|
CREATE INDEX idx_sessions_user ON sessions(user_id);
|
|
CREATE INDEX idx_sessions_status ON sessions(status);
|
|
CREATE INDEX idx_sessions_started ON sessions(started_at);
|
|
CREATE INDEX idx_sessions_session_id ON sessions(session_id);
|
|
CREATE INDEX idx_sessions_firebase_id ON sessions(firebase_id);
|
|
|
|
-- ==================================================
|
|
-- WORK_COMPLETED (AI-extracted accomplishments)
|
|
-- ==================================================
|
|
CREATE TABLE work_completed (
|
|
id SERIAL PRIMARY KEY,
|
|
session_id INTEGER REFERENCES sessions(id) ON DELETE CASCADE,
|
|
project_id INTEGER REFERENCES projects(id) ON DELETE CASCADE,
|
|
|
|
title VARCHAR(500) NOT NULL,
|
|
description TEXT,
|
|
category VARCHAR(100), -- frontend, backend, database, deployment, testing, docs, bugfix
|
|
|
|
files_modified JSONB DEFAULT '[]'::jsonb,
|
|
|
|
completed_at TIMESTAMP DEFAULT NOW(),
|
|
extracted_by_ai BOOLEAN DEFAULT true
|
|
);
|
|
|
|
CREATE INDEX idx_work_completed_project ON work_completed(project_id);
|
|
CREATE INDEX idx_work_completed_session ON work_completed(session_id);
|
|
CREATE INDEX idx_work_completed_category ON work_completed(category);
|
|
|
|
-- ==================================================
|
|
-- ARCHITECTURAL_DECISIONS (Design decisions)
|
|
-- ==================================================
|
|
CREATE TABLE architectural_decisions (
|
|
id SERIAL PRIMARY KEY,
|
|
project_id INTEGER REFERENCES projects(id) ON DELETE CASCADE,
|
|
identified_by_session_id INTEGER REFERENCES sessions(id) ON DELETE SET NULL,
|
|
|
|
title VARCHAR(500) NOT NULL,
|
|
context TEXT,
|
|
decision TEXT NOT NULL,
|
|
consequences TEXT,
|
|
|
|
status VARCHAR(50) DEFAULT 'accepted', -- proposed, accepted, deprecated, superseded
|
|
|
|
tags JSONB DEFAULT '[]'::jsonb,
|
|
|
|
decided_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_arch_decisions_project ON architectural_decisions(project_id);
|
|
CREATE INDEX idx_arch_decisions_status ON architectural_decisions(status);
|
|
|
|
-- ==================================================
|
|
-- ARCHITECTURE_DOCS (Auto-maintained documentation)
|
|
-- ==================================================
|
|
CREATE TABLE architecture_docs (
|
|
id SERIAL PRIMARY KEY,
|
|
project_id INTEGER REFERENCES projects(id) ON DELETE CASCADE,
|
|
|
|
doc_type VARCHAR(100) NOT NULL, -- tech_stack, data_model, api_design, deployment
|
|
content TEXT NOT NULL,
|
|
|
|
version INTEGER DEFAULT 1,
|
|
last_ai_update TIMESTAMP,
|
|
last_manual_update TIMESTAMP,
|
|
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW(),
|
|
|
|
UNIQUE(project_id, doc_type)
|
|
);
|
|
|
|
CREATE INDEX idx_arch_docs_project ON architecture_docs(project_id);
|
|
CREATE INDEX idx_arch_docs_type ON architecture_docs(doc_type);
|
|
|
|
-- ==================================================
|
|
-- TASKS (Project tasks)
|
|
-- ==================================================
|
|
CREATE TABLE tasks (
|
|
id SERIAL PRIMARY KEY,
|
|
project_id INTEGER REFERENCES projects(id) ON DELETE CASCADE,
|
|
|
|
title VARCHAR(500) NOT NULL,
|
|
description TEXT,
|
|
|
|
status VARCHAR(50) DEFAULT 'todo', -- todo, in_progress, review, done, blocked
|
|
priority VARCHAR(50) DEFAULT 'medium', -- low, medium, high, urgent
|
|
|
|
assigned_to INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
|
created_by INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
|
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW(),
|
|
completed_at TIMESTAMP,
|
|
|
|
identified_by_session_id INTEGER REFERENCES sessions(id) ON DELETE SET NULL,
|
|
related_sessions JSONB DEFAULT '[]'::jsonb,
|
|
|
|
metadata JSONB DEFAULT '{}'::jsonb
|
|
);
|
|
|
|
CREATE INDEX idx_tasks_project ON tasks(project_id);
|
|
CREATE INDEX idx_tasks_status ON tasks(status);
|
|
CREATE INDEX idx_tasks_assigned ON tasks(assigned_to);
|
|
|
|
-- ==================================================
|
|
-- ANALYSES (replaces Firebase analyses collection)
|
|
-- ==================================================
|
|
CREATE TABLE analyses (
|
|
id SERIAL PRIMARY KEY,
|
|
firebase_id VARCHAR(255), -- For migration
|
|
project_id INTEGER REFERENCES projects(id) ON DELETE CASCADE,
|
|
|
|
type VARCHAR(50) NOT NULL, -- code, chatgpt, github, combined
|
|
summary TEXT,
|
|
tech_stack JSONB DEFAULT '[]'::jsonb,
|
|
features JSONB DEFAULT '[]'::jsonb,
|
|
raw_data JSONB DEFAULT '{}'::jsonb,
|
|
|
|
created_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_analyses_project ON analyses(project_id);
|
|
CREATE INDEX idx_analyses_type ON analyses(type);
|
|
|
|
-- ==================================================
|
|
-- API_KEYS (User API keys for extension)
|
|
-- ==================================================
|
|
CREATE TABLE api_keys (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
|
|
|
key_hash VARCHAR(255) UNIQUE NOT NULL,
|
|
key_prefix VARCHAR(20), -- First few chars for display
|
|
|
|
name VARCHAR(255), -- User-friendly name
|
|
last_used TIMESTAMP,
|
|
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
expires_at TIMESTAMP,
|
|
revoked BOOLEAN DEFAULT false
|
|
);
|
|
|
|
CREATE INDEX idx_api_keys_user ON api_keys(user_id);
|
|
CREATE INDEX idx_api_keys_hash ON api_keys(key_hash);
|
|
|
|
-- ==================================================
|
|
-- USER_SESSIONS (Authentication sessions)
|
|
-- ==================================================
|
|
CREATE TABLE user_sessions (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
|
|
|
token VARCHAR(500) UNIQUE NOT NULL,
|
|
refresh_token VARCHAR(500),
|
|
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
expires_at TIMESTAMP,
|
|
last_activity TIMESTAMP DEFAULT NOW(),
|
|
|
|
ip_address VARCHAR(45),
|
|
user_agent TEXT
|
|
);
|
|
|
|
CREATE INDEX idx_user_sessions_token ON user_sessions(token);
|
|
CREATE INDEX idx_user_sessions_user ON user_sessions(user_id);
|
|
CREATE INDEX idx_user_sessions_expires ON user_sessions(expires_at);
|
|
|
|
-- ==================================================
|
|
-- KNOWLEDGE_ITEMS (Chat/Code context for AI)
|
|
-- ==================================================
|
|
CREATE TABLE knowledge_items (
|
|
id SERIAL PRIMARY KEY,
|
|
project_id INTEGER REFERENCES projects(id) ON DELETE CASCADE,
|
|
|
|
item_type VARCHAR(50) NOT NULL, -- chat_history, code_file, github_issue, documentation
|
|
source VARCHAR(100), -- cursor, chatgpt, github, manual
|
|
|
|
title VARCHAR(500),
|
|
content TEXT,
|
|
metadata JSONB DEFAULT '{}'::jsonb,
|
|
|
|
-- Status
|
|
processed BOOLEAN DEFAULT false,
|
|
chunk_count INTEGER DEFAULT 0,
|
|
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_knowledge_items_project ON knowledge_items(project_id);
|
|
CREATE INDEX idx_knowledge_items_type ON knowledge_items(item_type);
|
|
CREATE INDEX idx_knowledge_items_processed ON knowledge_items(processed);
|
|
|
|
-- ==================================================
|
|
-- ANALYTICS VIEWS
|
|
-- ==================================================
|
|
|
|
-- Project health overview
|
|
CREATE OR REPLACE VIEW project_health AS
|
|
SELECT
|
|
p.id as project_id,
|
|
p.name as project_name,
|
|
p.status,
|
|
p.current_phase,
|
|
c.name as client_name,
|
|
COUNT(DISTINCT s.id) as session_count,
|
|
COUNT(DISTINCT s.user_id) as active_users,
|
|
SUM(s.total_tokens) as total_tokens,
|
|
SUM(s.estimated_cost_usd) as total_cost,
|
|
COUNT(DISTINCT t.id) FILTER (WHERE t.status = 'done') as completed_tasks,
|
|
COUNT(DISTINCT t.id) FILTER (WHERE t.status != 'done') as pending_tasks,
|
|
MAX(s.last_updated) as last_activity
|
|
FROM projects p
|
|
LEFT JOIN clients c ON p.client_id = c.id
|
|
LEFT JOIN sessions s ON s.project_id = p.id
|
|
LEFT JOIN tasks t ON t.project_id = p.id
|
|
GROUP BY p.id, p.name, p.status, p.current_phase, c.name;
|
|
|
|
-- User activity summary
|
|
CREATE OR REPLACE VIEW user_activity AS
|
|
SELECT
|
|
u.id as user_id,
|
|
u.email,
|
|
u.display_name,
|
|
COUNT(DISTINCT s.id) as session_count,
|
|
COUNT(DISTINCT s.project_id) as projects_worked_on,
|
|
SUM(s.total_tokens) as total_tokens,
|
|
SUM(s.estimated_cost_usd) as total_cost,
|
|
MAX(s.last_updated) as last_activity
|
|
FROM users u
|
|
LEFT JOIN sessions s ON s.user_id = u.id
|
|
GROUP BY u.id, u.email, u.display_name;
|
|
|
|
-- Organization billing summary
|
|
CREATE OR REPLACE VIEW organization_billing AS
|
|
SELECT
|
|
c.id as client_id,
|
|
c.name as organization_name,
|
|
c.subscription_tier,
|
|
COUNT(DISTINCT u.id) as total_users,
|
|
COUNT(DISTINCT p.id) as total_projects,
|
|
COUNT(DISTINCT s.id) as total_sessions,
|
|
SUM(s.total_tokens) as total_tokens,
|
|
SUM(s.estimated_cost_usd) as total_cost,
|
|
SUM(s.estimated_cost_usd) FILTER (
|
|
WHERE s.started_at >= DATE_TRUNC('month', CURRENT_DATE)
|
|
) as current_month_cost
|
|
FROM clients c
|
|
LEFT JOIN projects p ON p.client_id = c.id
|
|
LEFT JOIN sessions s ON s.project_id = p.id
|
|
LEFT JOIN users u ON u.id = c.owner_user_id OR EXISTS (
|
|
SELECT 1 FROM project_contributors pc
|
|
WHERE pc.project_id = p.id AND pc.user_id = u.id
|
|
)
|
|
GROUP BY c.id, c.name, c.subscription_tier;
|
|
|
|
-- ==================================================
|
|
-- HELPER FUNCTIONS
|
|
-- ==================================================
|
|
|
|
-- Auto-update updated_at timestamps
|
|
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
NEW.updated_at = NOW();
|
|
RETURN NEW;
|
|
END;
|
|
$$ language 'plpgsql';
|
|
|
|
-- Apply to tables
|
|
CREATE TRIGGER update_users_updated_at BEFORE UPDATE ON users
|
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
|
|
CREATE TRIGGER update_clients_updated_at BEFORE UPDATE ON clients
|
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
|
|
CREATE TRIGGER update_projects_updated_at BEFORE UPDATE ON projects
|
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
|
|
CREATE TRIGGER update_sessions_updated_at BEFORE UPDATE ON sessions
|
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
|
|
-- ==================================================
|
|
-- SEED DATA (Optional)
|
|
-- ==================================================
|
|
|
|
-- Create default user (you)
|
|
INSERT INTO users (uid, email, display_name, workspace)
|
|
VALUES
|
|
('mark-admin-001', 'mark@getacquired.com', 'Mark Henderson', 'marks-account')
|
|
ON CONFLICT (email) DO NOTHING;
|
|
|
|
-- Create default client (your organization)
|
|
INSERT INTO clients (name, slug, owner_user_id, subscription_tier)
|
|
VALUES
|
|
('VIBN', 'vibn', 1, 'enterprise')
|
|
ON CONFLICT (slug) DO NOTHING;
|
|
|
|
COMMENT ON TABLE users IS 'VIBN users (developers, team members)';
|
|
COMMENT ON TABLE clients IS 'Organizations/Companies using VIBN';
|
|
COMMENT ON TABLE projects IS 'Development projects under organizations';
|
|
COMMENT ON TABLE sessions IS 'AI coding sessions with full conversation logs';
|
|
COMMENT ON TABLE work_completed IS 'AI-extracted accomplishments from sessions';
|
|
COMMENT ON TABLE architectural_decisions IS 'Design decisions made during development';
|