Rip out Theia, bump submodules, retire platform/ scaffold, snapshot docs + design assets
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
This commit is contained in:
496
vibn-coolify-schema.sql
Normal file
496
vibn-coolify-schema.sql
Normal file
@@ -0,0 +1,496 @@
|
||||
-- ==================================================
|
||||
-- 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';
|
||||
Reference in New Issue
Block a user