@matteai/stma-server 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/index.js +18444 -0
  2. package/dist/index.js.map +1 -0
  3. package/drizzle/0000_nappy_franklin_storm.sql +115 -0
  4. package/drizzle/0001_grey_ogun.sql +1 -0
  5. package/drizzle/0002_crazy_vindicator.sql +1 -0
  6. package/drizzle/0003_tan_puma.sql +1 -0
  7. package/drizzle/0004_dry_selene.sql +40 -0
  8. package/drizzle/0005_hot_the_fallen.sql +103 -0
  9. package/drizzle/0006_cooing_cargill.sql +42 -0
  10. package/drizzle/0007_public_slyde.sql +12 -0
  11. package/drizzle/0008_loving_maestro.sql +9 -0
  12. package/drizzle/0009_cultured_bucky.sql +15 -0
  13. package/drizzle/0010_dazzling_mephisto.sql +26 -0
  14. package/drizzle/0011_kind_toxin.sql +20 -0
  15. package/drizzle/0012_ordinary_jamie_braddock.sql +31 -0
  16. package/drizzle/0013_warm_silk_fever.sql +7 -0
  17. package/drizzle/0014_talented_squadron_sinister.sql +22 -0
  18. package/drizzle/0015_wild_bill_hollister.sql +8 -0
  19. package/drizzle/0016_lucky_shooting_star.sql +8 -0
  20. package/drizzle/0017_same_blindfold.sql +21 -0
  21. package/drizzle/0018_premium_namora.sql +20 -0
  22. package/drizzle/0019_brown_dragon_lord.sql +6 -0
  23. package/drizzle/meta/0000_snapshot.json +845 -0
  24. package/drizzle/meta/0001_snapshot.json +851 -0
  25. package/drizzle/meta/0002_snapshot.json +857 -0
  26. package/drizzle/meta/0003_snapshot.json +863 -0
  27. package/drizzle/meta/0004_snapshot.json +1204 -0
  28. package/drizzle/meta/0005_snapshot.json +2063 -0
  29. package/drizzle/meta/0006_snapshot.json +2080 -0
  30. package/drizzle/meta/0007_snapshot.json +2157 -0
  31. package/drizzle/meta/0008_snapshot.json +2216 -0
  32. package/drizzle/meta/0009_snapshot.json +2314 -0
  33. package/drizzle/meta/0010_snapshot.json +2431 -0
  34. package/drizzle/meta/0011_snapshot.json +2608 -0
  35. package/drizzle/meta/0012_snapshot.json +2870 -0
  36. package/drizzle/meta/0013_snapshot.json +2918 -0
  37. package/drizzle/meta/0014_snapshot.json +3081 -0
  38. package/drizzle/meta/0015_snapshot.json +3093 -0
  39. package/drizzle/meta/0017_snapshot.json +3271 -0
  40. package/drizzle/meta/0018_snapshot.json +3430 -0
  41. package/drizzle/meta/0019_snapshot.json +3466 -0
  42. package/drizzle/meta/_journal.json +146 -0
  43. package/package.json +67 -0
@@ -0,0 +1,115 @@
1
+ CREATE TABLE "debug_sessions" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "team_id" uuid NOT NULL,
4
+ "title" text NOT NULL,
5
+ "status" text DEFAULT 'open' NOT NULL,
6
+ "opened_by" uuid,
7
+ "context" jsonb,
8
+ "resolution" jsonb,
9
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
10
+ "resolved_at" timestamp with time zone
11
+ );
12
+ --> statement-breakpoint
13
+ CREATE TABLE "invites" (
14
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
15
+ "team_id" uuid NOT NULL,
16
+ "code" text NOT NULL,
17
+ "created_by" uuid,
18
+ "expires_at" timestamp with time zone NOT NULL,
19
+ "uses" integer DEFAULT 0 NOT NULL,
20
+ "max_uses" integer,
21
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
22
+ CONSTRAINT "invites_code_unique" UNIQUE("code")
23
+ );
24
+ --> statement-breakpoint
25
+ CREATE TABLE "memberships" (
26
+ "team_id" uuid NOT NULL,
27
+ "user_id" uuid NOT NULL,
28
+ "role" text DEFAULT 'member' NOT NULL,
29
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
30
+ CONSTRAINT "memberships_team_id_user_id_pk" PRIMARY KEY("team_id","user_id")
31
+ );
32
+ --> statement-breakpoint
33
+ CREATE TABLE "messages" (
34
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
35
+ "session_id" uuid NOT NULL,
36
+ "author_id" uuid,
37
+ "kind" text DEFAULT 'note' NOT NULL,
38
+ "body" text NOT NULL,
39
+ "attachments" jsonb,
40
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
41
+ );
42
+ --> statement-breakpoint
43
+ CREATE TABLE "read_state" (
44
+ "user_id" uuid NOT NULL,
45
+ "session_id" uuid NOT NULL,
46
+ "last_read_at" timestamp with time zone DEFAULT now() NOT NULL,
47
+ CONSTRAINT "read_state_user_id_session_id_pk" PRIMARY KEY("user_id","session_id")
48
+ );
49
+ --> statement-breakpoint
50
+ CREATE TABLE "snapshots" (
51
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
52
+ "team_id" uuid NOT NULL,
53
+ "user_id" uuid NOT NULL,
54
+ "repo" text,
55
+ "data" jsonb NOT NULL,
56
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
57
+ );
58
+ --> statement-breakpoint
59
+ CREATE TABLE "teams" (
60
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
61
+ "name" text NOT NULL,
62
+ "slug" text NOT NULL,
63
+ "created_by" uuid,
64
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
65
+ CONSTRAINT "teams_slug_unique" UNIQUE("slug")
66
+ );
67
+ --> statement-breakpoint
68
+ CREATE TABLE "tokens" (
69
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
70
+ "user_id" uuid NOT NULL,
71
+ "name" text NOT NULL,
72
+ "token_hash" text NOT NULL,
73
+ "prefix" text NOT NULL,
74
+ "last_used_at" timestamp with time zone,
75
+ "revoked_at" timestamp with time zone,
76
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
77
+ CONSTRAINT "tokens_token_hash_unique" UNIQUE("token_hash")
78
+ );
79
+ --> statement-breakpoint
80
+ CREATE TABLE "users" (
81
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
82
+ "github_id" bigint,
83
+ "username" text NOT NULL,
84
+ "display_name" text,
85
+ "email" text,
86
+ "avatar_url" text,
87
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
88
+ CONSTRAINT "users_github_id_unique" UNIQUE("github_id"),
89
+ CONSTRAINT "users_username_unique" UNIQUE("username")
90
+ );
91
+ --> statement-breakpoint
92
+ CREATE TABLE "web_sessions" (
93
+ "id" text PRIMARY KEY NOT NULL,
94
+ "user_id" uuid NOT NULL,
95
+ "expires_at" timestamp with time zone NOT NULL,
96
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
97
+ );
98
+ --> statement-breakpoint
99
+ ALTER TABLE "debug_sessions" ADD CONSTRAINT "debug_sessions_team_id_teams_id_fk" FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
100
+ ALTER TABLE "debug_sessions" ADD CONSTRAINT "debug_sessions_opened_by_users_id_fk" FOREIGN KEY ("opened_by") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
101
+ ALTER TABLE "invites" ADD CONSTRAINT "invites_team_id_teams_id_fk" FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
102
+ ALTER TABLE "invites" ADD CONSTRAINT "invites_created_by_users_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
103
+ ALTER TABLE "memberships" ADD CONSTRAINT "memberships_team_id_teams_id_fk" FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
104
+ ALTER TABLE "memberships" ADD CONSTRAINT "memberships_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
105
+ ALTER TABLE "messages" ADD CONSTRAINT "messages_session_id_debug_sessions_id_fk" FOREIGN KEY ("session_id") REFERENCES "public"."debug_sessions"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
106
+ ALTER TABLE "messages" ADD CONSTRAINT "messages_author_id_users_id_fk" FOREIGN KEY ("author_id") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
107
+ ALTER TABLE "read_state" ADD CONSTRAINT "read_state_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
108
+ ALTER TABLE "read_state" ADD CONSTRAINT "read_state_session_id_debug_sessions_id_fk" FOREIGN KEY ("session_id") REFERENCES "public"."debug_sessions"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
109
+ ALTER TABLE "snapshots" ADD CONSTRAINT "snapshots_team_id_teams_id_fk" FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
110
+ ALTER TABLE "snapshots" ADD CONSTRAINT "snapshots_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
111
+ ALTER TABLE "teams" ADD CONSTRAINT "teams_created_by_users_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
112
+ ALTER TABLE "tokens" ADD CONSTRAINT "tokens_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
113
+ ALTER TABLE "web_sessions" ADD CONSTRAINT "web_sessions_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
114
+ CREATE INDEX "messages_session_created" ON "messages" USING btree ("session_id","created_at");--> statement-breakpoint
115
+ CREATE INDEX "snapshots_team_user_created" ON "snapshots" USING btree ("team_id","user_id","created_at");
@@ -0,0 +1 @@
1
+ ALTER TABLE "messages" ADD COLUMN "via" text;
@@ -0,0 +1 @@
1
+ ALTER TABLE "teams" ADD COLUMN "webhook_url" text;
@@ -0,0 +1 @@
1
+ ALTER TABLE "users" ADD COLUMN "password_hash" text;
@@ -0,0 +1,40 @@
1
+ CREATE TABLE "activity" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "team_id" uuid NOT NULL,
4
+ "project_id" uuid,
5
+ "user_id" uuid,
6
+ "token_id" uuid,
7
+ "action" text NOT NULL,
8
+ "detail" text,
9
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
10
+ );
11
+ --> statement-breakpoint
12
+ CREATE TABLE "projects" (
13
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
14
+ "team_id" uuid NOT NULL,
15
+ "name" text NOT NULL,
16
+ "slug" text NOT NULL,
17
+ "created_by" uuid,
18
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
19
+ );
20
+ --> statement-breakpoint
21
+ ALTER TABLE "debug_sessions" ADD COLUMN "project_id" uuid;--> statement-breakpoint
22
+ ALTER TABLE "debug_sessions" ADD COLUMN "kind" text DEFAULT 'debug' NOT NULL;--> statement-breakpoint
23
+ ALTER TABLE "messages" ADD COLUMN "token_id" uuid;--> statement-breakpoint
24
+ ALTER TABLE "snapshots" ADD COLUMN "project_id" uuid;--> statement-breakpoint
25
+ ALTER TABLE "snapshots" ADD COLUMN "token_id" uuid;--> statement-breakpoint
26
+ ALTER TABLE "teams" ADD COLUMN "plan" text DEFAULT 'free' NOT NULL;--> statement-breakpoint
27
+ ALTER TABLE "teams" ADD COLUMN "inbound_token" text;--> statement-breakpoint
28
+ ALTER TABLE "activity" ADD CONSTRAINT "activity_team_id_teams_id_fk" FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
29
+ ALTER TABLE "activity" ADD CONSTRAINT "activity_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
30
+ ALTER TABLE "activity" ADD CONSTRAINT "activity_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
31
+ ALTER TABLE "activity" ADD CONSTRAINT "activity_token_id_tokens_id_fk" FOREIGN KEY ("token_id") REFERENCES "public"."tokens"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
32
+ ALTER TABLE "projects" ADD CONSTRAINT "projects_team_id_teams_id_fk" FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
33
+ ALTER TABLE "projects" ADD CONSTRAINT "projects_created_by_users_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
34
+ CREATE INDEX "activity_team_created" ON "activity" USING btree ("team_id","created_at");--> statement-breakpoint
35
+ CREATE UNIQUE INDEX "projects_team_slug" ON "projects" USING btree ("team_id","slug");--> statement-breakpoint
36
+ ALTER TABLE "debug_sessions" ADD CONSTRAINT "debug_sessions_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
37
+ ALTER TABLE "messages" ADD CONSTRAINT "messages_token_id_tokens_id_fk" FOREIGN KEY ("token_id") REFERENCES "public"."tokens"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
38
+ ALTER TABLE "snapshots" ADD CONSTRAINT "snapshots_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
39
+ ALTER TABLE "snapshots" ADD CONSTRAINT "snapshots_token_id_tokens_id_fk" FOREIGN KEY ("token_id") REFERENCES "public"."tokens"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
40
+ ALTER TABLE "teams" ADD CONSTRAINT "teams_inbound_token_unique" UNIQUE("inbound_token");
@@ -0,0 +1,103 @@
1
+ CREATE TABLE "agent_events" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "run_id" uuid NOT NULL,
4
+ "type" text NOT NULL,
5
+ "detail" jsonb,
6
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
7
+ );
8
+ --> statement-breakpoint
9
+ CREATE TABLE "agent_installations" (
10
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
11
+ "user_id" uuid NOT NULL,
12
+ "name" text NOT NULL,
13
+ "client_type" text DEFAULT 'generic' NOT NULL,
14
+ "client_version" text,
15
+ "device_fingerprint" text NOT NULL,
16
+ "capabilities" jsonb DEFAULT '[]'::jsonb NOT NULL,
17
+ "last_seen_at" timestamp with time zone DEFAULT now() NOT NULL,
18
+ "revoked_at" timestamp with time zone,
19
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
20
+ );
21
+ --> statement-breakpoint
22
+ CREATE TABLE "agent_runs" (
23
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
24
+ "installation_id" uuid NOT NULL,
25
+ "team_id" uuid NOT NULL,
26
+ "project_id" uuid,
27
+ "task_key" text,
28
+ "intent" text,
29
+ "repo" text,
30
+ "branch" text,
31
+ "worktree" text,
32
+ "base_sha" text,
33
+ "status" text DEFAULT 'starting' NOT NULL,
34
+ "policy_hash" text,
35
+ "environment_fingerprint" text,
36
+ "started_at" timestamp with time zone DEFAULT now() NOT NULL,
37
+ "last_heartbeat_at" timestamp with time zone DEFAULT now() NOT NULL,
38
+ "ended_at" timestamp with time zone
39
+ );
40
+ --> statement-breakpoint
41
+ CREATE TABLE "environment_baselines" (
42
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
43
+ "team_id" uuid NOT NULL,
44
+ "project_id" uuid NOT NULL,
45
+ "data" jsonb NOT NULL,
46
+ "fingerprint" text NOT NULL,
47
+ "active" boolean DEFAULT true NOT NULL,
48
+ "created_by" uuid,
49
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
50
+ );
51
+ --> statement-breakpoint
52
+ CREATE TABLE "policy_bundles" (
53
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
54
+ "team_id" uuid NOT NULL,
55
+ "project_id" uuid,
56
+ "scope_key" text NOT NULL,
57
+ "version" integer NOT NULL,
58
+ "status" text DEFAULT 'active' NOT NULL,
59
+ "document" jsonb NOT NULL,
60
+ "hash" text NOT NULL,
61
+ "created_by" uuid,
62
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
63
+ );
64
+ --> statement-breakpoint
65
+ CREATE TABLE "policy_receipts" (
66
+ "run_id" uuid PRIMARY KEY NOT NULL,
67
+ "expected_hash" text NOT NULL,
68
+ "reported_hash" text,
69
+ "drift" boolean DEFAULT false NOT NULL,
70
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
71
+ );
72
+ --> statement-breakpoint
73
+ CREATE TABLE "work_claims" (
74
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
75
+ "run_id" uuid NOT NULL,
76
+ "resource_type" text NOT NULL,
77
+ "resource_key" text NOT NULL,
78
+ "access" text DEFAULT 'write' NOT NULL,
79
+ "lease_expires_at" timestamp with time zone NOT NULL,
80
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
81
+ );
82
+ --> statement-breakpoint
83
+ ALTER TABLE "agent_events" ADD CONSTRAINT "agent_events_run_id_agent_runs_id_fk" FOREIGN KEY ("run_id") REFERENCES "public"."agent_runs"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
84
+ ALTER TABLE "agent_installations" ADD CONSTRAINT "agent_installations_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
85
+ ALTER TABLE "agent_runs" ADD CONSTRAINT "agent_runs_installation_id_agent_installations_id_fk" FOREIGN KEY ("installation_id") REFERENCES "public"."agent_installations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
86
+ ALTER TABLE "agent_runs" ADD CONSTRAINT "agent_runs_team_id_teams_id_fk" FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
87
+ ALTER TABLE "agent_runs" ADD CONSTRAINT "agent_runs_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
88
+ ALTER TABLE "environment_baselines" ADD CONSTRAINT "environment_baselines_team_id_teams_id_fk" FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
89
+ ALTER TABLE "environment_baselines" ADD CONSTRAINT "environment_baselines_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
90
+ ALTER TABLE "environment_baselines" ADD CONSTRAINT "environment_baselines_created_by_users_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
91
+ ALTER TABLE "policy_bundles" ADD CONSTRAINT "policy_bundles_team_id_teams_id_fk" FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
92
+ ALTER TABLE "policy_bundles" ADD CONSTRAINT "policy_bundles_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
93
+ ALTER TABLE "policy_bundles" ADD CONSTRAINT "policy_bundles_created_by_users_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
94
+ ALTER TABLE "policy_receipts" ADD CONSTRAINT "policy_receipts_run_id_agent_runs_id_fk" FOREIGN KEY ("run_id") REFERENCES "public"."agent_runs"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
95
+ ALTER TABLE "work_claims" ADD CONSTRAINT "work_claims_run_id_agent_runs_id_fk" FOREIGN KEY ("run_id") REFERENCES "public"."agent_runs"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
96
+ CREATE INDEX "agent_events_run_created" ON "agent_events" USING btree ("run_id","created_at");--> statement-breakpoint
97
+ CREATE UNIQUE INDEX "agent_installations_user_device_name" ON "agent_installations" USING btree ("user_id","device_fingerprint","name");--> statement-breakpoint
98
+ CREATE INDEX "agent_runs_team_status_heartbeat" ON "agent_runs" USING btree ("team_id","status","last_heartbeat_at");--> statement-breakpoint
99
+ CREATE INDEX "agent_runs_installation_started" ON "agent_runs" USING btree ("installation_id","started_at");--> statement-breakpoint
100
+ CREATE INDEX "environment_baselines_project_active" ON "environment_baselines" USING btree ("project_id","active","created_at");--> statement-breakpoint
101
+ CREATE UNIQUE INDEX "policy_bundles_team_scope_version" ON "policy_bundles" USING btree ("team_id","scope_key","version");--> statement-breakpoint
102
+ CREATE UNIQUE INDEX "work_claims_run_resource" ON "work_claims" USING btree ("run_id","resource_type","resource_key","access");--> statement-breakpoint
103
+ CREATE INDEX "work_claims_lease" ON "work_claims" USING btree ("lease_expires_at");
@@ -0,0 +1,42 @@
1
+ -- One announcements channel per team: before the unique index below existed,
2
+ -- concurrent first-announces could create duplicate channels. Keep the earliest
3
+ -- channel per team, repoint messages at it, copy read markers over, then delete
4
+ -- the duplicates (cascade clears their leftover read_state rows). Every
5
+ -- statement is a no-op when there are no duplicates.
6
+ WITH keep AS (
7
+ SELECT team_id, (array_agg(id ORDER BY created_at, id))[1] AS keep_id
8
+ FROM debug_sessions WHERE kind = 'announcements' GROUP BY team_id
9
+ ), dup AS (
10
+ SELECT s.id, keep.keep_id
11
+ FROM debug_sessions s
12
+ JOIN keep ON keep.team_id = s.team_id
13
+ WHERE s.kind = 'announcements' AND s.id <> keep.keep_id
14
+ )
15
+ UPDATE messages m SET session_id = dup.keep_id FROM dup WHERE m.session_id = dup.id;
16
+ --> statement-breakpoint
17
+ WITH keep AS (
18
+ SELECT team_id, (array_agg(id ORDER BY created_at, id))[1] AS keep_id
19
+ FROM debug_sessions WHERE kind = 'announcements' GROUP BY team_id
20
+ ), dup AS (
21
+ SELECT s.id, keep.keep_id
22
+ FROM debug_sessions s
23
+ JOIN keep ON keep.team_id = s.team_id
24
+ WHERE s.kind = 'announcements' AND s.id <> keep.keep_id
25
+ )
26
+ INSERT INTO read_state (user_id, session_id, last_read_at)
27
+ SELECT rs.user_id, dup.keep_id, max(rs.last_read_at)
28
+ FROM read_state rs
29
+ JOIN dup ON dup.id = rs.session_id
30
+ GROUP BY rs.user_id, dup.keep_id
31
+ ON CONFLICT (user_id, session_id) DO UPDATE
32
+ SET last_read_at = GREATEST(read_state.last_read_at, excluded.last_read_at);
33
+ --> statement-breakpoint
34
+ WITH keep AS (
35
+ SELECT team_id, (array_agg(id ORDER BY created_at, id))[1] AS keep_id
36
+ FROM debug_sessions WHERE kind = 'announcements' GROUP BY team_id
37
+ )
38
+ DELETE FROM debug_sessions s
39
+ USING keep
40
+ WHERE s.kind = 'announcements' AND s.team_id = keep.team_id AND s.id <> keep.keep_id;
41
+ --> statement-breakpoint
42
+ CREATE UNIQUE INDEX "debug_sessions_team_announcements" ON "debug_sessions" USING btree ("team_id") WHERE kind = 'announcements';
@@ -0,0 +1,12 @@
1
+ CREATE TABLE "crm_contacts" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "name" text NOT NULL,
4
+ "org" text,
5
+ "contact" text,
6
+ "status" text DEFAULT 'lead' NOT NULL,
7
+ "source" text,
8
+ "notes" text,
9
+ "next_action_at" timestamp with time zone,
10
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
11
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL
12
+ );
@@ -0,0 +1,9 @@
1
+ ALTER TABLE "snapshots" ADD COLUMN "device_label" text DEFAULT 'default' NOT NULL;--> statement-breakpoint
2
+ -- Backfill: rows pushed before the personal-fleet change keep a recognizable
3
+ -- device slot by adopting the name of the token that pushed them ("one token per
4
+ -- machine" is the documented convention). Mirrors normalizeDeviceLabel() in
5
+ -- src/lib/devices.ts; anything unusable stays 'default'.
6
+ UPDATE "snapshots" SET "device_label" = coalesce(nullif(btrim(left(regexp_replace(lower(btrim("tokens"."name")), '[^a-z0-9._-]+', '-', 'g'), 40), '-._'), ''), 'default') FROM "tokens" WHERE "snapshots"."token_id" = "tokens"."id";--> statement-breakpoint
7
+ ALTER TABLE "snapshots" ADD COLUMN "device_id" uuid;--> statement-breakpoint
8
+ ALTER TABLE "snapshots" ADD CONSTRAINT "snapshots_device_id_agent_installations_id_fk" FOREIGN KEY ("device_id") REFERENCES "public"."agent_installations"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
9
+ CREATE INDEX "snapshots_team_user_device_created" ON "snapshots" USING btree ("team_id","user_id","device_label","created_at");
@@ -0,0 +1,15 @@
1
+ CREATE TABLE "error_events" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "at" timestamp with time zone DEFAULT now() NOT NULL,
4
+ "kind" text DEFAULT 'http' NOT NULL,
5
+ "method" text,
6
+ "path" text,
7
+ "status" integer,
8
+ "message" text NOT NULL,
9
+ "stack" text,
10
+ "user_id" text,
11
+ "team_slug" text,
12
+ "request_id" text
13
+ );
14
+ --> statement-breakpoint
15
+ CREATE INDEX "error_events_at" ON "error_events" USING btree ("at" DESC NULLS LAST);
@@ -0,0 +1,26 @@
1
+ CREATE TABLE "auth_codes" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "user_id" uuid NOT NULL,
4
+ "purpose" text NOT NULL,
5
+ "code_hash" text NOT NULL,
6
+ "expires_at" timestamp with time zone NOT NULL,
7
+ "attempts" integer DEFAULT 0 NOT NULL,
8
+ "consumed_at" timestamp with time zone,
9
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
10
+ );
11
+ --> statement-breakpoint
12
+ ALTER TABLE "auth_codes" ADD CONSTRAINT "auth_codes_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
13
+ CREATE INDEX "auth_codes_user_purpose" ON "auth_codes" USING btree ("user_id","purpose");--> statement-breakpoint
14
+ -- Email becomes the login identity: normalize what is already stored so the
15
+ -- unique index below sees one canonical form (lib/email.normalizeEmail).
16
+ UPDATE "users" SET "email" = lower(btrim("email")) WHERE "email" IS NOT NULL;--> statement-breakpoint
17
+ -- Keep the oldest holder of a duplicate address and clear the others, so the
18
+ -- index applies on any existing database. A cleared account signs in again once
19
+ -- an operator sets its email in /admin/users.
20
+ UPDATE "users" SET "email" = NULL WHERE "id" IN (
21
+ SELECT "id" FROM (
22
+ SELECT "id", row_number() OVER (PARTITION BY "email" ORDER BY "created_at", "id") AS rn
23
+ FROM "users" WHERE "email" IS NOT NULL
24
+ ) dupes WHERE dupes.rn > 1
25
+ );--> statement-breakpoint
26
+ CREATE UNIQUE INDEX "users_email_unique" ON "users" USING btree ("email") WHERE email is not null;
@@ -0,0 +1,20 @@
1
+ CREATE TABLE "environment_checks" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "team_id" uuid NOT NULL,
4
+ "project_id" uuid NOT NULL,
5
+ "user_id" uuid,
6
+ "run_id" uuid,
7
+ "status" text NOT NULL,
8
+ "fingerprint" text NOT NULL,
9
+ "baseline_fingerprint" text,
10
+ "summary" text,
11
+ "details" jsonb,
12
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
13
+ );
14
+ --> statement-breakpoint
15
+ ALTER TABLE "environment_checks" ADD CONSTRAINT "environment_checks_team_id_teams_id_fk" FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
16
+ ALTER TABLE "environment_checks" ADD CONSTRAINT "environment_checks_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
17
+ ALTER TABLE "environment_checks" ADD CONSTRAINT "environment_checks_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
18
+ ALTER TABLE "environment_checks" ADD CONSTRAINT "environment_checks_run_id_agent_runs_id_fk" FOREIGN KEY ("run_id") REFERENCES "public"."agent_runs"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
19
+ CREATE INDEX "environment_checks_team_created" ON "environment_checks" USING btree ("team_id","created_at");--> statement-breakpoint
20
+ CREATE INDEX "environment_checks_project_created" ON "environment_checks" USING btree ("project_id","created_at");
@@ -0,0 +1,31 @@
1
+ CREATE TABLE "notification_prefs" (
2
+ "user_id" uuid PRIMARY KEY NOT NULL,
3
+ "session_reply" boolean DEFAULT true NOT NULL,
4
+ "session_resolved" boolean DEFAULT true NOT NULL,
5
+ "team_joined" boolean DEFAULT true NOT NULL,
6
+ "announcements" boolean DEFAULT false NOT NULL,
7
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL
8
+ );
9
+ --> statement-breakpoint
10
+ CREATE TABLE "notification_queue" (
11
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
12
+ "user_id" uuid NOT NULL,
13
+ "kind" text NOT NULL,
14
+ "coalesce_key" text NOT NULL,
15
+ "team_id" uuid,
16
+ "session_id" uuid,
17
+ "since_at" timestamp with time zone DEFAULT now() NOT NULL,
18
+ "not_before" timestamp with time zone NOT NULL,
19
+ "status" text DEFAULT 'pending' NOT NULL,
20
+ "reason" text,
21
+ "sent_at" timestamp with time zone,
22
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
23
+ );
24
+ --> statement-breakpoint
25
+ ALTER TABLE "notification_prefs" ADD CONSTRAINT "notification_prefs_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
26
+ ALTER TABLE "notification_queue" ADD CONSTRAINT "notification_queue_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
27
+ ALTER TABLE "notification_queue" ADD CONSTRAINT "notification_queue_team_id_teams_id_fk" FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
28
+ ALTER TABLE "notification_queue" ADD CONSTRAINT "notification_queue_session_id_debug_sessions_id_fk" FOREIGN KEY ("session_id") REFERENCES "public"."debug_sessions"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
29
+ CREATE UNIQUE INDEX "notification_queue_pending" ON "notification_queue" USING btree ("user_id","coalesce_key") WHERE status = 'pending';--> statement-breakpoint
30
+ CREATE INDEX "notification_queue_due" ON "notification_queue" USING btree ("status","not_before");--> statement-breakpoint
31
+ CREATE INDEX "notification_queue_user_sent" ON "notification_queue" USING btree ("user_id","sent_at");
@@ -0,0 +1,7 @@
1
+ CREATE TABLE "rate_counters" (
2
+ "key" text PRIMARY KEY NOT NULL,
3
+ "count" integer DEFAULT 0 NOT NULL,
4
+ "expires_at" timestamp with time zone NOT NULL
5
+ );
6
+ --> statement-breakpoint
7
+ CREATE INDEX "rate_counters_expires" ON "rate_counters" USING btree ("expires_at");
@@ -0,0 +1,22 @@
1
+ CREATE TABLE "team_integrations" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "team_id" uuid NOT NULL,
4
+ "provider" text DEFAULT 'github' NOT NULL,
5
+ "repo" text NOT NULL,
6
+ "token" text NOT NULL,
7
+ "comment_on_finish" boolean DEFAULT true NOT NULL,
8
+ "created_by" uuid,
9
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
10
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL
11
+ );
12
+ --> statement-breakpoint
13
+ ALTER TABLE "agent_installations" ADD COLUMN "role" text;--> statement-breakpoint
14
+ ALTER TABLE "agent_runs" ADD COLUMN "attempt_group" text;--> statement-breakpoint
15
+ ALTER TABLE "agent_runs" ADD COLUMN "quota_pct" integer;--> statement-breakpoint
16
+ ALTER TABLE "agent_runs" ADD COLUMN "quota_state" text;--> statement-breakpoint
17
+ ALTER TABLE "agent_runs" ADD COLUMN "quota_resets_at" timestamp with time zone;--> statement-breakpoint
18
+ ALTER TABLE "agent_runs" ADD COLUMN "quota_label" text;--> statement-breakpoint
19
+ ALTER TABLE "notification_prefs" ADD COLUMN "webhook_url" text;--> statement-breakpoint
20
+ ALTER TABLE "team_integrations" ADD CONSTRAINT "team_integrations_team_id_teams_id_fk" FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
21
+ ALTER TABLE "team_integrations" ADD CONSTRAINT "team_integrations_created_by_users_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
22
+ CREATE UNIQUE INDEX "team_integrations_team_provider" ON "team_integrations" USING btree ("team_id","provider");
@@ -0,0 +1,8 @@
1
+ ALTER TABLE "agent_runs" ADD COLUMN "quota_source" text;--> statement-breakpoint
2
+ ALTER TABLE "messages" ADD COLUMN "payload" jsonb;--> statement-breakpoint
3
+ -- A receipt with no reported hash used to be written as drift, because "drifted
4
+ -- until the agent answers" was the only honest reading while no MCP tool could
5
+ -- answer. update_run can answer now, so drift goes back to meaning a real
6
+ -- deviation and unconfirmed is its own, weaker state. Old rows are recomputed
7
+ -- so the governance page is not still counting silence as breakage.
8
+ UPDATE "policy_receipts" SET "drift" = false WHERE "reported_hash" IS NULL;
@@ -0,0 +1,8 @@
1
+ -- The plan ladder grew from two rungs to four, and the middle one was renamed.
2
+ --
3
+ -- `pro` was the only paid id the code ever knew, and the pricing document had
4
+ -- already settled on `team` for it — a name that says who it is for rather than
5
+ -- that it is the expensive one. Renaming it in the enum without renaming it in
6
+ -- the data would silently drop every paying team back to free defaults, because
7
+ -- an unknown plan id resolves to `free`.
8
+ UPDATE "teams" SET "plan" = 'team' WHERE "plan" = 'pro';
@@ -0,0 +1,21 @@
1
+ CREATE TABLE "saving_confirmations" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "team_id" uuid NOT NULL,
4
+ "kind" text NOT NULL,
5
+ "ref_id" uuid NOT NULL,
6
+ "run_id" uuid,
7
+ "confirmed_by" uuid,
8
+ "helpful" boolean NOT NULL,
9
+ "changed_behaviour" boolean DEFAULT false NOT NULL,
10
+ "minutes_saved" integer,
11
+ "spend_stopped" boolean DEFAULT false NOT NULL,
12
+ "note" text,
13
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
14
+ );
15
+ --> statement-breakpoint
16
+ ALTER TABLE "teams" ADD COLUMN "hourly_cost_cents" integer;--> statement-breakpoint
17
+ ALTER TABLE "saving_confirmations" ADD CONSTRAINT "saving_confirmations_team_id_teams_id_fk" FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
18
+ ALTER TABLE "saving_confirmations" ADD CONSTRAINT "saving_confirmations_run_id_agent_runs_id_fk" FOREIGN KEY ("run_id") REFERENCES "public"."agent_runs"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
19
+ ALTER TABLE "saving_confirmations" ADD CONSTRAINT "saving_confirmations_confirmed_by_users_id_fk" FOREIGN KEY ("confirmed_by") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
20
+ CREATE UNIQUE INDEX "saving_confirmations_ref_idx" ON "saving_confirmations" USING btree ("kind","ref_id");--> statement-breakpoint
21
+ CREATE INDEX "saving_confirmations_team_idx" ON "saving_confirmations" USING btree ("team_id","created_at");
@@ -0,0 +1,20 @@
1
+ CREATE TABLE "delivery_flows" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "team_id" uuid NOT NULL,
4
+ "project_id" uuid,
5
+ "name" text NOT NULL,
6
+ "template_key" text NOT NULL,
7
+ "provider" text DEFAULT 'azure-devops' NOT NULL,
8
+ "document" jsonb NOT NULL,
9
+ "status" text DEFAULT 'active' NOT NULL,
10
+ "version" integer DEFAULT 1 NOT NULL,
11
+ "created_by" uuid,
12
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
13
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL
14
+ );
15
+ --> statement-breakpoint
16
+ ALTER TABLE "team_integrations" ADD COLUMN "config" jsonb;--> statement-breakpoint
17
+ ALTER TABLE "delivery_flows" ADD CONSTRAINT "delivery_flows_team_id_teams_id_fk" FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
18
+ ALTER TABLE "delivery_flows" ADD CONSTRAINT "delivery_flows_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
19
+ ALTER TABLE "delivery_flows" ADD CONSTRAINT "delivery_flows_created_by_users_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
20
+ CREATE INDEX "delivery_flows_team" ON "delivery_flows" USING btree ("team_id","status");
@@ -0,0 +1,6 @@
1
+ ALTER TABLE "agent_runs" ADD COLUMN "pr_number" integer;--> statement-breakpoint
2
+ ALTER TABLE "agent_runs" ADD COLUMN "pr_url" text;--> statement-breakpoint
3
+ ALTER TABLE "agent_runs" ADD COLUMN "pr_state" text;--> statement-breakpoint
4
+ ALTER TABLE "agent_runs" ADD COLUMN "ci_state" text;--> statement-breakpoint
5
+ ALTER TABLE "agent_runs" ADD COLUMN "cost_cents" integer;--> statement-breakpoint
6
+ ALTER TABLE "agent_runs" ADD COLUMN "cost_source" text;