Files
AgentCompany/AgentCompany-Rust/crates/storage/src/schema.rs
T

369 lines
13 KiB
Rust

use anyhow::Result;
use domain::CONNECTOR_SEEDS;
use rusqlite::{Connection, params};
use support::time::now_iso;
pub fn initialize(conn: &Connection) -> Result<()> {
conn.execute_batch(
r#"
create table if not exists settings (
key text primary key,
value text not null
);
create table if not exists companies (
id text primary key,
name text not null,
description text not null default '',
status text not null default 'active',
auto_approve_hires integer not null default 0,
review_deliverables integer not null default 0,
execution_mode text not null default 'ai_ceo',
created_at text not null,
updated_at text not null
);
create table if not exists connectors (
id text primary key,
label text not null,
description text not null,
status text not null default 'not_installed',
command text not null default '',
version text null,
auth_state text not null default 'unknown',
last_checked_at text null,
last_error text null,
model text null,
env_binding_text text not null default '',
notes text not null default '',
updated_at text not null
);
create table if not exists workspaces (
id text primary key,
company_id text not null,
name text not null,
local_path text not null,
repo_url text not null default '',
repo_ref text not null default '',
project_id text null,
state text not null default 'ready',
is_primary integer not null default 0,
lock_holder_run_id text null,
lock_acquired_at text null,
created_at text not null,
updated_at text not null,
foreign key(company_id) references companies(id) on delete cascade
);
create table if not exists agents (
id text primary key,
company_id text not null,
name text not null,
role text not null default '',
title text not null default '',
department text null,
status text not null default 'idle',
reports_to text null,
connector_id text not null default 'anthropic',
workspace_id text null,
model text null,
capabilities text not null default '[]',
budget_monthly_usd real not null default 0,
spent_monthly_usd real not null default 0,
metadata_json text not null default '{}',
heartbeat_enabled integer not null default 0,
heartbeat_interval_sec integer not null default 0,
last_heartbeat_at text null,
created_at text not null,
updated_at text not null,
foreign key(company_id) references companies(id) on delete cascade
);
create table if not exists goals (
id text primary key,
company_id text not null,
title text not null,
description text not null default '',
parent_id text null,
owner_agent_id text null,
status text not null default 'planned',
created_at text not null,
updated_at text not null,
foreign key(company_id) references companies(id) on delete cascade
);
create table if not exists projects (
id text primary key,
company_id text not null,
goal_id text null,
name text not null,
description text not null default '',
lead_agent_id text null,
status text not null default 'planned',
target_date text null,
created_at text not null,
updated_at text not null,
foreign key(company_id) references companies(id) on delete cascade
);
create table if not exists tasks (
id text primary key,
company_id text not null,
project_id text null,
goal_id text null,
parent_id text null,
title text not null,
description text not null default '',
assignee_agent_id text null,
workspace_id text null,
status text not null default 'todo',
priority text not null default 'medium',
active_run_id text null,
cost_usd real not null default 0,
task_type text null,
requires_user_review integer not null default 0,
started_at text null,
completed_at text null,
cancelled_at text null,
created_at text not null,
updated_at text not null,
foreign key(company_id) references companies(id) on delete cascade
);
create table if not exists approvals (
id text primary key,
company_id text not null,
related_task_id text null,
requested_by_agent_id text null,
related_agent_id text null,
type text not null,
payload_summary text not null default '',
impact_summary text not null default '',
payload_json text null,
decision_note text not null default '',
state text not null default 'pending',
created_at text not null,
updated_at text not null,
foreign key(company_id) references companies(id) on delete cascade
);
create table if not exists runs (
id text primary key,
company_id text not null,
task_id text null,
agent_id text not null,
workspace_id text null,
connector_id text not null,
status text not null default 'queued',
summary text not null default '',
error_message text null,
exit_code integer null,
signal text null,
model text null,
cost_usd real null,
unattributed_cost integer not null default 0,
started_at text null,
finished_at text null,
log_path text null,
created_at text not null,
updated_at text not null,
foreign key(company_id) references companies(id) on delete cascade
);
create table if not exists activity (
id text primary key,
company_id text not null,
actor text not null,
action text not null,
entity_type text not null,
entity_id text not null,
detail text not null,
created_at text not null,
foreign key(company_id) references companies(id) on delete cascade
);
create table if not exists run_events (
id text primary key,
company_id text not null,
run_id text not null,
event_kind text not null,
title text not null,
detail text not null default '',
created_at text not null,
foreign key(company_id) references companies(id) on delete cascade,
foreign key(run_id) references runs(id) on delete cascade
);
create table if not exists artifacts (
id text primary key,
company_id text not null,
run_id text not null,
provider text not null,
external_id text not null,
title text not null,
metadata_json text not null default '{}',
created_at text not null,
foreign key(company_id) references companies(id) on delete cascade,
foreign key(run_id) references runs(id) on delete cascade
);
create table if not exists agent_messages (
id text primary key,
company_id text not null,
from_agent_id text not null,
to_agent_id text null,
sender_kind text not null default 'human',
channel text not null default 'company',
channel_target_id text null,
subject text not null,
body text not null,
priority text not null default 'normal',
read_at text null,
parent_message_id text null,
attachments_json text not null default '[]',
created_at text not null,
foreign key(company_id) references companies(id) on delete cascade
);
create table if not exists agent_message_reads (
message_id text not null,
agent_id text not null,
read_at text not null,
primary key(message_id, agent_id)
);
create table if not exists documents (
id text primary key,
company_id text not null,
type text not null,
title text not null,
content text not null default '',
author_agent_id text null,
reviewer_agent_id text null,
project_id text null,
goal_id text null,
parent_doc_id text null,
version integer not null default 1,
status text not null default 'draft',
tags_json text not null default '[]',
latest_revision_id text null,
source_run_id text null,
created_at text not null,
updated_at text not null,
foreign key(company_id) references companies(id) on delete cascade
);
create table if not exists document_revisions (
id text primary key,
company_id text not null,
document_id text not null,
revision_number integer not null,
body text not null,
change_summary text null,
created_by_agent_id text null,
created_by_user_id text null,
created_at text not null,
foreign key(company_id) references companies(id) on delete cascade,
foreign key(document_id) references documents(id) on delete cascade
);
create table if not exists conversation_threads (
id text primary key,
company_id text not null,
title text not null,
type text not null,
related_entity_type text null,
related_entity_id text null,
created_at text not null,
updated_at text not null,
foreign key(company_id) references companies(id) on delete cascade
);
create table if not exists conversation_events (
id text primary key,
thread_id text not null,
actor_id text not null,
actor_type text not null,
event_type text not null,
body text not null,
metadata_json text not null default '{}',
created_at text not null,
foreign key(thread_id) references conversation_threads(id) on delete cascade
);
create table if not exists conversation_participants (
thread_id text not null,
participant_id text not null,
participant_type text not null,
role text not null default 'member',
joined_at text not null,
primary key(thread_id, participant_id)
);
create table if not exists thread_wait_states (
id text primary key,
thread_id text not null,
company_id text not null,
waiting_for text not null,
related_approval_id text null,
reason text not null,
created_at text not null,
resolved_at text null,
foreign key(thread_id) references conversation_threads(id) on delete cascade,
foreign key(company_id) references companies(id) on delete cascade
);
create table if not exists work_products (
id text primary key,
company_id text not null,
project_id text null,
task_id text null,
type text not null,
provider text not null,
external_id text null,
title text not null,
url text null,
status text not null default 'active',
review_state text not null default 'none',
is_primary integer not null default 0,
summary text null,
metadata_json text null,
created_by_run_id text null,
created_at text not null,
updated_at text not null,
foreign key(company_id) references companies(id) on delete cascade
);
"#,
)?;
seed_connectors(conn)?;
Ok(())
}
fn seed_connectors(conn: &Connection) -> Result<()> {
let updated_at = now_iso()?;
let mut statement = conn.prepare(
r#"
insert into connectors (
id, label, description, status, command, version, auth_state,
last_checked_at, last_error, model, env_binding_text, notes, updated_at
)
values (?1, ?2, ?3, 'not_installed', '', null, 'unknown', null, null, null, '', '', ?4)
on conflict(id) do update set
label = excluded.label,
description = excluded.description,
updated_at = excluded.updated_at
"#,
)?;
for connector in CONNECTOR_SEEDS {
statement.execute(params![
connector.id,
connector.label,
connector.description,
updated_at
])?;
}
Ok(())
}