166 lines
6.5 KiB
SQL
166 lines
6.5 KiB
SQL
/*
|
|
# OKR Management System - Database Schema
|
|
|
|
1. New Tables
|
|
- `users` - System users (owner/pm/member roles)
|
|
- `projects` - Project entities with health status
|
|
- `project_members` - Many-to-many relationship for project membership
|
|
- `objectives` - Period-based objectives (O in OKR)
|
|
- `krs` - Key Results with flexible periods
|
|
- `checkins` - Daily progress updates
|
|
- `meetings` - Meeting records with summaries
|
|
- `metrics` - Configurable metrics library
|
|
- `templates` - KR templates library
|
|
|
|
2. Security
|
|
- RLS disabled for all tables (no-auth system requirement)
|
|
- All tables accessible without authentication
|
|
|
|
3. Notes
|
|
- All timestamps use timestamptz for timezone support
|
|
- Status fields use text with CHECK constraints
|
|
- JSON fields used for flexible template items
|
|
*/
|
|
|
|
-- Users table
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
name text NOT NULL,
|
|
role text NOT NULL CHECK (role IN ('owner', 'pm', 'member')),
|
|
avatar_url text,
|
|
created_at timestamptz DEFAULT now(),
|
|
updated_at timestamptz DEFAULT now()
|
|
);
|
|
|
|
-- Projects table
|
|
CREATE TABLE IF NOT EXISTS projects (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
name text NOT NULL,
|
|
description text,
|
|
owner_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
pm_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
project_type text DEFAULT 'general',
|
|
status text NOT NULL DEFAULT 'green' CHECK (status IN ('green', 'yellow', 'red')),
|
|
created_at timestamptz DEFAULT now(),
|
|
updated_at timestamptz DEFAULT now()
|
|
);
|
|
|
|
-- Project members junction table
|
|
CREATE TABLE IF NOT EXISTS project_members (
|
|
project_id uuid REFERENCES projects(id) ON DELETE CASCADE,
|
|
user_id uuid REFERENCES users(id) ON DELETE CASCADE,
|
|
PRIMARY KEY (project_id, user_id)
|
|
);
|
|
|
|
-- Objectives table (period-based goals)
|
|
CREATE TABLE IF NOT EXISTS objectives (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
title text NOT NULL,
|
|
description text,
|
|
period_start date NOT NULL,
|
|
period_end date NOT NULL,
|
|
created_by uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
created_at timestamptz DEFAULT now(),
|
|
updated_at timestamptz DEFAULT now(),
|
|
CONSTRAINT valid_period CHECK (period_end >= period_start)
|
|
);
|
|
|
|
-- Key Results table
|
|
CREATE TABLE IF NOT EXISTS krs (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
objective_id uuid REFERENCES objectives(id) ON DELETE SET NULL,
|
|
period_type text NOT NULL DEFAULT 'custom' CHECK (period_type IN ('custom', '3d', '1w', '2w', 'monthly')),
|
|
period_name text,
|
|
period_start date NOT NULL,
|
|
period_end date NOT NULL,
|
|
title text NOT NULL,
|
|
metric_name text NOT NULL,
|
|
unit text NOT NULL,
|
|
direction text NOT NULL DEFAULT 'increase' CHECK (direction IN ('increase', 'decrease')),
|
|
target_value numeric NOT NULL CHECK (target_value > 0),
|
|
current_value numeric NOT NULL DEFAULT 0,
|
|
owner_user_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
confidence integer NOT NULL DEFAULT 80 CHECK (confidence >= 0 AND confidence <= 100),
|
|
status text NOT NULL DEFAULT 'green' CHECK (status IN ('green', 'yellow', 'red')),
|
|
reason_code text CHECK (reason_code IS NULL OR reason_code IN ('RESOURCE', 'DEPENDENCY', 'DECISION', 'SCOPE', 'EXECUTION', 'OTHER')),
|
|
note text,
|
|
need_owner_help boolean NOT NULL DEFAULT false,
|
|
created_at timestamptz DEFAULT now(),
|
|
updated_at timestamptz DEFAULT now(),
|
|
CONSTRAINT valid_kr_period CHECK (period_end >= period_start)
|
|
);
|
|
|
|
-- Checkins table
|
|
CREATE TABLE IF NOT EXISTS checkins (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
kr_id uuid NOT NULL REFERENCES krs(id) ON DELETE CASCADE,
|
|
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
user_id uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
date date NOT NULL DEFAULT CURRENT_DATE,
|
|
current_value numeric NOT NULL,
|
|
delta_value numeric,
|
|
confidence integer NOT NULL CHECK (confidence >= 0 AND confidence <= 100),
|
|
status_snapshot text NOT NULL CHECK (status_snapshot IN ('green', 'yellow', 'red')),
|
|
reason_code text CHECK (reason_code IS NULL OR reason_code IN ('RESOURCE', 'DEPENDENCY', 'DECISION', 'SCOPE', 'EXECUTION', 'OTHER')),
|
|
note text,
|
|
created_at timestamptz DEFAULT now()
|
|
);
|
|
|
|
-- Meetings table
|
|
CREATE TABLE IF NOT EXISTS meetings (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
period_start date NOT NULL,
|
|
period_end date NOT NULL,
|
|
summary text NOT NULL,
|
|
decisions text,
|
|
risks text,
|
|
next_period_commitments text,
|
|
created_by uuid REFERENCES users(id) ON DELETE SET NULL,
|
|
created_at timestamptz DEFAULT now(),
|
|
updated_at timestamptz DEFAULT now()
|
|
);
|
|
|
|
-- Metrics library table
|
|
CREATE TABLE IF NOT EXISTS metrics (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
name text NOT NULL,
|
|
unit text NOT NULL,
|
|
direction text NOT NULL DEFAULT 'increase' CHECK (direction IN ('increase', 'decrease')),
|
|
category text,
|
|
is_active boolean NOT NULL DEFAULT true,
|
|
created_at timestamptz DEFAULT now(),
|
|
updated_at timestamptz DEFAULT now()
|
|
);
|
|
|
|
-- Templates library table
|
|
CREATE TABLE IF NOT EXISTS templates (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
name text NOT NULL,
|
|
description text,
|
|
project_type text,
|
|
tags jsonb DEFAULT '[]'::jsonb,
|
|
items jsonb NOT NULL DEFAULT '[]'::jsonb,
|
|
is_active boolean NOT NULL DEFAULT true,
|
|
created_at timestamptz DEFAULT now(),
|
|
updated_at timestamptz DEFAULT now()
|
|
);
|
|
|
|
-- Create indexes for better query performance
|
|
CREATE INDEX IF NOT EXISTS idx_projects_owner ON projects(owner_id);
|
|
CREATE INDEX IF NOT EXISTS idx_projects_pm ON projects(pm_id);
|
|
CREATE INDEX IF NOT EXISTS idx_projects_status ON projects(status);
|
|
CREATE INDEX IF NOT EXISTS idx_objectives_project ON objectives(project_id);
|
|
CREATE INDEX IF NOT EXISTS idx_objectives_period ON objectives(period_start, period_end);
|
|
CREATE INDEX IF NOT EXISTS idx_krs_project ON krs(project_id);
|
|
CREATE INDEX IF NOT EXISTS idx_krs_objective ON krs(objective_id);
|
|
CREATE INDEX IF NOT EXISTS idx_krs_owner ON krs(owner_user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_krs_status ON krs(status);
|
|
CREATE INDEX IF NOT EXISTS idx_krs_period ON krs(period_start, period_end);
|
|
CREATE INDEX IF NOT EXISTS idx_checkins_kr ON checkins(kr_id);
|
|
CREATE INDEX IF NOT EXISTS idx_checkins_date ON checkins(date);
|
|
CREATE INDEX IF NOT EXISTS idx_meetings_project ON meetings(project_id);
|
|
CREATE INDEX IF NOT EXISTS idx_metrics_active ON metrics(is_active);
|
|
CREATE INDEX IF NOT EXISTS idx_templates_active ON templates(is_active); |