Unify auth middleware and remove X-User-ID trust, add project_members authorization, sandbox workspaces via resolver, and admin-only reconcile by run_id. Introduce goose migrations with startup schema gate, fail closed when DB unavailable outside explicit ALLOW_IN_MEMORY, bundle web/dist in app Dockerfile, and remove frontend pseudo-login fallback.
56 lines
2.5 KiB
SQL
56 lines
2.5 KiB
SQL
-- +goose Up
|
|
-- 2026-09-11-freeform-documents.sql
|
|
-- 支持单条回复“保存到我的私密”及自由文档(Freeform Document)独立生命周期管理
|
|
|
|
CREATE TABLE IF NOT EXISTS freeform_documents (
|
|
doc_id VARCHAR(64) PRIMARY KEY,
|
|
project_id INT NOT NULL,
|
|
owner_user_id INT NOT NULL,
|
|
source_message_id BIGINT REFERENCES chat_messages(id) ON DELETE SET NULL,
|
|
source_content_sha256 VARCHAR(64) NOT NULL DEFAULT '',
|
|
title VARCHAR(255) NOT NULL,
|
|
governance_mode VARCHAR(32) NOT NULL DEFAULT 'freeform',
|
|
space VARCHAR(32) NOT NULL DEFAULT 'my_private',
|
|
current_version_id INT NOT NULL DEFAULT 1,
|
|
current_sha256 VARCHAR(64) NOT NULL DEFAULT '',
|
|
is_deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
|
deleted_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT chk_freeform_space CHECK (space IN ('my_private', 'project_shared', 'trash')),
|
|
CONSTRAINT chk_freeform_gov_mode CHECK (governance_mode = 'freeform')
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS freeform_document_versions (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
doc_id VARCHAR(64) NOT NULL REFERENCES freeform_documents(doc_id) ON DELETE CASCADE,
|
|
version_no INT NOT NULL,
|
|
content_sha256 VARCHAR(64) NOT NULL,
|
|
content_markdown TEXT NOT NULL,
|
|
created_by INT NOT NULL,
|
|
change_summary VARCHAR(255) NOT NULL DEFAULT '',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT uq_freeform_doc_version UNIQUE (doc_id, version_no)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS document_access_audit (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
doc_id VARCHAR(64) NOT NULL,
|
|
user_id INT NOT NULL,
|
|
action VARCHAR(64) NOT NULL,
|
|
success BOOLEAN NOT NULL DEFAULT TRUE,
|
|
ip_address VARCHAR(64) NOT NULL DEFAULT '',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- 索引与检索加速
|
|
CREATE INDEX IF NOT EXISTS idx_freeform_docs_owner_space ON freeform_documents (owner_user_id, space) WHERE is_deleted = FALSE;
|
|
CREATE INDEX IF NOT EXISTS idx_freeform_docs_project_space ON freeform_documents (project_id, space) WHERE is_deleted = FALSE;
|
|
CREATE INDEX IF NOT EXISTS idx_freeform_docs_source_msg ON freeform_documents (source_message_id);
|
|
CREATE INDEX IF NOT EXISTS idx_doc_access_audit_lookup ON document_access_audit (doc_id, user_id, created_at DESC);
|
|
|
|
-- 同一用户针对同一消息生成私密文档的幂等唯一索引
|
|
CREATE UNIQUE INDEX IF NOT EXISTS uq_freeform_user_source_message
|
|
ON freeform_documents (owner_user_id, source_message_id)
|
|
WHERE is_deleted = FALSE AND source_message_id IS NOT NULL;
|