1836 lines
64 KiB
SQL
1836 lines
64 KiB
SQL
create table if not exists "user"
|
|
(
|
|
uid uuid not null
|
|
primary key,
|
|
username varchar(255) not null,
|
|
display_name varchar(255),
|
|
avatar_url varchar(255),
|
|
website_url varchar(255),
|
|
organization varchar(255),
|
|
last_sign_in_at timestamp with time zone,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_user_username
|
|
on "user" (username);
|
|
|
|
create table if not exists user_password
|
|
(
|
|
"user" uuid not null
|
|
primary key,
|
|
password_hash varchar(255) not null,
|
|
password_salt varchar(255),
|
|
is_active boolean default true not null,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null
|
|
);
|
|
|
|
create table if not exists user_email
|
|
(
|
|
"user" uuid not null
|
|
primary key,
|
|
email varchar(255) not null,
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_user_email_email
|
|
on user_email (email);
|
|
|
|
create table if not exists user_2fa
|
|
(
|
|
"user" uuid not null
|
|
primary key,
|
|
method varchar(255) not null,
|
|
secret varchar(255),
|
|
backup_codes jsonb not null,
|
|
is_enabled boolean default false not null,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null
|
|
);
|
|
|
|
create table if not exists user_notification
|
|
(
|
|
"user" uuid not null
|
|
primary key,
|
|
email_enabled boolean default false not null,
|
|
in_app_enabled boolean default true not null,
|
|
push_enabled boolean default false not null,
|
|
digest_mode varchar(255) not null,
|
|
dnd_enabled boolean default false not null,
|
|
dnd_start_minute integer,
|
|
dnd_end_minute integer,
|
|
marketing_enabled boolean default true not null,
|
|
security_enabled boolean default true not null,
|
|
product_enabled boolean default true not null,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null,
|
|
push_subscription_endpoint text,
|
|
push_subscription_keys_p256dh text,
|
|
push_subscription_keys_auth text
|
|
);
|
|
|
|
create table if not exists user_preferences
|
|
(
|
|
"user" uuid not null
|
|
primary key,
|
|
language varchar(255) not null,
|
|
theme varchar(255) not null,
|
|
timezone varchar(255) not null,
|
|
email_notifications boolean default true not null,
|
|
in_app_notifications boolean default true not null,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null
|
|
);
|
|
|
|
create table if not exists user_password_reset
|
|
(
|
|
token varchar(255) not null
|
|
primary key,
|
|
user_uid uuid not null,
|
|
expires_at timestamp with time zone not null,
|
|
used boolean default false not null,
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_user_password_reset_user_uid
|
|
on user_password_reset (user_uid);
|
|
|
|
create table if not exists user_relation
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
"user" uuid not null,
|
|
target uuid not null,
|
|
relation_type varchar(255) not null,
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_user_relation_user
|
|
on user_relation ("user");
|
|
|
|
create index if not exists idx_user_relation_target
|
|
on user_relation (target);
|
|
|
|
create table if not exists user_ssh_key
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
"user" uuid not null,
|
|
title varchar(255) not null,
|
|
public_key text not null,
|
|
fingerprint varchar(255) not null,
|
|
key_type varchar(255) not null,
|
|
key_bits integer,
|
|
is_verified boolean default false not null,
|
|
last_used_at timestamp with time zone,
|
|
expires_at timestamp with time zone,
|
|
is_revoked boolean default false not null,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_user_ssh_key_user
|
|
on user_ssh_key ("user");
|
|
|
|
create table if not exists user_token
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
"user" uuid not null,
|
|
name varchar(255) not null,
|
|
token_hash varchar(255) not null,
|
|
scopes jsonb not null,
|
|
expires_at timestamp with time zone,
|
|
is_revoked boolean default false not null,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_user_token_user
|
|
on user_token ("user");
|
|
|
|
create table if not exists user_activity_log
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
user_uid uuid,
|
|
action varchar(255) not null,
|
|
ip_address varchar(255),
|
|
user_agent varchar(255),
|
|
details jsonb not null,
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_user_activity_log_user_uid
|
|
on user_activity_log (user_uid);
|
|
|
|
create index if not exists idx_user_activity_log_created_at
|
|
on user_activity_log (created_at);
|
|
|
|
create table if not exists project_access_log
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
project uuid not null,
|
|
actor_uid uuid,
|
|
action varchar(255) not null,
|
|
ip_address varchar(255),
|
|
user_agent varchar(255),
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_project_access_log_project
|
|
on project_access_log (project);
|
|
|
|
create index if not exists idx_project_access_log_created_at
|
|
on project_access_log (created_at);
|
|
|
|
create table if not exists project_audit_log
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
project uuid not null,
|
|
actor uuid not null,
|
|
action text not null,
|
|
details jsonb,
|
|
ip_address varchar(255),
|
|
user_agent varchar(255),
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_project_audit_log_project
|
|
on project_audit_log (project);
|
|
|
|
create index if not exists idx_project_audit_log_created_at
|
|
on project_audit_log (created_at);
|
|
|
|
create table if not exists project_billing
|
|
(
|
|
project_uuid uuid not null
|
|
primary key,
|
|
balance numeric default 0.0 not null,
|
|
currency text not null,
|
|
user_uuid uuid,
|
|
updated_at timestamp with time zone not null,
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create table if not exists project_billing_history
|
|
(
|
|
uid uuid not null
|
|
primary key,
|
|
project uuid not null,
|
|
"user" uuid,
|
|
amount numeric not null,
|
|
currency text not null,
|
|
reason text not null,
|
|
extra jsonb,
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_project_billing_history_project
|
|
on project_billing_history (project);
|
|
|
|
create table if not exists project_follow
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
project uuid not null,
|
|
"user" uuid not null,
|
|
created_at timestamp with time zone not null,
|
|
unique (project, "user")
|
|
);
|
|
|
|
create unique index if not exists idx_project_follow_project_user
|
|
on project_follow (project, "user");
|
|
|
|
create table if not exists project_history_name
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
project_uid uuid not null,
|
|
history_name varchar(255) not null,
|
|
changed_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_project_history_name_project_uid
|
|
on project_history_name (project_uid);
|
|
|
|
create table if not exists project_label
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
project_uuid uuid not null,
|
|
label_id bigint not null,
|
|
relation_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_project_label_project
|
|
on project_label (project_uuid);
|
|
|
|
create table if not exists project_like
|
|
(
|
|
project uuid not null,
|
|
"user" uuid not null,
|
|
created_at timestamp with time zone not null,
|
|
primary key (project, "user")
|
|
);
|
|
|
|
create table if not exists project_member_invitations
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
project uuid not null,
|
|
"user" uuid not null,
|
|
invited_by uuid not null,
|
|
scope varchar(255) not null,
|
|
accepted boolean default false not null,
|
|
accepted_at timestamp with time zone,
|
|
rejected boolean default false not null,
|
|
rejected_at timestamp with time zone,
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_project_member_invitations_project_user
|
|
on project_member_invitations (project, "user");
|
|
|
|
create table if not exists project_member_join_answers
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
project uuid not null,
|
|
"user" uuid not null,
|
|
request_id bigint not null,
|
|
question varchar(255) not null,
|
|
answer varchar(255) not null,
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_project_member_join_answers_request_id
|
|
on project_member_join_answers (request_id);
|
|
|
|
create table if not exists project_member_join_request
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
project uuid not null,
|
|
"user" uuid not null,
|
|
status varchar(255) not null,
|
|
message text,
|
|
processed_by uuid,
|
|
processed_at timestamp with time zone,
|
|
reject_reason text,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_project_member_join_request_project_user
|
|
on project_member_join_request (project, "user");
|
|
|
|
create index if not exists idx_project_member_join_request_status
|
|
on project_member_join_request (status);
|
|
|
|
create table if not exists project_member_join_settings
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
project uuid not null,
|
|
require_approval boolean default false not null,
|
|
require_questions boolean default false not null,
|
|
questions jsonb not null,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null
|
|
);
|
|
|
|
create table if not exists project_members
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
project_uuid uuid not null,
|
|
user_uuid uuid not null,
|
|
scope varchar(255) not null,
|
|
joined_at timestamp with time zone not null,
|
|
unique (project_uuid, user_uuid)
|
|
);
|
|
|
|
create unique index if not exists idx_project_members_project_user
|
|
on project_members (project_uuid, user_uuid);
|
|
|
|
create table if not exists project_watch
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
project uuid not null,
|
|
"user" uuid not null,
|
|
notifications_enabled boolean default true not null,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null,
|
|
unique (project, "user")
|
|
);
|
|
|
|
create unique index if not exists idx_project_watch_project_user
|
|
on project_watch (project, "user");
|
|
|
|
create table if not exists repo
|
|
(
|
|
id uuid not null
|
|
primary key,
|
|
repo_name varchar(255) not null,
|
|
project uuid not null,
|
|
description text,
|
|
default_branch varchar(255) not null,
|
|
is_private boolean default false not null,
|
|
storage_path varchar(255) not null,
|
|
created_by uuid not null,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null,
|
|
ai_code_review_enabled boolean default false not null
|
|
);
|
|
|
|
create index if not exists idx_repo_project
|
|
on repo (project);
|
|
|
|
create index if not exists idx_repo_repo_name
|
|
on repo (repo_name);
|
|
|
|
create table if not exists repo_branch
|
|
(
|
|
repo uuid not null,
|
|
name varchar(255) not null,
|
|
oid varchar(255) not null,
|
|
upstream varchar(255),
|
|
head boolean default false not null,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null,
|
|
primary key (repo, name)
|
|
);
|
|
|
|
create index if not exists idx_repo_branch_repo
|
|
on repo_branch (repo);
|
|
|
|
create table if not exists repo_branch_protect
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
repo_uuid uuid not null,
|
|
branch varchar(255) not null,
|
|
forbid_push boolean default false not null,
|
|
forbid_pull boolean default false not null,
|
|
forbid_merge boolean default false not null,
|
|
forbid_deletion boolean default false not null,
|
|
forbid_force_push boolean default false not null,
|
|
forbid_tag_push boolean default false not null,
|
|
required_approvals integer default 0 not null,
|
|
dismiss_stale_reviews boolean default false not null,
|
|
require_linear_history boolean default false not null,
|
|
allow_fork_syncing boolean default true not null,
|
|
unique (repo_uuid, branch)
|
|
);
|
|
|
|
create unique index if not exists idx_repo_branch_protect_repo_branch
|
|
on repo_branch_protect (repo_uuid, branch);
|
|
|
|
create table if not exists repo_collaborator
|
|
(
|
|
repo uuid not null,
|
|
"user" uuid not null,
|
|
scope varchar(255) not null,
|
|
created_at timestamp with time zone not null,
|
|
primary key (repo, "user")
|
|
);
|
|
|
|
create table if not exists repo_commit
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
repo uuid not null,
|
|
oid varchar(255) not null,
|
|
author_name varchar(255) not null,
|
|
author_email varchar(255) not null,
|
|
author uuid,
|
|
commiter_name varchar(255) not null,
|
|
commiter_email varchar(255) not null,
|
|
commiter uuid,
|
|
message text not null,
|
|
parent jsonb not null,
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_repo_commit_repo
|
|
on repo_commit (repo);
|
|
|
|
create index if not exists idx_repo_commit_oid
|
|
on repo_commit (oid);
|
|
|
|
create table if not exists repo_fork
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
parent_repo uuid not null,
|
|
forked_repo uuid not null,
|
|
forked_by uuid not null,
|
|
forked_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_repo_fork_parent_repo
|
|
on repo_fork (parent_repo);
|
|
|
|
create unique index if not exists idx_repo_fork_forked_repo
|
|
on repo_fork (forked_repo);
|
|
|
|
create table if not exists repo_history_name
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
repo_uuid uuid not null,
|
|
project_uid uuid not null,
|
|
name varchar(255) not null,
|
|
change_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_repo_history_name_repo
|
|
on repo_history_name (repo_uuid);
|
|
|
|
create table if not exists repo_hook
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
repo_uuid uuid not null,
|
|
event jsonb not null,
|
|
script text not null,
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_repo_hook_repo
|
|
on repo_hook (repo_uuid);
|
|
|
|
create table if not exists repo_lfs_lock
|
|
(
|
|
repo_uuid uuid not null,
|
|
path varchar(255) not null,
|
|
lock_type varchar(255) not null,
|
|
locked_by uuid not null,
|
|
locked_at timestamp with time zone not null,
|
|
unlocked_at timestamp with time zone,
|
|
primary key (repo_uuid, path)
|
|
);
|
|
|
|
create table if not exists repo_lfs_object
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
oid varchar(255) not null,
|
|
repo_uuid uuid not null,
|
|
size bigint not null,
|
|
storage_path varchar(255) not null,
|
|
uploaded_by uuid,
|
|
uploaded_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_repo_lfs_object_repo_oid
|
|
on repo_lfs_object (repo_uuid, oid);
|
|
|
|
create table if not exists repo_lock
|
|
(
|
|
repo_uuid uuid not null,
|
|
path varchar(255) not null,
|
|
lock_type varchar(255) not null,
|
|
locked_by uuid not null,
|
|
acquired_at timestamp with time zone not null,
|
|
released_at timestamp with time zone,
|
|
primary key (repo_uuid, path)
|
|
);
|
|
|
|
create table if not exists repo_star
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
repo_uuid uuid not null,
|
|
user_uuid uuid not null,
|
|
created_at timestamp with time zone not null,
|
|
unique (repo_uuid, user_uuid)
|
|
);
|
|
|
|
create unique index if not exists idx_repo_star_repo_user
|
|
on repo_star (repo_uuid, user_uuid);
|
|
|
|
create table if not exists repo_tag
|
|
(
|
|
repo_uuid uuid not null,
|
|
name varchar(255) not null,
|
|
oid varchar(255) not null,
|
|
color varchar(255),
|
|
description text,
|
|
created_at timestamp with time zone not null,
|
|
tagger_name varchar(255) not null,
|
|
tagger_email varchar(255) not null,
|
|
tagger_uuid uuid,
|
|
primary key (repo_uuid, name)
|
|
);
|
|
|
|
create table if not exists repo_upstream
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
repo_uuid uuid not null
|
|
unique,
|
|
source_url varchar(255) not null,
|
|
direction varchar(255) not null,
|
|
schedule_cron varchar(255),
|
|
last_run_at timestamp with time zone,
|
|
next_run_at timestamp with time zone,
|
|
status varchar(255) not null,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null
|
|
);
|
|
|
|
create unique index if not exists idx_repo_upstream_repo
|
|
on repo_upstream (repo_uuid);
|
|
|
|
create table if not exists repo_watch
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
user_uuid uuid not null,
|
|
repo_uuid uuid not null,
|
|
show_dashboard boolean default false not null,
|
|
notify_email boolean default false not null,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null,
|
|
unique (user_uuid, repo_uuid)
|
|
);
|
|
|
|
create unique index if not exists idx_repo_watch_user_repo
|
|
on repo_watch (user_uuid, repo_uuid);
|
|
|
|
create table if not exists repo_webhook
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
repo_uuid uuid not null,
|
|
event jsonb not null,
|
|
url varchar(255),
|
|
access_key varchar(255),
|
|
secret_key varchar(255),
|
|
created_at timestamp with time zone not null,
|
|
last_delivered_at timestamp with time zone,
|
|
touch_count bigint default 0 not null
|
|
);
|
|
|
|
create index if not exists idx_repo_webhook_repo
|
|
on repo_webhook (repo_uuid);
|
|
|
|
create table if not exists issue
|
|
(
|
|
id uuid not null
|
|
primary key,
|
|
project uuid not null,
|
|
number bigint not null,
|
|
title varchar(255) not null,
|
|
body text,
|
|
state varchar(255) not null,
|
|
author uuid not null,
|
|
milestone varchar(255),
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null,
|
|
closed_at timestamp with time zone,
|
|
created_by_ai boolean default false not null
|
|
);
|
|
|
|
create index if not exists idx_issue_project
|
|
on issue (project);
|
|
|
|
create index if not exists idx_issue_author
|
|
on issue (author);
|
|
|
|
create index if not exists idx_issue_state
|
|
on issue (state);
|
|
|
|
create table if not exists issue_assignee
|
|
(
|
|
issue uuid not null,
|
|
"user" uuid not null,
|
|
assigned_at timestamp with time zone not null,
|
|
primary key (issue, "user")
|
|
);
|
|
|
|
create table if not exists issue_comment
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
issue uuid not null,
|
|
author uuid not null,
|
|
body text not null,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_issue_comment_issue
|
|
on issue_comment (issue);
|
|
|
|
create table if not exists issue_comment_reaction
|
|
(
|
|
comment_id bigint not null,
|
|
user_uuid uuid not null,
|
|
reaction varchar(255) not null,
|
|
created_at timestamp with time zone not null,
|
|
primary key (comment_id, user_uuid, reaction)
|
|
);
|
|
|
|
create table if not exists issue_label
|
|
(
|
|
issue uuid not null,
|
|
label bigint not null,
|
|
relation_at timestamp with time zone not null,
|
|
primary key (issue, label)
|
|
);
|
|
|
|
create table if not exists issue_pull_request
|
|
(
|
|
issue uuid not null,
|
|
repo uuid not null,
|
|
number bigint not null,
|
|
relation_at timestamp with time zone not null,
|
|
primary key (issue, repo, number)
|
|
);
|
|
|
|
create table if not exists issue_reaction
|
|
(
|
|
issue_uuid uuid not null,
|
|
user_uuid uuid not null,
|
|
reaction varchar(255) not null,
|
|
created_at timestamp with time zone not null,
|
|
primary key (issue_uuid, user_uuid, reaction)
|
|
);
|
|
|
|
create table if not exists issue_repo
|
|
(
|
|
issue uuid not null,
|
|
repo uuid not null,
|
|
relation_at timestamp with time zone not null,
|
|
primary key (issue, repo)
|
|
);
|
|
|
|
create table if not exists issue_subscriber
|
|
(
|
|
issue uuid not null,
|
|
"user" uuid not null,
|
|
subscribed boolean default true not null,
|
|
created_at timestamp with time zone not null,
|
|
primary key (issue, "user")
|
|
);
|
|
|
|
create table if not exists pull_request
|
|
(
|
|
repo uuid not null,
|
|
number bigint not null,
|
|
issue uuid not null,
|
|
title varchar(255) not null,
|
|
body text,
|
|
author uuid not null,
|
|
base varchar(255) not null,
|
|
head varchar(255) not null,
|
|
status varchar(255) not null,
|
|
merged_by uuid,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null,
|
|
merged_at timestamp with time zone,
|
|
created_by_ai boolean default false not null,
|
|
primary key (repo, number)
|
|
);
|
|
|
|
create index if not exists idx_pull_request_repo
|
|
on pull_request (repo);
|
|
|
|
create index if not exists idx_pull_request_author
|
|
on pull_request (author);
|
|
|
|
create index if not exists idx_pull_request_status
|
|
on pull_request (status);
|
|
|
|
create table if not exists pull_request_commit
|
|
(
|
|
repo uuid not null,
|
|
number bigint not null,
|
|
commit varchar(255) not null,
|
|
message text not null,
|
|
author_name varchar(255) not null,
|
|
author_email varchar(255) not null,
|
|
authored_at timestamp with time zone not null,
|
|
committer_name varchar(255) not null,
|
|
committer_email varchar(255) not null,
|
|
committed_at timestamp with time zone not null,
|
|
created_at timestamp with time zone not null,
|
|
primary key (repo, number, commit)
|
|
);
|
|
|
|
create table if not exists pull_request_review
|
|
(
|
|
repo uuid not null,
|
|
number bigint not null,
|
|
reviewer uuid not null,
|
|
state varchar(255) not null,
|
|
body text,
|
|
submitted_at timestamp with time zone,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null,
|
|
primary key (repo, number, reviewer)
|
|
);
|
|
|
|
create table if not exists pull_request_review_comment
|
|
(
|
|
repo uuid not null,
|
|
number bigint not null,
|
|
id bigint not null,
|
|
review uuid,
|
|
path text,
|
|
side varchar(255),
|
|
line bigint,
|
|
old_line bigint,
|
|
body text not null,
|
|
author uuid not null,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null,
|
|
resolved boolean default false not null,
|
|
in_reply_to bigint,
|
|
primary key (repo, number, id)
|
|
);
|
|
|
|
create table if not exists room_category
|
|
(
|
|
id uuid not null
|
|
primary key,
|
|
project_uuid uuid not null,
|
|
name varchar(255) not null,
|
|
position integer not null,
|
|
created_by uuid not null,
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_room_category_project
|
|
on room_category (project_uuid);
|
|
|
|
create table if not exists room
|
|
(
|
|
id uuid not null
|
|
primary key,
|
|
project uuid not null,
|
|
room_name varchar(255) not null,
|
|
public boolean default false not null,
|
|
category uuid,
|
|
created_by uuid not null,
|
|
created_at timestamp with time zone not null,
|
|
last_msg_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_room_project
|
|
on room (project);
|
|
|
|
create index if not exists idx_room_category
|
|
on room (category);
|
|
|
|
create table if not exists room_ai
|
|
(
|
|
room uuid not null,
|
|
model uuid not null,
|
|
version uuid,
|
|
call_count bigint default 0 not null,
|
|
last_call_at timestamp with time zone,
|
|
history_limit bigint,
|
|
system_prompt text,
|
|
temperature double precision,
|
|
max_tokens bigint,
|
|
use_exact boolean default false not null,
|
|
think boolean default false not null,
|
|
min_score real,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null,
|
|
stream boolean default true not null,
|
|
agent_type varchar(50),
|
|
primary key (room, model)
|
|
);
|
|
|
|
create index if not exists idx_room_ai_agent_type
|
|
on room_ai (agent_type)
|
|
where (agent_type IS NOT NULL);
|
|
|
|
create table if not exists room_message
|
|
(
|
|
id uuid not null
|
|
primary key,
|
|
seq bigint not null,
|
|
room uuid not null,
|
|
sender_type varchar(255) not null,
|
|
sender_id uuid,
|
|
thread uuid,
|
|
content text not null,
|
|
content_type varchar(255) not null,
|
|
edited_at timestamp with time zone,
|
|
send_at timestamp with time zone not null,
|
|
revoked timestamp with time zone,
|
|
revoked_by uuid,
|
|
in_reply_to uuid,
|
|
content_tsv tsvector,
|
|
model_id uuid,
|
|
thinking_content text
|
|
);
|
|
|
|
create index if not exists idx_room_message_room_seq
|
|
on room_message (room, seq);
|
|
|
|
create index if not exists idx_room_message_thread
|
|
on room_message (thread);
|
|
|
|
create index if not exists idx_room_message_send_at
|
|
on room_message (send_at);
|
|
|
|
create index if not exists idx_room_message_content_tsv
|
|
on room_message using gin (content_tsv);
|
|
|
|
create index if not exists idx_room_message_model_id
|
|
on room_message (model_id)
|
|
where (model_id IS NOT NULL);
|
|
|
|
|
|
|
|
create table if not exists room_pin
|
|
(
|
|
room uuid not null,
|
|
message uuid not null,
|
|
pinned_by uuid not null,
|
|
pinned_at timestamp with time zone not null,
|
|
primary key (room, message)
|
|
);
|
|
|
|
create table if not exists room_thread
|
|
(
|
|
id uuid not null
|
|
primary key,
|
|
room uuid not null,
|
|
parent bigint not null,
|
|
created_by uuid not null,
|
|
participants jsonb not null,
|
|
last_message_at timestamp with time zone not null,
|
|
last_message_preview text,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_room_thread_room
|
|
on room_thread (room);
|
|
|
|
create table if not exists ai_model_provider
|
|
(
|
|
id uuid not null
|
|
primary key,
|
|
name varchar(255) not null,
|
|
display_name varchar(255) not null,
|
|
website varchar(255),
|
|
status varchar(255) not null,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null
|
|
);
|
|
|
|
create table if not exists ai_model
|
|
(
|
|
id uuid not null
|
|
primary key,
|
|
provider_id uuid not null,
|
|
name varchar(255) not null,
|
|
modality varchar(255) not null,
|
|
capability varchar(255) not null,
|
|
context_length bigint not null,
|
|
max_output_tokens bigint,
|
|
training_cutoff timestamp with time zone,
|
|
is_open_source boolean default false not null,
|
|
status varchar(255) not null,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_ai_model_provider_id
|
|
on ai_model (provider_id);
|
|
|
|
create table if not exists ai_model_version
|
|
(
|
|
id uuid not null
|
|
primary key,
|
|
model_id uuid not null,
|
|
version varchar(255) not null,
|
|
release_date timestamp with time zone,
|
|
change_log text,
|
|
is_default boolean default false not null,
|
|
status varchar(255) not null,
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_ai_model_version_model_id
|
|
on ai_model_version (model_id);
|
|
|
|
create table if not exists ai_model_capability
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
model_version_id uuid not null,
|
|
capability varchar(255) not null,
|
|
is_supported boolean default false not null,
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_ai_model_capability_model_version_id
|
|
on ai_model_capability (model_version_id);
|
|
|
|
create table if not exists ai_model_parameter_profile
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
model_version_id uuid not null
|
|
unique,
|
|
temperature_min double precision not null,
|
|
temperature_max double precision not null,
|
|
top_p_min double precision not null,
|
|
top_p_max double precision not null,
|
|
frequency_penalty_supported boolean default false not null,
|
|
presence_penalty_supported boolean default false not null
|
|
);
|
|
|
|
create unique index if not exists idx_ai_model_parameter_profile_model_version_id
|
|
on ai_model_parameter_profile (model_version_id);
|
|
|
|
create table if not exists ai_model_pricing
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
model_version_id uuid not null,
|
|
input_price_per_1k_tokens varchar(255) not null,
|
|
output_price_per_1k_tokens varchar(255) not null,
|
|
currency varchar(255) not null,
|
|
effective_from timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_ai_model_pricing_model_version_id
|
|
on ai_model_pricing (model_version_id);
|
|
|
|
create table if not exists ai_session
|
|
(
|
|
id uuid not null
|
|
primary key,
|
|
room uuid not null,
|
|
model uuid not null,
|
|
version uuid not null,
|
|
token_input bigint default 0 not null,
|
|
token_output bigint default 0 not null,
|
|
latency_ms bigint,
|
|
cost double precision,
|
|
currency varchar(255),
|
|
error_message text,
|
|
error_code varchar(255),
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_ai_session_room
|
|
on ai_session (room);
|
|
|
|
create table if not exists ai_tool_call
|
|
(
|
|
tool_call_id varchar(255) not null,
|
|
session uuid not null,
|
|
tool_name varchar(255) not null,
|
|
caller uuid not null,
|
|
arguments jsonb not null,
|
|
result jsonb not null,
|
|
status varchar(255) not null,
|
|
execution_time_ms bigint,
|
|
error_message text,
|
|
error_stack text,
|
|
retry_count integer default 0 not null,
|
|
created_at timestamp with time zone not null,
|
|
completed_at timestamp with time zone,
|
|
updated_at timestamp with time zone not null,
|
|
primary key (tool_call_id, session)
|
|
);
|
|
|
|
create index if not exists idx_ai_tool_call_session
|
|
on ai_tool_call (session);
|
|
|
|
create index if not exists idx_ai_tool_call_status
|
|
on ai_tool_call (status);
|
|
|
|
create table if not exists ai_tool_auth
|
|
(
|
|
session uuid not null,
|
|
tool_call_id varchar(255) not null,
|
|
method varchar(255) not null,
|
|
arguments text not null,
|
|
decision boolean default false not null,
|
|
reason varchar(255) not null,
|
|
decision_by uuid not null,
|
|
decision_comment text,
|
|
logs jsonb not null,
|
|
expires_at timestamp with time zone,
|
|
authorized_at timestamp with time zone,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null,
|
|
primary key (session, tool_call_id)
|
|
);
|
|
|
|
create table if not exists label
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
project_uuid uuid not null,
|
|
name varchar(255) not null,
|
|
color varchar(255) not null
|
|
);
|
|
|
|
create index if not exists idx_label_project
|
|
on label (project_uuid);
|
|
|
|
create table if not exists notify
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
user_uuid uuid not null,
|
|
title varchar(255) not null,
|
|
description text,
|
|
content text not null,
|
|
url varchar(255),
|
|
kind integer not null,
|
|
read_at timestamp with time zone,
|
|
deleted_at timestamp with time zone,
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_notify_user
|
|
on notify (user_uuid);
|
|
|
|
create index if not exists idx_notify_created_at
|
|
on notify (created_at);
|
|
|
|
create table if not exists room_notifications
|
|
(
|
|
id uuid not null
|
|
primary key,
|
|
room uuid,
|
|
project uuid,
|
|
user_id uuid,
|
|
notification_type varchar(255) not null,
|
|
related_message_id uuid,
|
|
related_user_id uuid,
|
|
related_room_id uuid,
|
|
title varchar(255) not null,
|
|
content text,
|
|
metadata jsonb,
|
|
is_read boolean default false not null,
|
|
is_archived boolean default false not null,
|
|
created_at timestamp with time zone not null,
|
|
read_at timestamp with time zone,
|
|
expires_at timestamp with time zone
|
|
);
|
|
|
|
create index if not exists idx_room_notifications_user_id_is_read
|
|
on room_notifications (user_id, is_read);
|
|
|
|
create index if not exists idx_room_notifications_user_id_created_at
|
|
on room_notifications (user_id, created_at);
|
|
|
|
create index if not exists idx_room_notifications_expires_at
|
|
on room_notifications (expires_at);
|
|
|
|
create table if not exists user_email_change
|
|
(
|
|
token varchar(255) not null
|
|
primary key,
|
|
user_uid uuid not null,
|
|
new_email varchar(255) not null,
|
|
expires_at timestamp with time zone not null,
|
|
used boolean default false not null,
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_user_email_change_user_uid
|
|
on user_email_change (user_uid);
|
|
|
|
create table if not exists project_activity
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
project uuid not null,
|
|
repo uuid,
|
|
actor uuid not null,
|
|
event_type varchar(50) not null,
|
|
event_id uuid,
|
|
event_sub_id bigint,
|
|
title varchar(500) not null,
|
|
content text,
|
|
metadata jsonb,
|
|
is_private boolean default false not null,
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_project_activity_project
|
|
on project_activity (project);
|
|
|
|
create index if not exists idx_project_activity_created_at
|
|
on project_activity (created_at desc);
|
|
|
|
create index if not exists idx_project_activity_event_type
|
|
on project_activity (event_type);
|
|
|
|
create table if not exists room_message_reaction
|
|
(
|
|
id uuid not null
|
|
primary key,
|
|
room uuid not null
|
|
references room
|
|
on delete cascade,
|
|
message uuid not null
|
|
references room_message
|
|
on delete cascade,
|
|
"user" uuid not null
|
|
references "user"
|
|
on delete cascade,
|
|
emoji varchar(50) not null,
|
|
created_at timestamp with time zone default now() not null,
|
|
unique (message, "user", emoji)
|
|
);
|
|
|
|
create index if not exists idx_room_message_reaction_message
|
|
on room_message_reaction (message);
|
|
|
|
create index if not exists idx_room_message_reaction_user
|
|
on room_message_reaction ("user");
|
|
|
|
create index if not exists idx_room_message_reaction_room
|
|
on room_message_reaction (room);
|
|
|
|
create table if not exists room_message_edit_history
|
|
(
|
|
id uuid not null
|
|
primary key,
|
|
message uuid not null
|
|
references room_message
|
|
on delete cascade,
|
|
"user" uuid not null
|
|
references "user"
|
|
on delete cascade,
|
|
old_content text not null,
|
|
new_content text not null,
|
|
edited_at timestamp with time zone default now() not null
|
|
);
|
|
|
|
create index if not exists idx_room_message_edit_history_message
|
|
on room_message_edit_history (message);
|
|
|
|
create index if not exists idx_room_message_edit_history_user
|
|
on room_message_edit_history ("user");
|
|
|
|
create table if not exists project_board
|
|
(
|
|
id uuid default gen_random_uuid() not null
|
|
primary key,
|
|
project_uuid uuid not null,
|
|
name varchar(255) not null,
|
|
description text,
|
|
created_by uuid not null,
|
|
created_at timestamp with time zone default now() not null,
|
|
updated_at timestamp with time zone default now() not null
|
|
);
|
|
|
|
create index if not exists idx_project_board_project
|
|
on project_board (project_uuid);
|
|
|
|
create table if not exists project_board_column
|
|
(
|
|
id uuid default gen_random_uuid() not null
|
|
primary key,
|
|
board_uuid uuid not null
|
|
references project_board
|
|
on delete cascade,
|
|
name varchar(255) not null,
|
|
position integer default 0 not null,
|
|
wip_limit integer,
|
|
color varchar(20)
|
|
);
|
|
|
|
create index if not exists idx_project_board_column_board
|
|
on project_board_column (board_uuid);
|
|
|
|
create table if not exists project_board_card
|
|
(
|
|
id uuid default gen_random_uuid() not null
|
|
primary key,
|
|
column_uuid uuid not null
|
|
references project_board_column
|
|
on delete cascade,
|
|
issue_id bigint,
|
|
project uuid,
|
|
title varchar(500) not null,
|
|
description text,
|
|
position integer default 0 not null,
|
|
assignee_id uuid,
|
|
due_date timestamp with time zone,
|
|
priority varchar(10),
|
|
created_by uuid not null,
|
|
created_at timestamp with time zone default now() not null,
|
|
updated_at timestamp with time zone default now() not null
|
|
);
|
|
|
|
create index if not exists idx_project_board_card_column
|
|
on project_board_card (column_uuid);
|
|
|
|
create index if not exists idx_project_board_card_issue
|
|
on project_board_card (issue_id)
|
|
where (issue_id IS NOT NULL);
|
|
|
|
create table if not exists pull_request_review_request
|
|
(
|
|
repo uuid not null,
|
|
number bigint not null,
|
|
reviewer uuid not null,
|
|
requested_by uuid not null,
|
|
requested_at timestamp with time zone default now() not null,
|
|
dismissed_at timestamp with time zone,
|
|
dismissed_by uuid,
|
|
primary key (repo, number, reviewer)
|
|
);
|
|
|
|
create table if not exists workspace
|
|
(
|
|
id uuid not null
|
|
primary key,
|
|
slug varchar(255) not null,
|
|
name varchar(255) not null,
|
|
description text,
|
|
avatar_url varchar(255),
|
|
plan varchar(50) default 'free'::character varying not null,
|
|
billing_email varchar(255),
|
|
stripe_customer_id varchar(255),
|
|
stripe_subscription_id varchar(255),
|
|
plan_expires_at timestamp with time zone,
|
|
deleted_at timestamp with time zone,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null
|
|
);
|
|
|
|
create table if not exists project
|
|
(
|
|
id uuid not null
|
|
primary key,
|
|
name varchar(255) not null,
|
|
display_name varchar(255) not null,
|
|
avatar_url varchar(255),
|
|
description text,
|
|
is_public boolean default false not null,
|
|
created_by uuid not null,
|
|
created_at timestamp with time zone not null,
|
|
updated_at timestamp with time zone not null,
|
|
workspace_id uuid
|
|
references workspace
|
|
on delete set null
|
|
);
|
|
|
|
create index if not exists idx_project_name
|
|
on project (name);
|
|
|
|
create index if not exists idx_project_created_by
|
|
on project (created_by);
|
|
|
|
create index if not exists idx_project_workspace_id
|
|
on project (workspace_id)
|
|
where (workspace_id IS NOT NULL);
|
|
|
|
create unique index if not exists idx_workspace_slug
|
|
on workspace (slug);
|
|
|
|
create index if not exists idx_workspace_deleted_at
|
|
on workspace (deleted_at);
|
|
|
|
create table if not exists workspace_membership
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
workspace_id uuid not null,
|
|
user_id uuid not null,
|
|
role varchar(50) default 'member'::character varying not null,
|
|
status varchar(50) default 'active'::character varying not null,
|
|
invited_by uuid,
|
|
joined_at timestamp with time zone not null,
|
|
invite_token varchar(255),
|
|
invite_expires_at timestamp with time zone,
|
|
unique (workspace_id, user_id)
|
|
);
|
|
|
|
create unique index if not exists idx_workspace_membership_ws_user
|
|
on workspace_membership (workspace_id, user_id);
|
|
|
|
create index if not exists idx_workspace_membership_user
|
|
on workspace_membership (user_id);
|
|
|
|
create index if not exists idx_workspace_membership_invite_token
|
|
on workspace_membership (invite_token)
|
|
where (invite_token IS NOT NULL);
|
|
|
|
create table if not exists workspace_billing
|
|
(
|
|
workspace_id uuid not null
|
|
primary key
|
|
references workspace
|
|
on delete cascade,
|
|
balance numeric(20, 4) default 0 not null,
|
|
currency varchar(10) default 'USD'::character varying not null,
|
|
monthly_quota numeric(20, 4) default 0 not null,
|
|
total_spent numeric(20, 4) default 0 not null,
|
|
updated_at timestamp with time zone not null,
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create table if not exists workspace_billing_history
|
|
(
|
|
uid uuid not null
|
|
primary key,
|
|
workspace_id uuid not null
|
|
references workspace
|
|
on delete cascade,
|
|
user_id uuid,
|
|
amount numeric(20, 4) not null,
|
|
currency varchar(10) default 'USD'::character varying not null,
|
|
reason varchar(100) not null,
|
|
extra jsonb,
|
|
created_at timestamp with time zone not null
|
|
);
|
|
|
|
create index if not exists idx_wsbh_workspace_id
|
|
on workspace_billing_history (workspace_id);
|
|
|
|
create index if not exists idx_wsbh_created_at
|
|
on workspace_billing_history (created_at desc);
|
|
|
|
create table if not exists project_skill
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
project_uuid uuid not null,
|
|
slug varchar(255) not null,
|
|
name varchar(255) not null,
|
|
description text,
|
|
source varchar(20) default 'manual'::character varying not null,
|
|
repo_id uuid,
|
|
content text default ''::text not null,
|
|
metadata jsonb default '{}'::jsonb not null,
|
|
enabled boolean default true not null,
|
|
created_by uuid,
|
|
created_at timestamp with time zone default now() not null,
|
|
updated_at timestamp with time zone default now() not null,
|
|
commit_sha varchar(40),
|
|
blob_hash varchar(40),
|
|
unique (project_uuid, slug)
|
|
);
|
|
|
|
create index if not exists idx_project_skill_project
|
|
on project_skill (project_uuid);
|
|
|
|
create index if not exists idx_project_skill_slug
|
|
on project_skill (slug);
|
|
|
|
create index if not exists idx_project_skill_source
|
|
on project_skill (source);
|
|
|
|
create index if not exists idx_project_skill_commit_sha
|
|
on project_skill (commit_sha);
|
|
|
|
create index if not exists idx_project_skill_blob_hash
|
|
on project_skill (blob_hash);
|
|
|
|
create table if not exists agent_task
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
project_uuid uuid not null,
|
|
parent_id bigint
|
|
constraint fk_agent_task_parent
|
|
references agent_task
|
|
on delete set null,
|
|
agent_type varchar(20) default 'react'::character varying not null,
|
|
status varchar(20) default 'pending'::character varying not null,
|
|
title varchar(255),
|
|
input text not null,
|
|
output text,
|
|
error text,
|
|
created_by uuid,
|
|
created_at timestamp with time zone default now() not null,
|
|
updated_at timestamp with time zone default now() not null,
|
|
started_at timestamp with time zone,
|
|
done_at timestamp with time zone,
|
|
progress varchar(255),
|
|
issue_id uuid,
|
|
retry_count integer default 0
|
|
);
|
|
|
|
create index if not exists idx_agent_task_project
|
|
on agent_task (project_uuid);
|
|
|
|
create index if not exists idx_agent_task_parent
|
|
on agent_task (parent_id);
|
|
|
|
create index if not exists idx_agent_task_status
|
|
on agent_task (status);
|
|
|
|
create index if not exists idx_agent_task_created_by
|
|
on agent_task (created_by);
|
|
|
|
create index if not exists idx_agent_task_created_at
|
|
on agent_task (created_at);
|
|
|
|
create index if not exists idx_agent_task_issue
|
|
on agent_task (issue_id);
|
|
|
|
create index if not exists idx_agent_task_retry_count
|
|
on agent_task (retry_count);
|
|
|
|
create table if not exists admin_user
|
|
(
|
|
id serial
|
|
primary key,
|
|
username varchar(255) not null
|
|
unique,
|
|
password_hash varchar(255) not null,
|
|
is_active boolean default true not null,
|
|
created_at timestamp with time zone default now() not null,
|
|
updated_at timestamp with time zone default now() not null
|
|
);
|
|
|
|
create index if not exists idx_admin_user_username
|
|
on admin_user (username);
|
|
|
|
create table if not exists admin_role
|
|
(
|
|
id serial
|
|
primary key,
|
|
name varchar(255) not null
|
|
unique,
|
|
description text,
|
|
created_at timestamp with time zone default now() not null
|
|
);
|
|
|
|
create table if not exists admin_permission
|
|
(
|
|
id serial
|
|
primary key,
|
|
name varchar(255) not null,
|
|
code varchar(255) not null
|
|
unique,
|
|
description text,
|
|
created_at timestamp with time zone default now() not null
|
|
);
|
|
|
|
create table if not exists admin_user_role
|
|
(
|
|
user_id integer not null
|
|
references admin_user
|
|
on delete cascade,
|
|
role_id integer not null
|
|
references admin_role
|
|
on delete cascade,
|
|
primary key (user_id, role_id)
|
|
);
|
|
|
|
create table if not exists admin_role_permission
|
|
(
|
|
role_id integer not null
|
|
references admin_role
|
|
on delete cascade,
|
|
permission_id integer not null
|
|
references admin_permission
|
|
on delete cascade,
|
|
primary key (role_id, permission_id)
|
|
);
|
|
|
|
create table if not exists admin_audit_log
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
user_id integer not null,
|
|
username varchar(255) not null,
|
|
action varchar(50) not null,
|
|
resource varchar(255) not null,
|
|
resource_id varchar(255),
|
|
request_params jsonb,
|
|
ip_address varchar(255),
|
|
user_agent text,
|
|
result varchar(20) default 'success'::character varying not null,
|
|
error_message text,
|
|
created_at timestamp with time zone default now() not null
|
|
);
|
|
|
|
create index if not exists idx_admin_audit_log_user_id
|
|
on admin_audit_log (user_id);
|
|
|
|
create index if not exists idx_admin_audit_log_created_at
|
|
on admin_audit_log (created_at desc);
|
|
|
|
create index if not exists idx_admin_audit_log_action
|
|
on admin_audit_log (action);
|
|
|
|
create index if not exists idx_admin_audit_log_resource
|
|
on admin_audit_log (resource);
|
|
|
|
create table if not exists admin_api_token
|
|
(
|
|
id serial
|
|
primary key,
|
|
name varchar(255) not null,
|
|
token_hash varchar(64) not null
|
|
unique,
|
|
token_prefix varchar(32) not null,
|
|
permissions text[] default '{}'::text[] not null,
|
|
created_by integer not null
|
|
references admin_user
|
|
on delete set null,
|
|
created_at timestamp with time zone default now() not null,
|
|
last_used_at timestamp with time zone,
|
|
expires_at timestamp with time zone,
|
|
is_active boolean default true not null
|
|
);
|
|
|
|
comment on table admin_api_token is 'Admin API Token for programmatic access';
|
|
|
|
create index if not exists idx_admin_api_token_hash
|
|
on admin_api_token (token_hash);
|
|
|
|
create table if not exists workspace_alert_config
|
|
(
|
|
id serial
|
|
primary key,
|
|
workspace_id uuid not null,
|
|
alert_type varchar(32) not null,
|
|
threshold numeric(10, 4) not null,
|
|
email_enabled boolean default true,
|
|
enabled boolean default true,
|
|
created_by integer,
|
|
created_at timestamp with time zone default now(),
|
|
updated_at timestamp with time zone default now(),
|
|
unique (workspace_id, alert_type)
|
|
);
|
|
|
|
create index if not exists idx_alert_config_workspace
|
|
on workspace_alert_config (workspace_id);
|
|
|
|
create table if not exists room_attachment
|
|
(
|
|
id uuid not null
|
|
primary key,
|
|
room uuid not null,
|
|
message uuid not null,
|
|
uploader uuid not null,
|
|
file_name varchar(255) not null,
|
|
file_size bigint not null,
|
|
content_type varchar(100) not null,
|
|
s3_key varchar(500) not null,
|
|
created_at timestamp with time zone default now() not null
|
|
);
|
|
|
|
create index if not exists idx_room_attachment_room
|
|
on room_attachment (room);
|
|
|
|
create index if not exists idx_room_attachment_message
|
|
on room_attachment (message);
|
|
|
|
create index if not exists idx_room_attachment_uploader
|
|
on room_attachment (uploader);
|
|
|
|
create table if not exists room_access
|
|
(
|
|
room uuid not null,
|
|
"user" uuid not null,
|
|
granted_by uuid not null,
|
|
granted_at timestamp with time zone default now() not null,
|
|
primary key (room, "user")
|
|
);
|
|
|
|
create index if not exists idx_room_access_user
|
|
on room_access ("user");
|
|
|
|
create table if not exists room_user_state
|
|
(
|
|
room uuid not null,
|
|
"user" uuid not null,
|
|
last_read_seq bigint,
|
|
do_not_disturb boolean default false not null,
|
|
dnd_start_hour smallint,
|
|
dnd_end_hour smallint,
|
|
joined_at timestamp with time zone,
|
|
primary key (room, "user")
|
|
);
|
|
|
|
create index if not exists idx_room_user_state_user
|
|
on room_user_state ("user");
|
|
|
|
create table if not exists project_role_priority
|
|
(
|
|
id bigserial
|
|
primary key,
|
|
project_uuid uuid not null,
|
|
role_key varchar(64) not null,
|
|
display_name varchar(128) not null,
|
|
priority integer default 0 not null,
|
|
color varchar(32),
|
|
created_at timestamp with time zone default now(),
|
|
updated_at timestamp with time zone default now(),
|
|
unique (project_uuid, role_key)
|
|
);
|
|
|
|
create index if not exists idx_project_role_priority_project
|
|
on project_role_priority (project_uuid);
|
|
|
|
create index if not exists idx_project_role_priority_priority
|
|
on project_role_priority (project_uuid, priority);
|
|
|
|
create table if not exists ai_conversation
|
|
(
|
|
id uuid default gen_random_uuid() not null
|
|
primary key,
|
|
user_id uuid not null,
|
|
project_id uuid
|
|
constraint fk_ai_conv_project
|
|
references project
|
|
on delete cascade,
|
|
scope varchar(16) not null,
|
|
title varchar(512),
|
|
model varchar(128) default 'gpt-4'::character varying not null,
|
|
model_config jsonb,
|
|
status varchar(32) default 'active'::character varying not null,
|
|
root_message_id uuid,
|
|
fork_count integer default 0 not null,
|
|
is_shared boolean default false not null,
|
|
message_count integer default 0 not null,
|
|
token_usage_total integer,
|
|
created_at timestamp with time zone default now() not null,
|
|
updated_at timestamp with time zone default now() not null,
|
|
access_visibility varchar(32) default 'owner'::character varying not null,
|
|
can_ask varchar(32) default 'owner'::character varying not null,
|
|
project_uid integer,
|
|
model_uid uuid,
|
|
model_name varchar(256)
|
|
);
|
|
|
|
create index if not exists idx_ai_conv_user_id
|
|
on ai_conversation (user_id);
|
|
|
|
create index if not exists idx_ai_conv_project_id
|
|
on ai_conversation (project_id);
|
|
|
|
create index if not exists idx_ai_conv_scope
|
|
on ai_conversation (scope);
|
|
|
|
create index if not exists idx_ai_conv_user_created
|
|
on ai_conversation (user_id asc, created_at desc);
|
|
|
|
create index if not exists idx_ai_conv_project_created
|
|
on ai_conversation (project_id asc, created_at desc);
|
|
|
|
create index if not exists idx_ai_conv_access_vis
|
|
on ai_conversation (access_visibility);
|
|
|
|
create index if not exists idx_ai_conv_project_uid
|
|
on ai_conversation (project_id, project_uid)
|
|
where (project_uid IS NOT NULL);
|
|
|
|
create table if not exists ai_message
|
|
(
|
|
id uuid default gen_random_uuid() not null
|
|
primary key,
|
|
conversation_id uuid not null
|
|
constraint fk_ai_msg_conv
|
|
references ai_conversation
|
|
on delete cascade,
|
|
parent_message_id uuid
|
|
constraint fk_ai_msg_parent
|
|
references ai_message
|
|
on delete set null,
|
|
role varchar(16) not null,
|
|
content jsonb not null,
|
|
model varchar(128),
|
|
is_fork_origin boolean default false not null,
|
|
stop_reason varchar(32),
|
|
input_tokens integer,
|
|
output_tokens integer,
|
|
latency_ms integer,
|
|
metadata jsonb,
|
|
room_id uuid,
|
|
created_at timestamp with time zone default now() not null
|
|
);
|
|
|
|
create index if not exists idx_ai_msg_conv
|
|
on ai_message (conversation_id, created_at);
|
|
|
|
create index if not exists idx_ai_msg_parent
|
|
on ai_message (parent_message_id);
|
|
|
|
create table if not exists ai_message_fork
|
|
(
|
|
id uuid default gen_random_uuid() not null
|
|
primary key,
|
|
source_message_id uuid not null
|
|
constraint fk_ai_fork_source
|
|
references ai_message
|
|
on delete cascade,
|
|
fork_message_id uuid not null
|
|
constraint fk_ai_fork_fork
|
|
references ai_message
|
|
on delete cascade,
|
|
created_at timestamp with time zone default now() not null
|
|
);
|
|
|
|
create index if not exists idx_ai_fork_source
|
|
on ai_message_fork (source_message_id);
|
|
|
|
create index if not exists idx_ai_fork_fork
|
|
on ai_message_fork (fork_message_id);
|
|
|
|
create table if not exists ai_shared_conversation
|
|
(
|
|
id uuid default gen_random_uuid() not null
|
|
primary key,
|
|
conversation_id uuid not null
|
|
constraint fk_ai_share_conv
|
|
references ai_conversation
|
|
on delete cascade,
|
|
share_token varchar(128) not null
|
|
unique,
|
|
created_by uuid not null,
|
|
view_count integer default 0 not null,
|
|
created_at timestamp with time zone default now() not null,
|
|
expires_at timestamp with time zone
|
|
);
|
|
|
|
create index if not exists idx_ai_share_conv
|
|
on ai_shared_conversation (conversation_id);
|
|
|
|
create index if not exists idx_ai_share_token
|
|
on ai_shared_conversation (share_token);
|
|
|
|
create table if not exists ai_token_usage
|
|
(
|
|
id uuid default gen_random_uuid() not null
|
|
primary key,
|
|
user_id uuid not null,
|
|
conversation_id uuid,
|
|
model varchar(128) not null,
|
|
input_tokens integer not null,
|
|
output_tokens integer not null,
|
|
cost_usd numeric(10, 6),
|
|
recorded_at timestamp with time zone default now() not null
|
|
);
|
|
|
|
create index if not exists idx_ai_token_user
|
|
on ai_token_usage (user_id);
|
|
|
|
create index if not exists idx_ai_token_conv
|
|
on ai_token_usage (conversation_id);
|
|
|
|
create index if not exists idx_ai_token_recorded
|
|
on ai_token_usage (recorded_at);
|
|
|