bopodev-db 0.1.1

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.
package/src/schema.ts ADDED
@@ -0,0 +1,226 @@
1
+ import { sql } from "drizzle-orm";
2
+ import {
3
+ boolean,
4
+ integer,
5
+ numeric,
6
+ pgTable,
7
+ primaryKey,
8
+ text,
9
+ timestamp
10
+ } from "drizzle-orm/pg-core";
11
+
12
+ export const companies = pgTable("companies", {
13
+ id: text("id").primaryKey(),
14
+ name: text("name").notNull(),
15
+ mission: text("mission"),
16
+ createdAt: timestamp("created_at", { mode: "date" }).defaultNow().notNull()
17
+ });
18
+
19
+ export const projects = pgTable("projects", {
20
+ id: text("id").primaryKey(),
21
+ companyId: text("company_id")
22
+ .notNull()
23
+ .references(() => companies.id, { onDelete: "cascade" }),
24
+ name: text("name").notNull(),
25
+ description: text("description"),
26
+ status: text("status").notNull().default("planned"),
27
+ plannedStartAt: timestamp("planned_start_at", { mode: "date" }),
28
+ workspaceLocalPath: text("workspace_local_path"),
29
+ workspaceGithubRepo: text("workspace_github_repo"),
30
+ createdAt: timestamp("created_at", { mode: "date" }).defaultNow().notNull()
31
+ });
32
+
33
+ export const goals = pgTable("goals", {
34
+ id: text("id").primaryKey(),
35
+ companyId: text("company_id")
36
+ .notNull()
37
+ .references(() => companies.id, { onDelete: "cascade" }),
38
+ projectId: text("project_id").references(() => projects.id, { onDelete: "set null" }),
39
+ parentGoalId: text("parent_goal_id"),
40
+ level: text("level").notNull(),
41
+ title: text("title").notNull(),
42
+ description: text("description"),
43
+ status: text("status").notNull().default("draft"),
44
+ createdAt: timestamp("created_at", { mode: "date" }).defaultNow().notNull(),
45
+ updatedAt: timestamp("updated_at", { mode: "date" }).defaultNow().notNull()
46
+ });
47
+
48
+ export const agents = pgTable("agents", {
49
+ id: text("id").primaryKey(),
50
+ companyId: text("company_id")
51
+ .notNull()
52
+ .references(() => companies.id, { onDelete: "cascade" }),
53
+ managerAgentId: text("manager_agent_id"),
54
+ role: text("role").notNull(),
55
+ name: text("name").notNull(),
56
+ providerType: text("provider_type").notNull(),
57
+ status: text("status").notNull().default("idle"),
58
+ heartbeatCron: text("heartbeat_cron").notNull(),
59
+ monthlyBudgetUsd: numeric("monthly_budget_usd", { precision: 12, scale: 4 })
60
+ .notNull()
61
+ .default("0"),
62
+ usedBudgetUsd: numeric("used_budget_usd", { precision: 12, scale: 4 })
63
+ .notNull()
64
+ .default("0"),
65
+ tokenUsage: integer("token_usage").notNull().default(0),
66
+ canHireAgents: boolean("can_hire_agents").notNull().default(false),
67
+ stateBlob: text("state_blob").notNull().default("{}"),
68
+ createdAt: timestamp("created_at", { mode: "date" }).defaultNow().notNull(),
69
+ updatedAt: timestamp("updated_at", { mode: "date" }).defaultNow().notNull()
70
+ });
71
+
72
+ export const issues = pgTable("issues", {
73
+ id: text("id").primaryKey(),
74
+ companyId: text("company_id")
75
+ .notNull()
76
+ .references(() => companies.id, { onDelete: "cascade" }),
77
+ projectId: text("project_id")
78
+ .notNull()
79
+ .references(() => projects.id, { onDelete: "cascade" }),
80
+ parentIssueId: text("parent_issue_id"),
81
+ title: text("title").notNull(),
82
+ body: text("body"),
83
+ status: text("status").notNull().default("todo"),
84
+ priority: text("priority").notNull().default("none"),
85
+ assigneeAgentId: text("assignee_agent_id"),
86
+ labelsJson: text("labels_json").notNull().default("[]"),
87
+ tagsJson: text("tags_json").notNull().default("[]"),
88
+ isClaimed: boolean("is_claimed").notNull().default(false),
89
+ claimedByHeartbeatRunId: text("claimed_by_heartbeat_run_id"),
90
+ createdAt: timestamp("created_at", { mode: "date" }).defaultNow().notNull(),
91
+ updatedAt: timestamp("updated_at", { mode: "date" }).defaultNow().notNull()
92
+ });
93
+
94
+ export const issueComments = pgTable("issue_comments", {
95
+ id: text("id").primaryKey(),
96
+ issueId: text("issue_id")
97
+ .notNull()
98
+ .references(() => issues.id, { onDelete: "cascade" }),
99
+ companyId: text("company_id")
100
+ .notNull()
101
+ .references(() => companies.id, { onDelete: "cascade" }),
102
+ authorType: text("author_type").notNull(),
103
+ authorId: text("author_id"),
104
+ body: text("body").notNull(),
105
+ createdAt: timestamp("created_at", { mode: "date" }).defaultNow().notNull()
106
+ });
107
+
108
+ export const activityLogs = pgTable("activity_logs", {
109
+ id: text("id").primaryKey(),
110
+ companyId: text("company_id")
111
+ .notNull()
112
+ .references(() => companies.id, { onDelete: "cascade" }),
113
+ issueId: text("issue_id").references(() => issues.id, { onDelete: "set null" }),
114
+ actorType: text("actor_type").notNull(),
115
+ actorId: text("actor_id"),
116
+ eventType: text("event_type").notNull(),
117
+ payloadJson: text("payload_json").notNull().default("{}"),
118
+ createdAt: timestamp("created_at", { mode: "date" }).defaultNow().notNull()
119
+ });
120
+
121
+ export const heartbeatRuns = pgTable("heartbeat_runs", {
122
+ id: text("id").primaryKey(),
123
+ companyId: text("company_id")
124
+ .notNull()
125
+ .references(() => companies.id, { onDelete: "cascade" }),
126
+ agentId: text("agent_id")
127
+ .notNull()
128
+ .references(() => agents.id, { onDelete: "cascade" }),
129
+ status: text("status").notNull().default("started"),
130
+ startedAt: timestamp("started_at", { mode: "date" }).defaultNow().notNull(),
131
+ finishedAt: timestamp("finished_at", { mode: "date" }),
132
+ message: text("message")
133
+ });
134
+
135
+ export const approvalRequests = pgTable("approval_requests", {
136
+ id: text("id").primaryKey(),
137
+ companyId: text("company_id")
138
+ .notNull()
139
+ .references(() => companies.id, { onDelete: "cascade" }),
140
+ requestedByAgentId: text("requested_by_agent_id"),
141
+ action: text("action").notNull(),
142
+ payloadJson: text("payload_json").notNull().default("{}"),
143
+ status: text("status").notNull().default("pending"),
144
+ createdAt: timestamp("created_at", { mode: "date" }).defaultNow().notNull(),
145
+ resolvedAt: timestamp("resolved_at", { mode: "date" })
146
+ });
147
+
148
+ export const approvalInboxStates = pgTable(
149
+ "approval_inbox_states",
150
+ {
151
+ companyId: text("company_id")
152
+ .notNull()
153
+ .references(() => companies.id, { onDelete: "cascade" }),
154
+ actorId: text("actor_id").notNull(),
155
+ approvalId: text("approval_id")
156
+ .notNull()
157
+ .references(() => approvalRequests.id, { onDelete: "cascade" }),
158
+ seenAt: timestamp("seen_at", { mode: "date" }),
159
+ dismissedAt: timestamp("dismissed_at", { mode: "date" }),
160
+ createdAt: timestamp("created_at", { mode: "date" }).defaultNow().notNull(),
161
+ updatedAt: timestamp("updated_at", { mode: "date" }).defaultNow().notNull()
162
+ },
163
+ (table) => [primaryKey({ columns: [table.companyId, table.actorId, table.approvalId] })]
164
+ );
165
+
166
+ export const costLedger = pgTable("cost_ledger", {
167
+ id: text("id").primaryKey(),
168
+ companyId: text("company_id")
169
+ .notNull()
170
+ .references(() => companies.id, { onDelete: "cascade" }),
171
+ projectId: text("project_id").references(() => projects.id, { onDelete: "set null" }),
172
+ issueId: text("issue_id").references(() => issues.id, { onDelete: "set null" }),
173
+ agentId: text("agent_id").references(() => agents.id, { onDelete: "set null" }),
174
+ providerType: text("provider_type").notNull(),
175
+ tokenInput: integer("token_input").notNull().default(0),
176
+ tokenOutput: integer("token_output").notNull().default(0),
177
+ usdCost: numeric("usd_cost", { precision: 12, scale: 6 }).notNull().default("0"),
178
+ createdAt: timestamp("created_at", { mode: "date" }).defaultNow().notNull()
179
+ });
180
+
181
+ export const auditEvents = pgTable("audit_events", {
182
+ id: text("id").primaryKey(),
183
+ companyId: text("company_id")
184
+ .notNull()
185
+ .references(() => companies.id, { onDelete: "cascade" }),
186
+ actorType: text("actor_type").notNull(),
187
+ actorId: text("actor_id"),
188
+ eventType: text("event_type").notNull(),
189
+ entityType: text("entity_type").notNull(),
190
+ entityId: text("entity_id").notNull(),
191
+ correlationId: text("correlation_id"),
192
+ payloadJson: text("payload_json").notNull().default("{}"),
193
+ createdAt: timestamp("created_at", { mode: "date" }).defaultNow().notNull()
194
+ });
195
+
196
+ export const agentIssueLabels = pgTable(
197
+ "agent_issue_labels",
198
+ {
199
+ companyId: text("company_id")
200
+ .notNull()
201
+ .references(() => companies.id, { onDelete: "cascade" }),
202
+ issueId: text("issue_id")
203
+ .notNull()
204
+ .references(() => issues.id, { onDelete: "cascade" }),
205
+ label: text("label").notNull()
206
+ },
207
+ (table) => [primaryKey({ columns: [table.companyId, table.issueId, table.label] })]
208
+ );
209
+
210
+ export const schema = {
211
+ companies,
212
+ projects,
213
+ goals,
214
+ agents,
215
+ issues,
216
+ issueComments,
217
+ activityLogs,
218
+ heartbeatRuns,
219
+ approvalRequests,
220
+ approvalInboxStates,
221
+ costLedger,
222
+ auditEvents,
223
+ agentIssueLabels
224
+ };
225
+
226
+ export const touchUpdatedAtSql = sql`CURRENT_TIMESTAMP`;
package/tsconfig.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "declaration": true,
6
+ "emitDeclarationOnly": true
7
+ },
8
+ "include": ["src"]
9
+ }