@critical-path/core 0.28.0 → 0.30.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 (52) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +14 -0
  3. package/dist/domain/events.d.ts +8 -2
  4. package/dist/domain/events.d.ts.map +1 -1
  5. package/dist/domain/events.js +1 -0
  6. package/dist/domain/events.js.map +1 -1
  7. package/dist/engine/cascade.test.d.ts +2 -0
  8. package/dist/engine/cascade.test.d.ts.map +1 -0
  9. package/dist/engine/cascade.test.js +99 -0
  10. package/dist/engine/cascade.test.js.map +1 -0
  11. package/dist/engine/index.d.ts +25 -2
  12. package/dist/engine/index.d.ts.map +1 -1
  13. package/dist/engine/index.js +117 -6
  14. package/dist/engine/index.js.map +1 -1
  15. package/dist/schemas/index.d.ts +81 -28
  16. package/dist/schemas/index.d.ts.map +1 -1
  17. package/dist/schemas/index.js +26 -0
  18. package/dist/schemas/index.js.map +1 -1
  19. package/dist/store/firebase.d.ts +12 -0
  20. package/dist/store/firebase.d.ts.map +1 -1
  21. package/dist/store/firebase.js +40 -8
  22. package/dist/store/firebase.js.map +1 -1
  23. package/dist/store/index.d.ts +15 -0
  24. package/dist/store/index.d.ts.map +1 -1
  25. package/dist/store/index.js +19 -0
  26. package/dist/store/index.js.map +1 -1
  27. package/dist/store/query.d.ts +50 -0
  28. package/dist/store/query.d.ts.map +1 -0
  29. package/dist/store/query.js +79 -0
  30. package/dist/store/query.js.map +1 -0
  31. package/dist/store/query.test.d.ts +2 -0
  32. package/dist/store/query.test.d.ts.map +1 -0
  33. package/dist/store/query.test.js +89 -0
  34. package/dist/store/query.test.js.map +1 -0
  35. package/dist/store/sqlite.d.ts +6 -0
  36. package/dist/store/sqlite.d.ts.map +1 -1
  37. package/dist/store/sqlite.js +131 -24
  38. package/dist/store/sqlite.js.map +1 -1
  39. package/dist/webhooks/webhooks.test.js +2 -1
  40. package/dist/webhooks/webhooks.test.js.map +1 -1
  41. package/package.json +1 -1
  42. package/src/domain/events.ts +7 -0
  43. package/src/engine/cascade.test.ts +121 -0
  44. package/src/engine/index.ts +126 -6
  45. package/src/schemas/index.ts +31 -0
  46. package/src/store/firebase.ts +47 -8
  47. package/src/store/index.ts +40 -0
  48. package/src/store/query.test.ts +110 -0
  49. package/src/store/query.ts +113 -0
  50. package/src/store/sqlite.ts +149 -31
  51. package/src/webhooks/webhooks.test.ts +2 -1
  52. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/store/query.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=query.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.test.d.ts","sourceRoot":"","sources":["../../src/store/query.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,89 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { CriticalPathEngine, InMemoryStore, SQLiteStore, FirebaseStore, InMemoryFirestoreMock, ValidationError, createRolePolicy, MAX_PAGE_SIZE } from '../index.js';
3
+ const stores = [
4
+ ['InMemoryStore', () => new InMemoryStore()],
5
+ ['SQLiteStore', () => new SQLiteStore({ filename: ':memory:' })],
6
+ ['FirebaseStore', () => new FirebaseStore({ db: new InMemoryFirestoreMock() })]
7
+ ];
8
+ describe.each(stores)('task and activity queries (%s)', (_name, makeStore) => {
9
+ async function setup() {
10
+ const engine = new CriticalPathEngine({ store: makeStore() });
11
+ const project = await engine.createProject({ name: 'Query' });
12
+ const other = await engine.createProject({ name: 'Other' });
13
+ const sprint = await engine.createIteration({ projectId: project.id, name: 'S1', status: 'active' });
14
+ const parent = await engine.createTask({ projectId: project.id, title: 'Parent', status: 'in_progress', priority: 'high', assigneeId: 'ana' });
15
+ const child = await engine.createTask({ projectId: project.id, title: 'Child', parentId: parent.id, status: 'todo', priority: 'low', iterationId: sprint.id });
16
+ const shared = await engine.createTask({
17
+ projectId: project.id,
18
+ title: 'Shared',
19
+ status: 'done',
20
+ priority: 'high',
21
+ assignees: [{ id: 'ana', type: 'user' }, { id: 'ben', type: 'user' }]
22
+ });
23
+ const elsewhere = await engine.createTask({ projectId: other.id, title: 'Elsewhere', assigneeId: 'ana' });
24
+ return { engine, project, other, sprint, parent, child, shared, elsewhere };
25
+ }
26
+ const titles = (tasks) => tasks.map((t) => t.title).sort();
27
+ it('filters by status, priority, assignee (including assignees), iteration and parent', async () => {
28
+ const { engine, project, sprint, parent } = await setup();
29
+ const q = (query) => engine.queryTasks({ projectId: project.id, ...query }).then((p) => titles(p.items));
30
+ expect(await q({ status: ['todo', 'done'] })).toEqual(['Child', 'Shared']);
31
+ expect(await q({ priority: ['high'] })).toEqual(['Parent', 'Shared']);
32
+ expect(await q({ assigneeId: 'ana' })).toEqual(['Parent', 'Shared']);
33
+ expect(await q({ assigneeId: 'ben' })).toEqual(['Shared']);
34
+ expect(await q({ iterationId: sprint.id })).toEqual(['Child']);
35
+ expect(await q({ parentId: parent.id })).toEqual(['Child']);
36
+ expect(await q({ parentId: null })).toEqual(['Parent', 'Shared']);
37
+ expect(titles((await engine.queryTasks({ assigneeId: 'ana' })).items)).toEqual(['Elsewhere', 'Parent', 'Shared']);
38
+ });
39
+ it('pages through every task exactly once, oldest first', async () => {
40
+ const { engine, project } = await setup();
41
+ for (let i = 0; i < 12; i++)
42
+ await engine.createTask({ projectId: project.id, title: `Bulk ${i}` });
43
+ const seen = [];
44
+ let cursor;
45
+ do {
46
+ const page = await engine.queryTasks({ projectId: project.id, limit: 5, cursor });
47
+ expect(page.items.length).toBeLessThanOrEqual(5);
48
+ seen.push(...page.items);
49
+ cursor = page.nextCursor;
50
+ } while (cursor);
51
+ expect(seen).toHaveLength(15);
52
+ expect(new Set(seen.map((t) => t.id)).size).toBe(15);
53
+ const keys = seen.map((t) => `${t.createdAt}|${t.id}`);
54
+ expect([...keys].sort()).toEqual(keys);
55
+ });
56
+ it('pages the activity feed newest first', async () => {
57
+ const { engine, project } = await setup();
58
+ const all = (await engine.queryActivities({ projectId: project.id, limit: MAX_PAGE_SIZE })).items;
59
+ expect(all.length).toBeGreaterThan(3);
60
+ const keys = all.map((a) => `${a.createdAt}|${a.id}`);
61
+ expect([...keys].sort().reverse()).toEqual(keys);
62
+ const first = await engine.queryActivities({ projectId: project.id, limit: 2 });
63
+ const second = await engine.queryActivities({ projectId: project.id, limit: 2, cursor: first.nextCursor });
64
+ expect([...first.items, ...second.items].map((a) => a.id)).toEqual(all.slice(0, 4).map((a) => a.id));
65
+ });
66
+ it('rejects malformed cursors and clamps page sizes', async () => {
67
+ const { engine, project } = await setup();
68
+ await expect(engine.queryTasks({ projectId: project.id, cursor: 'not-a-cursor' })).rejects.toThrow(ValidationError);
69
+ expect((await engine.queryTasks({ projectId: project.id, limit: 0 })).items).toHaveLength(1);
70
+ expect((await engine.queryTasks({ projectId: project.id, limit: 10_000 })).items).toHaveLength(3);
71
+ });
72
+ });
73
+ describe('query authorization', () => {
74
+ it('limits cross-project queries and activity feeds to readable projects', async () => {
75
+ const engine = new CriticalPathEngine({ authorize: createRolePolicy() });
76
+ const mine = await engine.createProject({ name: 'Mine', members: [{ userId: 'ana', role: 'viewer' }] });
77
+ const secret = await engine.createProject({ name: 'Secret' });
78
+ await engine.createTask({ projectId: mine.id, title: 'Visible' });
79
+ await engine.createTask({ projectId: secret.id, title: 'Hidden' });
80
+ const ana = engine.withActor({ userId: 'ana' });
81
+ expect((await ana.queryTasks()).items.map((t) => t.title)).toEqual(['Visible']);
82
+ expect((await ana.queryTasks({ projectId: secret.id })).items).toEqual([]);
83
+ expect((await ana.queryTasks({ projectIds: [mine.id, secret.id] })).items.map((t) => t.title)).toEqual(['Visible']);
84
+ const feed = (await ana.queryActivities()).items;
85
+ expect(feed.length).toBeGreaterThan(0);
86
+ expect(feed.every((a) => a.projectId === mine.id)).toBe(true);
87
+ });
88
+ });
89
+ //# sourceMappingURL=query.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.test.js","sourceRoot":"","sources":["../../src/store/query.test.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import type { DatabaseSync } from 'node:sqlite';
2
2
  import type { StorageAdapter } from './index.js';
3
+ import { type ActivityQuery, type Page, type TaskQuery } from './query.js';
3
4
  import type { Project, Task, Iteration, Team, TaskContainer, Comment, Attachment, TimeEntry, Activity, Webhook, TaskDependency, Workflow, Deliverable, CreateDeliverableInput } from '../types/index.js';
4
5
  export interface SQLiteStoreConfig {
5
6
  /**
@@ -42,6 +43,7 @@ export declare class SQLiteStore implements StorageAdapter {
42
43
  updateDeliverable(id: string, updates: Partial<Deliverable>): Promise<Deliverable | null>;
43
44
  deleteDeliverable(id: string): Promise<boolean>;
44
45
  getTasks(projectId?: string): Promise<Task[]>;
46
+ queryTasks(query: TaskQuery): Promise<Page<Task>>;
45
47
  getTask(id: string): Promise<Task | null>;
46
48
  createTask(task: Omit<Task, 'id' | 'createdAt' | 'updatedAt'>): Promise<Task>;
47
49
  updateTask(id: string, updates: Partial<Task>): Promise<Task | null>;
@@ -77,6 +79,7 @@ export declare class SQLiteStore implements StorageAdapter {
77
79
  projectId?: string;
78
80
  taskId?: string;
79
81
  }): Promise<Activity[]>;
82
+ queryActivities(query: ActivityQuery): Promise<Page<Activity>>;
80
83
  logActivity(activity: Omit<Activity, 'id' | 'createdAt'>): Promise<Activity>;
81
84
  getTimeEntries(taskId: string): Promise<TimeEntry[]>;
82
85
  logTime(entry: Omit<TimeEntry, 'id' | 'loggedAt'> & {
@@ -84,6 +87,9 @@ export declare class SQLiteStore implements StorageAdapter {
84
87
  }): Promise<TimeEntry>;
85
88
  getDependencies(taskId: string): Promise<TaskDependency[]>;
86
89
  addDependency(dep: Omit<TaskDependency, 'id'>): Promise<TaskDependency>;
90
+ getDependency(id: string): Promise<TaskDependency | null>;
91
+ removeDependency(id: string): Promise<boolean>;
92
+ deleteTimeEntry(id: string): Promise<boolean>;
87
93
  getWebhooks(): Promise<Webhook[]>;
88
94
  getWebhook(id: string): Promise<Webhook | null>;
89
95
  updateWebhook(id: string, updates: Partial<Omit<Webhook, 'id' | 'createdAt'>>): Promise<Webhook | null>;
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/store/sqlite.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/store/sqlite.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,12 @@
1
+ import { decodeCursor, encodeCursor, pageSize } from './query.js';
1
2
  import { generateProjectKey } from '../utils/key.js';
3
+ /**
4
+ * SQLite returns NULL columns as `null`, while domain objects leave unset optional fields out.
5
+ * Dropping nulls keeps SQLiteStore results identical to the other adapters.
6
+ */
7
+ function dropNulls(row) {
8
+ return Object.fromEntries(Object.entries(row).filter(([, value]) => value !== null));
9
+ }
2
10
  export class SQLiteStore {
3
11
  db;
4
12
  constructor(config = {}) {
@@ -246,6 +254,16 @@ export class SQLiteStore {
246
254
  catch {
247
255
  // Column may already exist
248
256
  }
257
+ // Indexes for filtered queries and keyset pagination
258
+ this.db.exec(`
259
+ CREATE INDEX IF NOT EXISTS idx_tasks_project_created ON tasks (projectId, createdAt, id);
260
+ CREATE INDEX IF NOT EXISTS idx_tasks_parent ON tasks (parentId);
261
+ CREATE INDEX IF NOT EXISTS idx_activities_project_created ON activities (projectId, createdAt, id);
262
+ CREATE INDEX IF NOT EXISTS idx_activities_task_created ON activities (taskId, createdAt, id);
263
+ CREATE INDEX IF NOT EXISTS idx_comments_task ON comments (taskId);
264
+ CREATE INDEX IF NOT EXISTS idx_dependencies_task ON dependencies (taskId);
265
+ CREATE INDEX IF NOT EXISTS idx_dependencies_upstream ON dependencies (dependsOnTaskId);
266
+ `);
249
267
  for (const column of ['name TEXT', 'tenantId TEXT']) {
250
268
  try {
251
269
  this.db.exec(`ALTER TABLE webhooks ADD COLUMN ${column}`);
@@ -394,12 +412,12 @@ export class SQLiteStore {
394
412
  async getContainers(projectId) {
395
413
  const stmt = this.db.prepare('SELECT * FROM containers WHERE projectId = ?');
396
414
  const rows = stmt.all(projectId);
397
- return rows;
415
+ return rows.map(dropNulls);
398
416
  }
399
417
  async getContainer(id) {
400
418
  const stmt = this.db.prepare('SELECT * FROM containers WHERE id = ?');
401
419
  const row = stmt.get(id);
402
- return row || null;
420
+ return row ? dropNulls(row) : null;
403
421
  }
404
422
  async createContainer(container) {
405
423
  const id = `cnt_${Math.random().toString(36).substring(2, 9)}`;
@@ -497,6 +515,54 @@ export class SQLiteStore {
497
515
  }
498
516
  return rows.map((r) => this.mapTask(r));
499
517
  }
518
+ async queryTasks(query) {
519
+ const where = [];
520
+ const params = [];
521
+ const inList = (column, values) => {
522
+ where.push(`${column} IN (${values.map(() => '?').join(', ')})`);
523
+ params.push(...values);
524
+ };
525
+ if (query.projectId) {
526
+ where.push('projectId = ?');
527
+ params.push(query.projectId);
528
+ }
529
+ if (query.projectIds) {
530
+ if (query.projectIds.length === 0)
531
+ return { items: [] };
532
+ inList('projectId', query.projectIds);
533
+ }
534
+ if (query.status?.length)
535
+ inList('status', query.status);
536
+ if (query.priority?.length)
537
+ inList('priority', query.priority);
538
+ for (const column of ['iterationId', 'deliverableId', 'containerId']) {
539
+ if (query[column]) {
540
+ where.push(`${column} = ?`);
541
+ params.push(query[column]);
542
+ }
543
+ }
544
+ if (query.parentId === null)
545
+ where.push('parentId IS NULL');
546
+ else if (query.parentId) {
547
+ where.push('parentId = ?');
548
+ params.push(query.parentId);
549
+ }
550
+ if (query.assigneeId) {
551
+ where.push("(assigneeId = ? OR EXISTS (SELECT 1 FROM json_each(COALESCE(assignees, '[]')) WHERE json_extract(value, '$.id') = ?))");
552
+ params.push(query.assigneeId, query.assigneeId);
553
+ }
554
+ const after = decodeCursor(query.cursor);
555
+ if (after) {
556
+ where.push('(createdAt > ? OR (createdAt = ? AND id > ?))');
557
+ params.push(after[0], after[0], after[1]);
558
+ }
559
+ const size = pageSize(query.limit);
560
+ const sql = `SELECT * FROM tasks ${where.length ? `WHERE ${where.join(' AND ')}` : ''} ORDER BY createdAt ASC, id ASC LIMIT ?`;
561
+ const rows = this.db.prepare(sql).all(...params, size + 1);
562
+ const items = rows.slice(0, size).map((r) => this.mapTask(r));
563
+ const last = items[items.length - 1];
564
+ return { items, nextCursor: rows.length > size && last ? encodeCursor(last.createdAt, last.id) : undefined };
565
+ }
500
566
  async getTask(id) {
501
567
  const stmt = this.db.prepare('SELECT * FROM tasks WHERE id = ?');
502
568
  const row = stmt.get(id);
@@ -553,12 +619,12 @@ export class SQLiteStore {
553
619
  async getIterations(projectId) {
554
620
  const stmt = this.db.prepare('SELECT * FROM iterations WHERE projectId = ?');
555
621
  const rows = stmt.all(projectId);
556
- return rows;
622
+ return rows.map(dropNulls);
557
623
  }
558
624
  async getIteration(id) {
559
625
  const stmt = this.db.prepare('SELECT * FROM iterations WHERE id = ?');
560
626
  const row = stmt.get(id);
561
- return row || null;
627
+ return row ? dropNulls(row) : null;
562
628
  }
563
629
  async createIteration(iteration) {
564
630
  const id = `iter_${Math.random().toString(36).substring(2, 9)}`;
@@ -590,7 +656,7 @@ export class SQLiteStore {
590
656
  }
591
657
  // --- Comments ---
592
658
  mapComment(row) {
593
- return {
659
+ return dropNulls({
594
660
  id: row.id,
595
661
  taskId: row.taskId,
596
662
  authorId: row.authorId,
@@ -602,7 +668,7 @@ export class SQLiteStore {
602
668
  metadata: row.metadata ? JSON.parse(row.metadata) : undefined,
603
669
  createdAt: row.createdAt,
604
670
  updatedAt: row.updatedAt
605
- };
671
+ });
606
672
  }
607
673
  async getComments(taskId) {
608
674
  const stmt = this.db.prepare('SELECT * FROM comments WHERE taskId = ? ORDER BY createdAt ASC');
@@ -701,7 +767,7 @@ export class SQLiteStore {
701
767
  sql += ' ORDER BY createdAt DESC';
702
768
  const stmt = this.db.prepare(sql);
703
769
  const rows = stmt.all(...params);
704
- return rows.map((r) => ({
770
+ return rows.map((r) => dropNulls({
705
771
  ...r,
706
772
  sizeBytes: Number(r.sizeBytes),
707
773
  metadata: r.metadata ? JSON.parse(r.metadata) : undefined
@@ -712,11 +778,11 @@ export class SQLiteStore {
712
778
  const row = stmt.get(id);
713
779
  if (!row)
714
780
  return null;
715
- return {
781
+ return dropNulls({
716
782
  ...row,
717
783
  sizeBytes: Number(row.sizeBytes),
718
784
  metadata: row.metadata ? JSON.parse(row.metadata) : undefined
719
- };
785
+ });
720
786
  }
721
787
  async createAttachment(attachment) {
722
788
  const id = `att_${Math.random().toString(36).substring(2, 9)}`;
@@ -757,11 +823,42 @@ export class SQLiteStore {
757
823
  sql += ' ORDER BY createdAt DESC';
758
824
  const stmt = this.db.prepare(sql);
759
825
  const rows = stmt.all(...params);
760
- return rows.map((r) => ({
826
+ return rows.map((r) => dropNulls({
761
827
  ...r,
762
828
  details: r.details ? JSON.parse(r.details) : undefined
763
829
  }));
764
830
  }
831
+ async queryActivities(query) {
832
+ const where = [];
833
+ const params = [];
834
+ if (query.projectId) {
835
+ where.push('projectId = ?');
836
+ params.push(query.projectId);
837
+ }
838
+ if (query.projectIds) {
839
+ if (query.projectIds.length === 0)
840
+ return { items: [] };
841
+ where.push(`projectId IN (${query.projectIds.map(() => '?').join(', ')})`);
842
+ params.push(...query.projectIds);
843
+ }
844
+ if (query.taskId) {
845
+ where.push('taskId = ?');
846
+ params.push(query.taskId);
847
+ }
848
+ const after = decodeCursor(query.cursor);
849
+ if (after) {
850
+ where.push('(createdAt < ? OR (createdAt = ? AND id < ?))');
851
+ params.push(after[0], after[0], after[1]);
852
+ }
853
+ const size = pageSize(query.limit);
854
+ const sql = `SELECT * FROM activities ${where.length ? `WHERE ${where.join(' AND ')}` : ''} ORDER BY createdAt DESC, id DESC LIMIT ?`;
855
+ const rows = this.db.prepare(sql).all(...params, size + 1);
856
+ const items = rows
857
+ .slice(0, size)
858
+ .map((r) => dropNulls({ ...r, details: r.details ? JSON.parse(r.details) : undefined }));
859
+ const last = items[items.length - 1];
860
+ return { items, nextCursor: rows.length > size && last ? encodeCursor(last.createdAt, last.id) : undefined };
861
+ }
765
862
  async logActivity(activity) {
766
863
  const id = `act_${Math.random().toString(36).substring(2, 9)}`;
767
864
  const now = new Date().toISOString();
@@ -777,7 +874,7 @@ export class SQLiteStore {
777
874
  async getTimeEntries(taskId) {
778
875
  const stmt = this.db.prepare('SELECT * FROM time_entries WHERE taskId = ?');
779
876
  const rows = stmt.all(taskId);
780
- return rows.map((r) => ({ ...r, isBillable: r.isBillable !== null ? Boolean(r.isBillable) : undefined }));
877
+ return rows.map((r) => dropNulls({ ...r, isBillable: r.isBillable !== null ? Boolean(r.isBillable) : undefined }));
781
878
  }
782
879
  async logTime(entry) {
783
880
  const id = `time_${Math.random().toString(36).substring(2, 9)}`;
@@ -793,7 +890,7 @@ export class SQLiteStore {
793
890
  // --- Dependencies ---
794
891
  async getDependencies(taskId) {
795
892
  const stmt = this.db.prepare('SELECT * FROM dependencies WHERE taskId = ? OR dependsOnTaskId = ?');
796
- return stmt.all(taskId, taskId);
893
+ return stmt.all(taskId, taskId).map(dropNulls);
797
894
  }
798
895
  async addDependency(dep) {
799
896
  const id = `dep_${Math.random().toString(36).substring(2, 9)}`;
@@ -805,6 +902,16 @@ export class SQLiteStore {
805
902
  stmt.run(newDep.id, newDep.taskId, newDep.dependsOnTaskId, newDep.type);
806
903
  return newDep;
807
904
  }
905
+ async getDependency(id) {
906
+ const row = this.db.prepare('SELECT * FROM dependencies WHERE id = ?').get(id);
907
+ return row ? { id: row.id, taskId: row.taskId, dependsOnTaskId: row.dependsOnTaskId, type: row.type } : null;
908
+ }
909
+ async removeDependency(id) {
910
+ return Number(this.db.prepare('DELETE FROM dependencies WHERE id = ?').run(id).changes) > 0;
911
+ }
912
+ async deleteTimeEntry(id) {
913
+ return Number(this.db.prepare('DELETE FROM time_entries WHERE id = ?').run(id).changes) > 0;
914
+ }
808
915
  // --- Webhooks ---
809
916
  async getWebhooks() {
810
917
  const stmt = this.db.prepare('SELECT * FROM webhooks');
@@ -830,7 +937,7 @@ export class SQLiteStore {
830
937
  return Number(result.changes) > 0;
831
938
  }
832
939
  mapWebhook(row) {
833
- return {
940
+ return dropNulls({
834
941
  id: row.id,
835
942
  name: row.name ?? '',
836
943
  url: row.url,
@@ -839,7 +946,7 @@ export class SQLiteStore {
839
946
  active: Boolean(row.active),
840
947
  tenantId: row.tenantId ?? undefined,
841
948
  createdAt: row.createdAt
842
- };
949
+ });
843
950
  }
844
951
  async addWebhook(webhook) {
845
952
  const id = `wh_${Math.random().toString(36).substring(2, 9)}`;
@@ -854,7 +961,7 @@ export class SQLiteStore {
854
961
  }
855
962
  // Helper mappers
856
963
  mapProject(row) {
857
- return {
964
+ return dropNulls({
858
965
  ...row,
859
966
  tenantId: row.tenantId ?? undefined,
860
967
  workflowId: row.workflowId || undefined,
@@ -864,27 +971,27 @@ export class SQLiteStore {
864
971
  statusDefinitions: row.statusDefinitions ? JSON.parse(row.statusDefinitions) : [],
865
972
  priorityDefinitions: row.priorityDefinitions ? JSON.parse(row.priorityDefinitions) : [],
866
973
  customFieldDefinitions: row.customFieldDefinitions ? JSON.parse(row.customFieldDefinitions) : []
867
- };
974
+ });
868
975
  }
869
976
  mapWorkflow(row) {
870
- return {
977
+ return dropNulls({
871
978
  ...row,
872
979
  tenantId: row.tenantId ?? undefined,
873
980
  statuses: row.statuses ? JSON.parse(row.statuses) : [],
874
981
  transitions: row.transitions ? JSON.parse(row.transitions) : [],
875
982
  taskTypes: row.taskTypes ? JSON.parse(row.taskTypes) : undefined,
876
983
  isDefault: row.isDefault !== null && row.isDefault !== undefined ? Boolean(row.isDefault) : undefined
877
- };
984
+ });
878
985
  }
879
986
  mapTeam(row) {
880
- return {
987
+ return dropNulls({
881
988
  ...row,
882
989
  tenantId: row.tenantId ?? undefined,
883
990
  memberIds: row.memberIds ? JSON.parse(row.memberIds) : []
884
- };
991
+ });
885
992
  }
886
993
  mapTask(row) {
887
- return {
994
+ return dropNulls({
888
995
  ...row,
889
996
  actualDurationSeconds: row.actualDurationSeconds ?? undefined,
890
997
  inProgressSince: row.inProgressSince || undefined,
@@ -899,15 +1006,15 @@ export class SQLiteStore {
899
1006
  tags: row.tags ? JSON.parse(row.tags) : [],
900
1007
  assignees: row.assignees ? JSON.parse(row.assignees) : undefined,
901
1008
  customFields: row.customFields ? JSON.parse(row.customFields) : {}
902
- };
1009
+ });
903
1010
  }
904
1011
  mapDeliverable(row) {
905
- return {
1012
+ return dropNulls({
906
1013
  ...row,
907
1014
  specs: row.specs ? JSON.parse(row.specs) : undefined,
908
1015
  outputUrls: row.outputUrls ? JSON.parse(row.outputUrls) : [],
909
1016
  customFields: row.customFields ? JSON.parse(row.customFields) : {}
910
- };
1017
+ });
911
1018
  }
912
1019
  }
913
1020
  //# sourceMappingURL=sqlite.js.map