gitdataai/libs/migrate/sql/init.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);