bopodev-db 0.1.12 → 0.1.14

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bopodev-db",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
package/src/bootstrap.ts CHANGED
@@ -181,6 +181,21 @@ export async function bootstrapDatabase(dbPath?: string) {
181
181
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
182
182
  );
183
183
  `);
184
+ await db.execute(sql`
185
+ CREATE TABLE IF NOT EXISTS issue_attachments (
186
+ id TEXT PRIMARY KEY,
187
+ company_id TEXT NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
188
+ issue_id TEXT NOT NULL REFERENCES issues(id) ON DELETE CASCADE,
189
+ project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
190
+ file_name TEXT NOT NULL,
191
+ mime_type TEXT,
192
+ file_size_bytes INTEGER NOT NULL,
193
+ relative_path TEXT NOT NULL,
194
+ uploaded_by_actor_type TEXT NOT NULL DEFAULT 'human',
195
+ uploaded_by_actor_id TEXT,
196
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
197
+ );
198
+ `);
184
199
  await db.execute(sql`
185
200
  CREATE TABLE IF NOT EXISTS activity_logs (
186
201
  id TEXT PRIMARY KEY,
@@ -204,6 +219,34 @@ export async function bootstrapDatabase(dbPath?: string) {
204
219
  message TEXT
205
220
  );
206
221
  `);
222
+ await db.execute(sql`
223
+ CREATE TABLE IF NOT EXISTS heartbeat_run_messages (
224
+ id TEXT PRIMARY KEY,
225
+ company_id TEXT NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
226
+ run_id TEXT NOT NULL REFERENCES heartbeat_runs(id) ON DELETE CASCADE,
227
+ sequence INTEGER NOT NULL,
228
+ kind TEXT NOT NULL,
229
+ label TEXT,
230
+ text TEXT,
231
+ payload_json TEXT,
232
+ signal_level TEXT,
233
+ group_key TEXT,
234
+ source TEXT,
235
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
236
+ );
237
+ `);
238
+ await db.execute(sql`
239
+ ALTER TABLE heartbeat_run_messages
240
+ ADD COLUMN IF NOT EXISTS signal_level TEXT;
241
+ `);
242
+ await db.execute(sql`
243
+ ALTER TABLE heartbeat_run_messages
244
+ ADD COLUMN IF NOT EXISTS group_key TEXT;
245
+ `);
246
+ await db.execute(sql`
247
+ ALTER TABLE heartbeat_run_messages
248
+ ADD COLUMN IF NOT EXISTS source TEXT;
249
+ `);
207
250
  await db.execute(sql`
208
251
  CREATE TABLE IF NOT EXISTS approval_requests (
209
252
  id TEXT PRIMARY KEY,
@@ -236,12 +279,46 @@ export async function bootstrapDatabase(dbPath?: string) {
236
279
  issue_id TEXT REFERENCES issues(id) ON DELETE SET NULL,
237
280
  agent_id TEXT REFERENCES agents(id) ON DELETE SET NULL,
238
281
  provider_type TEXT NOT NULL,
282
+ runtime_model_id TEXT,
283
+ pricing_provider_type TEXT,
284
+ pricing_model_id TEXT,
285
+ pricing_source TEXT,
239
286
  token_input INTEGER NOT NULL DEFAULT 0,
240
287
  token_output INTEGER NOT NULL DEFAULT 0,
241
288
  usd_cost NUMERIC(12, 6) NOT NULL DEFAULT 0,
242
289
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
243
290
  );
244
291
  `);
292
+ await db.execute(sql`
293
+ ALTER TABLE cost_ledger
294
+ ADD COLUMN IF NOT EXISTS runtime_model_id TEXT;
295
+ `);
296
+ await db.execute(sql`
297
+ ALTER TABLE cost_ledger
298
+ ADD COLUMN IF NOT EXISTS pricing_provider_type TEXT;
299
+ `);
300
+ await db.execute(sql`
301
+ ALTER TABLE cost_ledger
302
+ ADD COLUMN IF NOT EXISTS pricing_model_id TEXT;
303
+ `);
304
+ await db.execute(sql`
305
+ ALTER TABLE cost_ledger
306
+ ADD COLUMN IF NOT EXISTS pricing_source TEXT;
307
+ `);
308
+ await db.execute(sql`
309
+ CREATE TABLE IF NOT EXISTS model_pricing (
310
+ company_id TEXT NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
311
+ provider_type TEXT NOT NULL,
312
+ model_id TEXT NOT NULL,
313
+ display_name TEXT,
314
+ input_usd_per_1m NUMERIC(12, 6) NOT NULL DEFAULT 0,
315
+ output_usd_per_1m NUMERIC(12, 6) NOT NULL DEFAULT 0,
316
+ currency TEXT NOT NULL DEFAULT 'USD',
317
+ updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
318
+ updated_by TEXT,
319
+ PRIMARY KEY (company_id, provider_type, model_id)
320
+ );
321
+ `);
245
322
  await db.execute(sql`
246
323
  CREATE TABLE IF NOT EXISTS audit_events (
247
324
  id TEXT PRIMARY KEY,
@@ -256,6 +333,48 @@ export async function bootstrapDatabase(dbPath?: string) {
256
333
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
257
334
  );
258
335
  `);
336
+ await db.execute(sql`
337
+ CREATE TABLE IF NOT EXISTS plugins (
338
+ id TEXT PRIMARY KEY,
339
+ name TEXT NOT NULL,
340
+ version TEXT NOT NULL,
341
+ kind TEXT NOT NULL,
342
+ runtime_type TEXT NOT NULL,
343
+ runtime_entrypoint TEXT NOT NULL,
344
+ hooks_json TEXT NOT NULL DEFAULT '[]',
345
+ capabilities_json TEXT NOT NULL DEFAULT '[]',
346
+ manifest_json TEXT NOT NULL DEFAULT '{}',
347
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
348
+ updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
349
+ );
350
+ `);
351
+ await db.execute(sql`
352
+ CREATE TABLE IF NOT EXISTS plugin_configs (
353
+ company_id TEXT NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
354
+ plugin_id TEXT NOT NULL REFERENCES plugins(id) ON DELETE CASCADE,
355
+ enabled BOOLEAN NOT NULL DEFAULT false,
356
+ priority INTEGER NOT NULL DEFAULT 100,
357
+ config_json TEXT NOT NULL DEFAULT '{}',
358
+ granted_capabilities_json TEXT NOT NULL DEFAULT '[]',
359
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
360
+ updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
361
+ PRIMARY KEY (company_id, plugin_id)
362
+ );
363
+ `);
364
+ await db.execute(sql`
365
+ CREATE TABLE IF NOT EXISTS plugin_runs (
366
+ id TEXT PRIMARY KEY,
367
+ company_id TEXT NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
368
+ run_id TEXT REFERENCES heartbeat_runs(id) ON DELETE CASCADE,
369
+ plugin_id TEXT NOT NULL REFERENCES plugins(id) ON DELETE CASCADE,
370
+ hook TEXT NOT NULL,
371
+ status TEXT NOT NULL,
372
+ duration_ms INTEGER NOT NULL DEFAULT 0,
373
+ error TEXT,
374
+ diagnostics_json TEXT NOT NULL DEFAULT '{}',
375
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
376
+ );
377
+ `);
259
378
  await db.execute(sql`
260
379
  CREATE TABLE IF NOT EXISTS agent_issue_labels (
261
380
  company_id TEXT NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
@@ -268,6 +387,14 @@ export async function bootstrapDatabase(dbPath?: string) {
268
387
  CREATE INDEX IF NOT EXISTS idx_issues_company_status
269
388
  ON issues (company_id, status, updated_at);
270
389
  `);
390
+ await db.execute(sql`
391
+ CREATE INDEX IF NOT EXISTS idx_issue_attachments_company_issue
392
+ ON issue_attachments (company_id, issue_id, created_at DESC);
393
+ `);
394
+ await db.execute(sql`
395
+ CREATE INDEX IF NOT EXISTS idx_issue_attachments_company_project
396
+ ON issue_attachments (company_id, project_id, created_at DESC);
397
+ `);
271
398
  await db.execute(sql`
272
399
  CREATE INDEX IF NOT EXISTS idx_audit_events_company_created
273
400
  ON audit_events (company_id, created_at DESC);
@@ -281,10 +408,26 @@ export async function bootstrapDatabase(dbPath?: string) {
281
408
  ON heartbeat_runs (company_id, agent_id)
282
409
  WHERE status = 'started';
283
410
  `);
411
+ await db.execute(sql`
412
+ CREATE INDEX IF NOT EXISTS idx_heartbeat_run_messages_company_run_sequence
413
+ ON heartbeat_run_messages (company_id, run_id, sequence ASC);
414
+ `);
415
+ await db.execute(sql`
416
+ CREATE INDEX IF NOT EXISTS idx_heartbeat_run_messages_company_created
417
+ ON heartbeat_run_messages (company_id, created_at DESC);
418
+ `);
284
419
  await db.execute(sql`
285
420
  CREATE INDEX IF NOT EXISTS idx_approval_inbox_states_company_actor_updated
286
421
  ON approval_inbox_states (company_id, actor_id, updated_at DESC);
287
422
  `);
423
+ await db.execute(sql`
424
+ CREATE INDEX IF NOT EXISTS idx_plugin_configs_company_enabled_priority
425
+ ON plugin_configs (company_id, enabled, priority ASC, plugin_id ASC);
426
+ `);
427
+ await db.execute(sql`
428
+ CREATE INDEX IF NOT EXISTS idx_plugin_runs_company_created
429
+ ON plugin_runs (company_id, created_at DESC);
430
+ `);
288
431
 
289
432
  return { db, client };
290
433
  }