hzl-core 1.1.0 → 1.2.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 (49) hide show
  1. package/dist/__tests__/backup/backup-restore.test.js +1 -1
  2. package/dist/__tests__/backup/import-export.test.js +37 -28
  3. package/dist/__tests__/backup/import-export.test.js.map +1 -1
  4. package/dist/__tests__/properties/invariants.test.js +4 -1
  5. package/dist/__tests__/properties/invariants.test.js.map +1 -1
  6. package/dist/db/migrations.d.ts.map +1 -1
  7. package/dist/db/migrations.js +68 -0
  8. package/dist/db/migrations.js.map +1 -1
  9. package/dist/db/migrations.test.js +40 -0
  10. package/dist/db/migrations.test.js.map +1 -1
  11. package/dist/db/schema.d.ts +1 -1
  12. package/dist/db/schema.d.ts.map +1 -1
  13. package/dist/db/schema.js +11 -0
  14. package/dist/db/schema.js.map +1 -1
  15. package/dist/events/types.d.ts +44 -1
  16. package/dist/events/types.d.ts.map +1 -1
  17. package/dist/events/types.js +27 -0
  18. package/dist/events/types.js.map +1 -1
  19. package/dist/events/types.test.d.ts +2 -0
  20. package/dist/events/types.test.d.ts.map +1 -0
  21. package/dist/events/types.test.js +113 -0
  22. package/dist/events/types.test.js.map +1 -0
  23. package/dist/index.d.ts +3 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +3 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/projections/projects.d.ts +12 -0
  28. package/dist/projections/projects.d.ts.map +1 -0
  29. package/dist/projections/projects.js +46 -0
  30. package/dist/projections/projects.js.map +1 -0
  31. package/dist/projections/projects.test.d.ts +2 -0
  32. package/dist/projections/projects.test.d.ts.map +1 -0
  33. package/dist/projections/projects.test.js +103 -0
  34. package/dist/projections/projects.test.js.map +1 -0
  35. package/dist/services/project-service.d.ts +40 -0
  36. package/dist/services/project-service.d.ts.map +1 -0
  37. package/dist/services/project-service.js +136 -0
  38. package/dist/services/project-service.js.map +1 -0
  39. package/dist/services/project-service.test.d.ts +2 -0
  40. package/dist/services/project-service.test.d.ts.map +1 -0
  41. package/dist/services/project-service.test.js +136 -0
  42. package/dist/services/project-service.test.js.map +1 -0
  43. package/dist/services/task-service.d.ts +4 -1
  44. package/dist/services/task-service.d.ts.map +1 -1
  45. package/dist/services/task-service.js +30 -1
  46. package/dist/services/task-service.js.map +1 -1
  47. package/dist/services/task-service.test.js +47 -1
  48. package/dist/services/task-service.test.js.map +1 -1
  49. package/package.json +1 -1
@@ -10,6 +10,9 @@ export var EventType;
10
10
  EventType["TaskArchived"] = "task_archived";
11
11
  EventType["CommentAdded"] = "comment_added";
12
12
  EventType["CheckpointRecorded"] = "checkpoint_recorded";
13
+ EventType["ProjectCreated"] = "project_created";
14
+ EventType["ProjectRenamed"] = "project_renamed";
15
+ EventType["ProjectDeleted"] = "project_deleted";
13
16
  })(EventType || (EventType = {}));
14
17
  export var TaskStatus;
15
18
  (function (TaskStatus) {
@@ -25,6 +28,12 @@ const isoDateTime = z.string().refine((s) => !Number.isNaN(Date.parse(s)), {
25
28
  });
26
29
  // Non-empty string
27
30
  const nonEmptyString = z.string().min(1);
31
+ // Project name validation: alphanumeric start, followed by alphanumeric/hyphens/underscores
32
+ const projectName = z
33
+ .string()
34
+ .min(1, 'Project name cannot be empty')
35
+ .max(255, 'Project name cannot exceed 255 characters')
36
+ .regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/, 'Project name must start with alphanumeric and contain only alphanumeric, hyphens, and underscores');
28
37
  // Event data schemas
29
38
  const TaskCreatedSchema = z.object({
30
39
  title: nonEmptyString,
@@ -66,6 +75,20 @@ const CheckpointRecordedSchema = z.object({
66
75
  name: nonEmptyString,
67
76
  data: z.record(z.unknown()).optional(),
68
77
  });
78
+ const ProjectCreatedSchema = z.object({
79
+ name: projectName,
80
+ description: z.string().optional(),
81
+ is_protected: z.boolean().optional(),
82
+ });
83
+ const ProjectRenamedSchema = z.object({
84
+ old_name: projectName,
85
+ new_name: projectName,
86
+ });
87
+ const ProjectDeletedSchema = z.object({
88
+ name: nonEmptyString,
89
+ task_count: z.number().int().min(0),
90
+ archived_task_count: z.number().int().min(0),
91
+ });
69
92
  export const EventSchemas = {
70
93
  [EventType.TaskCreated]: TaskCreatedSchema,
71
94
  [EventType.StatusChanged]: StatusChangedSchema,
@@ -76,6 +99,9 @@ export const EventSchemas = {
76
99
  [EventType.TaskArchived]: TaskArchivedSchema,
77
100
  [EventType.CommentAdded]: CommentAddedSchema,
78
101
  [EventType.CheckpointRecorded]: CheckpointRecordedSchema,
102
+ [EventType.ProjectCreated]: ProjectCreatedSchema,
103
+ [EventType.ProjectRenamed]: ProjectRenamedSchema,
104
+ [EventType.ProjectDeleted]: ProjectDeletedSchema,
79
105
  };
80
106
  export function validateEventData(type, data) {
81
107
  const schema = EventSchemas[type];
@@ -84,4 +110,5 @@ export function validateEventData(type, data) {
84
110
  }
85
111
  schema.parse(data);
86
112
  }
113
+ export const PROJECT_EVENT_TASK_ID = '__project__';
87
114
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/events/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/events/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.test.d.ts","sourceRoot":"","sources":["../../src/events/types.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,113 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { EventType, validateEventData } from './types.js';
3
+ describe('Project event types', () => {
4
+ it('should have ProjectCreated event type', () => {
5
+ expect(EventType.ProjectCreated).toBe('project_created');
6
+ });
7
+ it('should have ProjectRenamed event type', () => {
8
+ expect(EventType.ProjectRenamed).toBe('project_renamed');
9
+ });
10
+ it('should have ProjectDeleted event type', () => {
11
+ expect(EventType.ProjectDeleted).toBe('project_deleted');
12
+ });
13
+ it('should validate ProjectCreated data', () => {
14
+ expect(() => validateEventData(EventType.ProjectCreated, {
15
+ name: 'myproject',
16
+ description: 'A test project',
17
+ })).not.toThrow();
18
+ });
19
+ it('should validate ProjectCreated with is_protected', () => {
20
+ expect(() => validateEventData(EventType.ProjectCreated, {
21
+ name: 'inbox',
22
+ is_protected: true,
23
+ })).not.toThrow();
24
+ });
25
+ it('should validate ProjectRenamed data', () => {
26
+ expect(() => validateEventData(EventType.ProjectRenamed, {
27
+ old_name: 'oldproject',
28
+ new_name: 'newproject',
29
+ })).not.toThrow();
30
+ });
31
+ it('should validate ProjectDeleted data', () => {
32
+ expect(() => validateEventData(EventType.ProjectDeleted, {
33
+ name: 'myproject',
34
+ task_count: 5,
35
+ archived_task_count: 2,
36
+ })).not.toThrow();
37
+ });
38
+ it('should reject ProjectCreated without name', () => {
39
+ expect(() => validateEventData(EventType.ProjectCreated, {})).toThrow();
40
+ });
41
+ it('should reject ProjectRenamed without old_name', () => {
42
+ expect(() => validateEventData(EventType.ProjectRenamed, { new_name: 'foo' })).toThrow();
43
+ });
44
+ describe('project name validation', () => {
45
+ it('should accept valid project names', () => {
46
+ const validNames = [
47
+ 'myproject',
48
+ 'my-project',
49
+ 'my_project',
50
+ 'MyProject123',
51
+ '123project',
52
+ 'a',
53
+ 'A',
54
+ '1',
55
+ ];
56
+ for (const name of validNames) {
57
+ expect(() => validateEventData(EventType.ProjectCreated, { name })).not.toThrow();
58
+ }
59
+ });
60
+ it('should reject project names with leading whitespace', () => {
61
+ expect(() => validateEventData(EventType.ProjectCreated, { name: ' myproject' })).toThrow();
62
+ });
63
+ it('should reject project names with trailing whitespace', () => {
64
+ expect(() => validateEventData(EventType.ProjectCreated, { name: 'myproject ' })).toThrow();
65
+ });
66
+ it('should reject project names with newlines', () => {
67
+ expect(() => validateEventData(EventType.ProjectCreated, { name: 'my\nproject' })).toThrow();
68
+ });
69
+ it('should reject project names with control characters', () => {
70
+ expect(() => validateEventData(EventType.ProjectCreated, { name: 'my\x00project' })).toThrow();
71
+ });
72
+ it('should reject project names with path separators', () => {
73
+ expect(() => validateEventData(EventType.ProjectCreated, { name: 'my/project' })).toThrow();
74
+ expect(() => validateEventData(EventType.ProjectCreated, { name: 'my\\project' })).toThrow();
75
+ });
76
+ it('should reject project names starting with hyphen', () => {
77
+ expect(() => validateEventData(EventType.ProjectCreated, { name: '-myproject' })).toThrow();
78
+ });
79
+ it('should reject project names starting with underscore', () => {
80
+ expect(() => validateEventData(EventType.ProjectCreated, { name: '_myproject' })).toThrow();
81
+ });
82
+ it('should reject project names with spaces', () => {
83
+ expect(() => validateEventData(EventType.ProjectCreated, { name: 'my project' })).toThrow();
84
+ });
85
+ it('should reject project names with special characters', () => {
86
+ const invalidNames = ['my@project', 'my#project', 'my$project', 'my.project'];
87
+ for (const name of invalidNames) {
88
+ expect(() => validateEventData(EventType.ProjectCreated, { name })).toThrow();
89
+ }
90
+ });
91
+ it('should reject project names exceeding 255 characters', () => {
92
+ const longName = 'a'.repeat(256);
93
+ expect(() => validateEventData(EventType.ProjectCreated, { name: longName })).toThrow();
94
+ });
95
+ it('should accept project names at exactly 255 characters', () => {
96
+ const maxName = 'a'.repeat(255);
97
+ expect(() => validateEventData(EventType.ProjectCreated, { name: maxName })).not.toThrow();
98
+ });
99
+ it('should apply same validation to ProjectRenamed new_name', () => {
100
+ expect(() => validateEventData(EventType.ProjectRenamed, {
101
+ old_name: 'valid-name',
102
+ new_name: 'invalid name with spaces',
103
+ })).toThrow();
104
+ });
105
+ it('should apply same validation to ProjectRenamed old_name', () => {
106
+ expect(() => validateEventData(EventType.ProjectRenamed, {
107
+ old_name: 'invalid/path',
108
+ new_name: 'valid-name',
109
+ })).toThrow();
110
+ });
111
+ });
112
+ });
113
+ //# sourceMappingURL=types.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.test.js","sourceRoot":"","sources":["../../src/events/types.test.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -9,7 +9,7 @@
9
9
  export { createConnection, getDefaultDbPath, withWriteTransaction, } from './db/connection.js';
10
10
  export { runMigrations, getCurrentVersion } from './db/migrations.js';
11
11
  export { EventStore, type AppendEventInput, type PersistedEventEnvelope, type GetByTaskIdOptions, } from './events/store.js';
12
- export { EventType, TaskStatus, validateEventData, EventSchemas, type EventEnvelope, type TaskCreatedData, type StatusChangedData, type CommentAddedData, type CheckpointRecordedData, } from './events/types.js';
12
+ export { EventType, TaskStatus, validateEventData, EventSchemas, PROJECT_EVENT_TASK_ID, type EventEnvelope, type TaskCreatedData, type StatusChangedData, type CommentAddedData, type CheckpointRecordedData, } from './events/types.js';
13
13
  export { ProjectionEngine } from './projections/engine.js';
14
14
  export { type Projector, type ProjectionState, } from './projections/types.js';
15
15
  export { TasksCurrentProjector } from './projections/tasks-current.js';
@@ -17,8 +17,10 @@ export { DependenciesProjector } from './projections/dependencies.js';
17
17
  export { TagsProjector } from './projections/tags.js';
18
18
  export { SearchProjector } from './projections/search.js';
19
19
  export { CommentsCheckpointsProjector } from './projections/comments-checkpoints.js';
20
+ export { ProjectsProjector } from './projections/projects.js';
20
21
  export { rebuildAllProjections } from './projections/rebuild.js';
21
22
  export { TaskService, TaskNotFoundError, TaskNotClaimableError, DependenciesNotDoneError, type CreateTaskInput, type EventContext, type Task, type ClaimTaskOptions, type ClaimNextOptions, type StealOptions, type StealResult, type StuckTask, type AvailableTask, type Comment, type Checkpoint, } from './services/task-service.js';
23
+ export { ProjectService, ProjectNotFoundError, ProtectedProjectError, ProjectHasTasksError, ProjectAlreadyExistsError, type Project, type CreateProjectOptions, } from './services/project-service.js';
22
24
  export { ValidationService, type CycleNode, type MissingDep, type ValidationIssue, type ValidationResult, } from './services/validation-service.js';
23
25
  export { SearchService, type SearchTaskResult, type SearchResult, type SearchOptions, } from './services/search-service.js';
24
26
  export { BackupService, type ImportResult, } from './services/backup-service.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAMtE,OAAO,EACL,UAAU,EACV,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,YAAY,EACZ,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,GAC5B,MAAM,mBAAmB,CAAC;AAM3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EACL,KAAK,SAAS,EACd,KAAK,eAAe,GACrB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AAErF,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAMjE,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,EACxB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,IAAI,EACT,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,OAAO,EACZ,KAAK,UAAU,GAChB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,iBAAiB,EACjB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACtB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EACL,aAAa,EACb,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,aAAa,GACnB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,aAAa,EACb,KAAK,YAAY,GAClB,MAAM,8BAA8B,CAAC;AAMtC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAMtD,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,KAAK,UAAU,GAChB,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAMtE,OAAO,EACL,UAAU,EACV,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,YAAY,EACZ,qBAAqB,EACrB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,GAC5B,MAAM,mBAAmB,CAAC;AAM3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EACL,KAAK,SAAS,EACd,KAAK,eAAe,GACrB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAMjE,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,EACxB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,IAAI,EACT,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,OAAO,EACZ,KAAK,UAAU,GAChB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,EACzB,KAAK,OAAO,EACZ,KAAK,oBAAoB,GAC1B,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EACL,iBAAiB,EACjB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACtB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EACL,aAAa,EACb,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,aAAa,GACnB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,aAAa,EACb,KAAK,YAAY,GAClB,MAAM,8BAA8B,CAAC;AAMtC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAMtD,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,KAAK,UAAU,GAChB,MAAM,2BAA2B,CAAC"}
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ export { runMigrations, getCurrentVersion } from './db/migrations.js';
15
15
  // Events
16
16
  // ============================================================================
17
17
  export { EventStore, } from './events/store.js';
18
- export { EventType, TaskStatus, validateEventData, EventSchemas, } from './events/types.js';
18
+ export { EventType, TaskStatus, validateEventData, EventSchemas, PROJECT_EVENT_TASK_ID, } from './events/types.js';
19
19
  // ============================================================================
20
20
  // Projections
21
21
  // ============================================================================
@@ -25,11 +25,13 @@ export { DependenciesProjector } from './projections/dependencies.js';
25
25
  export { TagsProjector } from './projections/tags.js';
26
26
  export { SearchProjector } from './projections/search.js';
27
27
  export { CommentsCheckpointsProjector } from './projections/comments-checkpoints.js';
28
+ export { ProjectsProjector } from './projections/projects.js';
28
29
  export { rebuildAllProjections } from './projections/rebuild.js';
29
30
  // ============================================================================
30
31
  // Services
31
32
  // ============================================================================
32
33
  export { TaskService, TaskNotFoundError, TaskNotClaimableError, DependenciesNotDoneError, } from './services/task-service.js';
34
+ export { ProjectService, ProjectNotFoundError, ProtectedProjectError, ProjectHasTasksError, ProjectAlreadyExistsError, } from './services/project-service.js';
33
35
  export { ValidationService, } from './services/validation-service.js';
34
36
  export { SearchService, } from './services/search-service.js';
35
37
  export { BackupService, } from './services/backup-service.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,+EAA+E;AAC/E,WAAW;AACX,+EAA+E;AAE/E,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEtE,+EAA+E;AAC/E,SAAS;AACT,+EAA+E;AAE/E,OAAO,EACL,UAAU,GAIX,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,YAAY,GAMb,MAAM,mBAAmB,CAAC;AAE3B,+EAA+E;AAC/E,cAAc;AACd,+EAA+E;AAE/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAO3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AAErF,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,+EAA+E;AAC/E,WAAW;AACX,+EAA+E;AAE/E,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,GAYzB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,iBAAiB,GAKlB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EACL,aAAa,GAId,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,aAAa,GAEd,MAAM,8BAA8B,CAAC;AAEtC,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAEtD,+EAA+E;AAC/E,WAAW;AACX,+EAA+E;AAE/E,OAAO,EACL,YAAY,EACZ,mBAAmB,GAEpB,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,+EAA+E;AAC/E,WAAW;AACX,+EAA+E;AAE/E,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEtE,+EAA+E;AAC/E,SAAS;AACT,+EAA+E;AAE/E,OAAO,EACL,UAAU,GAIX,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,YAAY,EACZ,qBAAqB,GAMtB,MAAM,mBAAmB,CAAC;AAE3B,+EAA+E;AAC/E,cAAc;AACd,+EAA+E;AAE/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAO3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,+EAA+E;AAC/E,WAAW;AACX,+EAA+E;AAE/E,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,GAYzB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,GAG1B,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EACL,iBAAiB,GAKlB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EACL,aAAa,GAId,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,aAAa,GAEd,MAAM,8BAA8B,CAAC;AAEtC,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAEtD,+EAA+E;AAC/E,WAAW;AACX,+EAA+E;AAE/E,OAAO,EACL,YAAY,EACZ,mBAAmB,GAEpB,MAAM,2BAA2B,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type Database from 'better-sqlite3';
2
+ import type { PersistedEventEnvelope } from '../events/store.js';
3
+ import type { Projector } from './types.js';
4
+ export declare class ProjectsProjector implements Projector {
5
+ name: string;
6
+ apply(event: PersistedEventEnvelope, db: Database.Database): void;
7
+ reset(db: Database.Database): void;
8
+ private handleProjectCreated;
9
+ private handleProjectRenamed;
10
+ private handleProjectDeleted;
11
+ }
12
+ //# sourceMappingURL=projects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/projections/projects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,qBAAa,iBAAkB,YAAW,SAAS;IACjD,IAAI,SAAc;IAElB,KAAK,CAAC,KAAK,EAAE,sBAAsB,EAAE,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI;IAcjE,KAAK,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI;IAIlC,OAAO,CAAC,oBAAoB;IAuB5B,OAAO,CAAC,oBAAoB;IA+B5B,OAAO,CAAC,oBAAoB;CAO7B"}
@@ -0,0 +1,46 @@
1
+ import { EventType } from '../events/types.js';
2
+ export class ProjectsProjector {
3
+ name = 'projects';
4
+ apply(event, db) {
5
+ switch (event.type) {
6
+ case EventType.ProjectCreated:
7
+ this.handleProjectCreated(event, db);
8
+ break;
9
+ case EventType.ProjectRenamed:
10
+ this.handleProjectRenamed(event, db);
11
+ break;
12
+ case EventType.ProjectDeleted:
13
+ this.handleProjectDeleted(event, db);
14
+ break;
15
+ }
16
+ }
17
+ reset(db) {
18
+ db.exec('DELETE FROM projects');
19
+ }
20
+ handleProjectCreated(event, db) {
21
+ const data = event.data;
22
+ db.prepare(`
23
+ INSERT OR IGNORE INTO projects (name, description, is_protected, created_at, last_event_id)
24
+ VALUES (?, ?, ?, ?, ?)
25
+ `).run(data.name, data.description ?? null, data.is_protected ? 1 : 0, event.timestamp, event.rowid);
26
+ }
27
+ handleProjectRenamed(event, db) {
28
+ const data = event.data;
29
+ const oldProject = db
30
+ .prepare('SELECT * FROM projects WHERE name = ?')
31
+ .get(data.old_name);
32
+ if (!oldProject)
33
+ return;
34
+ db.prepare('DELETE FROM projects WHERE name = ?').run(data.old_name);
35
+ db.prepare(`
36
+ INSERT INTO projects (name, description, is_protected, created_at, last_event_id)
37
+ VALUES (?, ?, ?, ?, ?)
38
+ `).run(data.new_name, oldProject.description, oldProject.is_protected, oldProject.created_at, event.rowid);
39
+ db.prepare('UPDATE tasks_current SET project = ? WHERE project = ?').run(data.new_name, data.old_name);
40
+ }
41
+ handleProjectDeleted(event, db) {
42
+ const data = event.data;
43
+ db.prepare('DELETE FROM projects WHERE name = ?').run(data.name);
44
+ }
45
+ }
46
+ //# sourceMappingURL=projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/projections/projects.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,MAAM,OAAO,iBAAiB;IAC5B,IAAI,GAAG,UAAU,CAAC;IAElB,KAAK,CAAC,KAA6B,EAAE,EAAqB;QACxD,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,SAAS,CAAC,cAAc;gBAC3B,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBACrC,MAAM;YACR,KAAK,SAAS,CAAC,cAAc;gBAC3B,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBACrC,MAAM;YACR,KAAK,SAAS,CAAC,cAAc;gBAC3B,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBACrC,MAAM;QACV,CAAC;IACH,CAAC;IAED,KAAK,CAAC,EAAqB;QACzB,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAClC,CAAC;IAEO,oBAAoB,CAC1B,KAA6B,EAC7B,EAAqB;QAErB,MAAM,IAAI,GAAG,KAAK,CAAC,IAIlB,CAAC;QACF,EAAE,CAAC,OAAO,CACR;;;KAGD,CACA,CAAC,GAAG,CACH,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,WAAW,IAAI,IAAI,EACxB,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACzB,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,KAAK,CACZ,CAAC;IACJ,CAAC;IAEO,oBAAoB,CAC1B,KAA6B,EAC7B,EAAqB;QAErB,MAAM,IAAI,GAAG,KAAK,CAAC,IAA8C,CAAC;QAElE,MAAM,UAAU,GAAG,EAAE;aAClB,OAAO,CAAC,uCAAuC,CAAC;aAChD,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAQ,CAAC;QAC7B,IAAI,CAAC,UAAU;YAAE,OAAO;QAExB,EAAE,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrE,EAAE,CAAC,OAAO,CACR;;;KAGD,CACA,CAAC,GAAG,CACH,IAAI,CAAC,QAAQ,EACb,UAAU,CAAC,WAAW,EACtB,UAAU,CAAC,YAAY,EACvB,UAAU,CAAC,UAAU,EACrB,KAAK,CAAC,KAAK,CACZ,CAAC;QAEF,EAAE,CAAC,OAAO,CAAC,wDAAwD,CAAC,CAAC,GAAG,CACtE,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,QAAQ,CACd,CAAC;IACJ,CAAC;IAEO,oBAAoB,CAC1B,KAA6B,EAC7B,EAAqB;QAErB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAwB,CAAC;QAC5C,EAAE,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnE,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=projects.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.test.d.ts","sourceRoot":"","sources":["../../src/projections/projects.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,103 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import Database from 'better-sqlite3';
3
+ import { ProjectsProjector } from './projects.js';
4
+ import { EventType, PROJECT_EVENT_TASK_ID } from '../events/types.js';
5
+ describe('ProjectsProjector', () => {
6
+ let db;
7
+ let projector;
8
+ beforeEach(() => {
9
+ db = new Database(':memory:');
10
+ db.exec(`
11
+ CREATE TABLE projects (
12
+ name TEXT PRIMARY KEY,
13
+ description TEXT,
14
+ is_protected INTEGER NOT NULL DEFAULT 0,
15
+ created_at TEXT NOT NULL,
16
+ last_event_id INTEGER NOT NULL
17
+ );
18
+ CREATE TABLE tasks_current (
19
+ task_id TEXT PRIMARY KEY,
20
+ title TEXT NOT NULL,
21
+ project TEXT NOT NULL,
22
+ status TEXT NOT NULL,
23
+ created_at TEXT NOT NULL,
24
+ updated_at TEXT NOT NULL,
25
+ last_event_id INTEGER NOT NULL
26
+ );
27
+ `);
28
+ projector = new ProjectsProjector();
29
+ });
30
+ afterEach(() => {
31
+ db.close();
32
+ });
33
+ it('should have correct name', () => {
34
+ expect(projector.name).toBe('projects');
35
+ });
36
+ it('should handle ProjectCreated event', () => {
37
+ const event = {
38
+ rowid: 1,
39
+ event_id: 'evt-1',
40
+ task_id: PROJECT_EVENT_TASK_ID,
41
+ type: EventType.ProjectCreated,
42
+ data: { name: 'myproject', description: 'Test project' },
43
+ timestamp: '2026-01-30T12:00:00.000Z',
44
+ };
45
+ projector.apply(event, db);
46
+ const row = db.prepare('SELECT * FROM projects WHERE name = ?').get('myproject');
47
+ expect(row).toBeDefined();
48
+ expect(row.name).toBe('myproject');
49
+ expect(row.description).toBe('Test project');
50
+ expect(row.is_protected).toBe(0);
51
+ });
52
+ it('should handle ProjectCreated with is_protected', () => {
53
+ const event = {
54
+ rowid: 1,
55
+ event_id: 'evt-1',
56
+ task_id: PROJECT_EVENT_TASK_ID,
57
+ type: EventType.ProjectCreated,
58
+ data: { name: 'inbox', is_protected: true },
59
+ timestamp: '2026-01-30T12:00:00.000Z',
60
+ };
61
+ projector.apply(event, db);
62
+ const row = db.prepare('SELECT * FROM projects WHERE name = ?').get('inbox');
63
+ expect(row.is_protected).toBe(1);
64
+ });
65
+ it('should handle ProjectRenamed event', () => {
66
+ db.prepare('INSERT INTO projects (name, description, is_protected, created_at, last_event_id) VALUES (?, ?, ?, ?, ?)').run('oldname', null, 0, '2026-01-30T12:00:00.000Z', 1);
67
+ const event = {
68
+ rowid: 2,
69
+ event_id: 'evt-2',
70
+ task_id: PROJECT_EVENT_TASK_ID,
71
+ type: EventType.ProjectRenamed,
72
+ data: { old_name: 'oldname', new_name: 'newname' },
73
+ timestamp: '2026-01-30T12:01:00.000Z',
74
+ };
75
+ projector.apply(event, db);
76
+ const oldRow = db.prepare('SELECT * FROM projects WHERE name = ?').get('oldname');
77
+ expect(oldRow).toBeUndefined();
78
+ const newRow = db.prepare('SELECT * FROM projects WHERE name = ?').get('newname');
79
+ expect(newRow).toBeDefined();
80
+ expect(newRow.name).toBe('newname');
81
+ });
82
+ it('should handle ProjectDeleted event', () => {
83
+ db.prepare('INSERT INTO projects (name, description, is_protected, created_at, last_event_id) VALUES (?, ?, ?, ?, ?)').run('myproject', null, 0, '2026-01-30T12:00:00.000Z', 1);
84
+ const event = {
85
+ rowid: 2,
86
+ event_id: 'evt-2',
87
+ task_id: PROJECT_EVENT_TASK_ID,
88
+ type: EventType.ProjectDeleted,
89
+ data: { name: 'myproject', task_count: 0, archived_task_count: 0 },
90
+ timestamp: '2026-01-30T12:01:00.000Z',
91
+ };
92
+ projector.apply(event, db);
93
+ const row = db.prepare('SELECT * FROM projects WHERE name = ?').get('myproject');
94
+ expect(row).toBeUndefined();
95
+ });
96
+ it('should reset projection', () => {
97
+ db.prepare('INSERT INTO projects (name, description, is_protected, created_at, last_event_id) VALUES (?, ?, ?, ?, ?)').run('myproject', null, 0, '2026-01-30T12:00:00.000Z', 1);
98
+ projector.reset(db);
99
+ const count = db.prepare('SELECT COUNT(*) as count FROM projects').get();
100
+ expect(count.count).toBe(0);
101
+ });
102
+ });
103
+ //# sourceMappingURL=projects.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.test.js","sourceRoot":"","sources":["../../src/projections/projects.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import type Database from 'better-sqlite3';
2
+ import { EventStore } from '../events/store.js';
3
+ import { ProjectionEngine } from '../projections/engine.js';
4
+ export interface Project {
5
+ name: string;
6
+ description: string | null;
7
+ is_protected: boolean;
8
+ created_at: string;
9
+ }
10
+ export interface CreateProjectOptions {
11
+ description?: string;
12
+ is_protected?: boolean;
13
+ }
14
+ export declare class ProjectNotFoundError extends Error {
15
+ constructor(name: string);
16
+ }
17
+ export declare class ProtectedProjectError extends Error {
18
+ constructor(name: string, action?: string);
19
+ }
20
+ export declare class ProjectHasTasksError extends Error {
21
+ constructor(name: string, taskCount: number, archivedTaskCount: number);
22
+ }
23
+ export declare class ProjectAlreadyExistsError extends Error {
24
+ constructor(name: string);
25
+ }
26
+ export declare class ProjectService {
27
+ private db;
28
+ private eventStore;
29
+ private projectionEngine;
30
+ constructor(db: Database.Database, eventStore: EventStore, projectionEngine: ProjectionEngine);
31
+ createProject(name: string, options?: CreateProjectOptions): Project;
32
+ getProject(name: string): Project | null;
33
+ projectExists(name: string): boolean;
34
+ listProjects(): Project[];
35
+ renameProject(oldName: string, newName: string): void;
36
+ getTaskCount(projectName: string, includeArchived?: boolean): number;
37
+ ensureInboxExists(): void;
38
+ requireProject(name: string): void;
39
+ }
40
+ //# sourceMappingURL=project-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-service.d.ts","sourceRoot":"","sources":["../../src/services/project-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAG5D,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,IAAI,EAAE,MAAM;CAIzB;AAED,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAiB;CAIpD;AAED,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM;CAMvE;AAED,qBAAa,yBAA0B,SAAQ,KAAK;gBACtC,IAAI,EAAE,MAAM;CAIzB;AAED,qBAAa,cAAc;IAEvB,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,gBAAgB;gBAFhB,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,UAAU,EAAE,UAAU,EACtB,gBAAgB,EAAE,gBAAgB;IAG5C,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO;IAqBpE,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;IAexC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAKpC,YAAY,IAAI,OAAO,EAAE;IAczB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IA0BrD,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,eAAe,GAAE,OAAe,GAAG,MAAM;IAgB3E,iBAAiB,IAAI,IAAI;IAazB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;CAKnC"}