134 lines
5.9 KiB
SQL
134 lines
5.9 KiB
SQL
-- Research-project proposals (Thuyết minh đề tài, Mẫu III.06-TM.ĐTUD) + the PI "cockpit" entities.
|
|
-- A proposal row IS the project across its lifecycle: draft -> submitted -> approved | rejected.
|
|
-- On approval the cockpit unlocks; child tables (members/datasets/models/assets/milestones) hang off it.
|
|
-- Owner+admin authz (v1): a project is owned by owner_user_id; admins may review/approve/reject.
|
|
-- Apply after 015_document_templates.sql:
|
|
-- docker exec -i initiative-postgres psql -U initiative -d initiatives < be0/migrations/016_research_projects.sql
|
|
|
|
CREATE TABLE IF NOT EXISTS research_projects (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
owner_user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
status TEXT NOT NULL DEFAULT 'draft' CHECK (status IN ('draft','submitted','approved','rejected')),
|
|
code TEXT,
|
|
title TEXT NOT NULL DEFAULT '',
|
|
level TEXT NOT NULL DEFAULT '',
|
|
pi_name TEXT NOT NULL DEFAULT '',
|
|
period_months INTEGER,
|
|
budget_total NUMERIC(14,2),
|
|
content JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
submitted_at TIMESTAMPTZ,
|
|
reviewed_by UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
reviewed_at TIMESTAMPTZ,
|
|
review_note TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_research_projects_owner ON research_projects (owner_user_id, created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_research_projects_status ON research_projects (status, created_at DESC);
|
|
|
|
CREATE TABLE IF NOT EXISTS research_project_members (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
project_id UUID NOT NULL REFERENCES research_projects(id) ON DELETE CASCADE,
|
|
sort_order INTEGER NOT NULL DEFAULT 0,
|
|
name TEXT NOT NULL DEFAULT '',
|
|
role TEXT NOT NULL DEFAULT '',
|
|
access TEXT NOT NULL DEFAULT '',
|
|
org TEXT NOT NULL DEFAULT '',
|
|
email TEXT NOT NULL DEFAULT '',
|
|
months INTEGER,
|
|
tasks TEXT NOT NULL DEFAULT '',
|
|
status TEXT NOT NULL DEFAULT '',
|
|
user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_research_project_members_project ON research_project_members (project_id, sort_order);
|
|
|
|
CREATE TABLE IF NOT EXISTS research_project_datasets (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
project_id UUID NOT NULL REFERENCES research_projects(id) ON DELETE CASCADE,
|
|
sort_order INTEGER NOT NULL DEFAULT 0,
|
|
name TEXT NOT NULL DEFAULT '',
|
|
type TEXT NOT NULL DEFAULT '',
|
|
records INTEGER,
|
|
source TEXT NOT NULL DEFAULT '',
|
|
sensitivity TEXT NOT NULL DEFAULT '',
|
|
ethics TEXT NOT NULL DEFAULT '',
|
|
owner TEXT NOT NULL DEFAULT '',
|
|
status TEXT NOT NULL DEFAULT '',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_research_project_datasets_project ON research_project_datasets (project_id, sort_order);
|
|
|
|
CREATE TABLE IF NOT EXISTS research_project_models (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
project_id UUID NOT NULL REFERENCES research_projects(id) ON DELETE CASCADE,
|
|
sort_order INTEGER NOT NULL DEFAULT 0,
|
|
name TEXT NOT NULL DEFAULT '',
|
|
task TEXT NOT NULL DEFAULT '',
|
|
framework TEXT NOT NULL DEFAULT '',
|
|
version TEXT NOT NULL DEFAULT '',
|
|
dataset TEXT NOT NULL DEFAULT '',
|
|
auc NUMERIC(6,4),
|
|
sensitivity NUMERIC(6,4),
|
|
specificity NUMERIC(6,4),
|
|
accuracy NUMERIC(6,4),
|
|
owner TEXT NOT NULL DEFAULT '',
|
|
notes TEXT NOT NULL DEFAULT '',
|
|
status TEXT NOT NULL DEFAULT '',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_research_project_models_project ON research_project_models (project_id, sort_order);
|
|
|
|
CREATE TABLE IF NOT EXISTS research_project_assets (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
project_id UUID NOT NULL REFERENCES research_projects(id) ON DELETE CASCADE,
|
|
sort_order INTEGER NOT NULL DEFAULT 0,
|
|
name TEXT NOT NULL DEFAULT '',
|
|
category TEXT NOT NULL DEFAULT '',
|
|
acquisition TEXT NOT NULL DEFAULT '',
|
|
value NUMERIC(14,2),
|
|
owner TEXT NOT NULL DEFAULT '',
|
|
notes TEXT NOT NULL DEFAULT '',
|
|
status TEXT NOT NULL DEFAULT '',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_research_project_assets_project ON research_project_assets (project_id, sort_order);
|
|
|
|
CREATE TABLE IF NOT EXISTS research_project_milestones (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
project_id UUID NOT NULL REFERENCES research_projects(id) ON DELETE CASCADE,
|
|
sort_order INTEGER NOT NULL DEFAULT 0,
|
|
title TEXT NOT NULL DEFAULT '',
|
|
deliverable TEXT NOT NULL DEFAULT '',
|
|
start_period TEXT NOT NULL DEFAULT '',
|
|
end_period TEXT NOT NULL DEFAULT '',
|
|
owner TEXT NOT NULL DEFAULT '',
|
|
budget NUMERIC(14,2),
|
|
progress INTEGER NOT NULL DEFAULT 0,
|
|
status TEXT NOT NULL DEFAULT '',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_research_project_milestones_project ON research_project_milestones (project_id, sort_order);
|
|
|
|
CREATE TABLE IF NOT EXISTS research_project_audit (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
project_id UUID NOT NULL REFERENCES research_projects(id) ON DELETE CASCADE,
|
|
occurred_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
actor_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
actor_name TEXT NOT NULL DEFAULT '',
|
|
role_label TEXT NOT NULL DEFAULT '',
|
|
action TEXT NOT NULL,
|
|
subject TEXT NOT NULL DEFAULT '',
|
|
detail TEXT NOT NULL DEFAULT ''
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_research_project_audit_project ON research_project_audit (project_id, occurred_at DESC);
|
|
|
|
COMMENT ON TABLE research_projects IS
|
|
'Research-project proposals (Thuyet minh de tai) that become managed projects on approval. Owner and admin authz. Content JSONB holds the full proposal form. Child research_project_* tables hold cockpit entities.';
|