@critical-path/core 0.23.0 → 0.25.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.
- package/CHANGELOG.md +50 -0
- package/README.md +13 -2
- package/dist/domain/errors.d.ts +7 -1
- package/dist/domain/errors.d.ts.map +1 -1
- package/dist/domain/errors.js +3 -4
- package/dist/domain/errors.js.map +1 -1
- package/dist/engine/actor.test.js +1 -0
- package/dist/engine/actor.test.js.map +1 -1
- package/dist/engine/index.d.ts +12 -17
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/index.js +18 -38
- package/dist/engine/index.js.map +1 -1
- package/dist/index.test.js +1 -5
- package/dist/index.test.js.map +1 -1
- package/dist/schemas/index.d.ts +1904 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +276 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/schemas.test.d.ts +2 -0
- package/dist/schemas/schemas.test.d.ts.map +1 -0
- package/dist/schemas/schemas.test.js +57 -0
- package/dist/schemas/schemas.test.js.map +1 -0
- package/package.json +10 -3
- package/src/domain/errors.ts +10 -1
- package/src/engine/actor.test.ts +2 -1
- package/src/engine/index.ts +24 -52
- package/src/index.test.ts +1 -5
- package/src/schemas/index.ts +349 -0
- package/src/schemas/schemas.test.ts +112 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAS1F;AAUD,eAAO,MAAM,oBAAoB,oEAAkE,CAAC;AACpG,eAAO,MAAM,gBAAgB,wCAAsC,CAAC;AAEpE,eAAO,MAAM,sBAAsB;;;;;;;;;;;;EAIjC,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAe7B,CAAC;AAEH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;EAQtC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;EAOnC,CAAC;AAOH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiB/B,CAAC;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAiC,CAAC;AAInE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiB9B,CAAC;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAgC,CAAC;AAgEjE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAuD,CAAC;AAErF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAqC,CAAC;AAInE,eAAO,MAAM,sBAAsB;;;;;;;;;EAGjC,CAAC;AAiBH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAA8D,CAAC;AACnG,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAA4C,CAAC;AAIjF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAO3B,CAAC;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAA6B,CAAC;AAW3D,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;EAA4D,CAAC;AAC/F,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;EAA0C,CAAC;AAY7E,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;EAA4D,CAAC;AAC/F,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;EAEtB,CAAC;AAIb,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;EAM9B,CAAC;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;EAEpB,CAAC;AAEb,eAAO,MAAM,qBAAqB;;;;;;EAEhC,CAAC;AAYH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQjC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAOjC,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;EAIlC,CAAC;AAIH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;EAMxB,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AACjE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AACjE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACvE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEvE,+EAA+E;AAC/E,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACtE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACtE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACpE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACpE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC9D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC9D,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC1E,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAC5E,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAC5E,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC9D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC9D,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACxE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACxE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACxE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACxE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACpE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACpE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACxE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC1E,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC1E,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAC5E,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC"}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request payload schemas for Critical Path resources.
|
|
3
|
+
*
|
|
4
|
+
* Exposed from `@critical-path/core/schemas` (not the package root) so browser bundles of core do
|
|
5
|
+
* not pull in zod. Create schemas omit server-assigned fields (`id`, `createdAt`, `updatedAt`, task
|
|
6
|
+
* `key`); update schemas additionally make every field optional and omit the owning `projectId`.
|
|
7
|
+
* Schemas are strict: unknown or server-assigned keys are rejected with a 400 rather than ignored.
|
|
8
|
+
* Identity (authors, reactors, uploaders, time-entry users) is never taken from payloads; it comes
|
|
9
|
+
* from the caller resolved by the server (see `CriticalPathEngine.withActor`).
|
|
10
|
+
*/
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
import { ValidationError } from '../domain/errors.js';
|
|
13
|
+
/**
|
|
14
|
+
* Parses `data` with `schema`, returning the cleaned value (unknown keys stripped, defaults
|
|
15
|
+
* applied) or throwing a `ValidationError` whose `issues` list every problem.
|
|
16
|
+
*/
|
|
17
|
+
export function parsePayload(schema, data) {
|
|
18
|
+
const result = schema.safeParse(data ?? {});
|
|
19
|
+
if (result.success)
|
|
20
|
+
return result.data;
|
|
21
|
+
const issues = result.error.issues.map((issue) => ({
|
|
22
|
+
path: issue.path.join('.'),
|
|
23
|
+
message: issue.message
|
|
24
|
+
}));
|
|
25
|
+
const summary = issues.map((i) => (i.path ? `${i.path}: ${i.message}` : i.message)).join('; ');
|
|
26
|
+
throw new ValidationError(`Invalid request body: ${summary}`, issues);
|
|
27
|
+
}
|
|
28
|
+
/** Objects reject unknown keys so typos and protected fields surface as 400s. */
|
|
29
|
+
function strictObject(shape) {
|
|
30
|
+
return z.object(shape).strict();
|
|
31
|
+
}
|
|
32
|
+
const isoString = z.string();
|
|
33
|
+
const nonEmpty = z.string().min(1);
|
|
34
|
+
export const SemanticStatusSchema = z.enum(['not_started', 'in_progress', 'completed', 'canceled']);
|
|
35
|
+
export const AuthorTypeSchema = z.enum(['user', 'agent', 'system']);
|
|
36
|
+
export const StatusDefinitionSchema = strictObject({
|
|
37
|
+
key: nonEmpty,
|
|
38
|
+
label: z.string(),
|
|
39
|
+
category: SemanticStatusSchema
|
|
40
|
+
});
|
|
41
|
+
export const WorkScheduleSchema = strictObject({
|
|
42
|
+
id: z.string().optional(),
|
|
43
|
+
name: z.string().optional(),
|
|
44
|
+
timezone: z.string().optional(),
|
|
45
|
+
defaultHoursPerDay: z.number().nonnegative().optional(),
|
|
46
|
+
days: z.array(strictObject({
|
|
47
|
+
dayOfWeek: z.number().int().min(0).max(6),
|
|
48
|
+
isWorkingDay: z.boolean(),
|
|
49
|
+
hours: z.array(strictObject({ start: z.string(), end: z.string() })).optional()
|
|
50
|
+
})),
|
|
51
|
+
holidays: z
|
|
52
|
+
.array(strictObject({ date: z.string(), name: z.string().optional(), halfDay: z.boolean().optional() }))
|
|
53
|
+
.optional()
|
|
54
|
+
});
|
|
55
|
+
export const CustomFieldDefinitionSchema = strictObject({
|
|
56
|
+
id: z.string(),
|
|
57
|
+
key: nonEmpty,
|
|
58
|
+
label: z.string(),
|
|
59
|
+
type: z.enum(['text', 'number', 'date', 'boolean', 'single_select', 'multi_select', 'user']),
|
|
60
|
+
options: z.array(z.string()).optional(),
|
|
61
|
+
required: z.boolean().optional(),
|
|
62
|
+
defaultValue: z.unknown().optional()
|
|
63
|
+
});
|
|
64
|
+
export const TaskTypeDefinitionSchema = strictObject({
|
|
65
|
+
key: nonEmpty,
|
|
66
|
+
label: z.string(),
|
|
67
|
+
description: z.string().optional(),
|
|
68
|
+
icon: z.string().optional(),
|
|
69
|
+
defaultStatusKey: z.string().optional(),
|
|
70
|
+
workflowId: z.string().optional()
|
|
71
|
+
});
|
|
72
|
+
const customFields = z.record(z.unknown());
|
|
73
|
+
const metadata = z.record(z.unknown());
|
|
74
|
+
// --- Workflows ---
|
|
75
|
+
export const CreateWorkflowSchema = strictObject({
|
|
76
|
+
name: nonEmpty,
|
|
77
|
+
description: z.string().optional(),
|
|
78
|
+
statuses: z.array(StatusDefinitionSchema),
|
|
79
|
+
transitions: z
|
|
80
|
+
.array(strictObject({
|
|
81
|
+
id: z.string().optional(),
|
|
82
|
+
name: z.string().optional(),
|
|
83
|
+
fromStatusKey: z.string(),
|
|
84
|
+
toStatusKey: z.string()
|
|
85
|
+
}))
|
|
86
|
+
.default([]),
|
|
87
|
+
taskTypes: z.array(TaskTypeDefinitionSchema).optional(),
|
|
88
|
+
defaultStatusKey: z.string().optional(),
|
|
89
|
+
isDefault: z.boolean().optional()
|
|
90
|
+
});
|
|
91
|
+
export const UpdateWorkflowSchema = CreateWorkflowSchema.partial();
|
|
92
|
+
// --- Projects ---
|
|
93
|
+
export const CreateProjectSchema = strictObject({
|
|
94
|
+
key: z.string().optional(),
|
|
95
|
+
name: nonEmpty,
|
|
96
|
+
description: z.string().optional(),
|
|
97
|
+
ownerId: z.string().optional(),
|
|
98
|
+
members: z.array(z.string()).optional(),
|
|
99
|
+
teamIds: z.array(z.string()).optional(),
|
|
100
|
+
workflowId: z.string().optional(),
|
|
101
|
+
taskTypes: z.array(TaskTypeDefinitionSchema).optional(),
|
|
102
|
+
statusDefinitions: z.array(StatusDefinitionSchema).optional(),
|
|
103
|
+
priorityDefinitions: z
|
|
104
|
+
.array(strictObject({ key: z.string(), label: z.string(), level: z.number().optional() }))
|
|
105
|
+
.optional(),
|
|
106
|
+
customFieldDefinitions: z.array(CustomFieldDefinitionSchema).optional(),
|
|
107
|
+
schedule: WorkScheduleSchema.optional(),
|
|
108
|
+
startDate: isoString.optional(),
|
|
109
|
+
targetEndDate: isoString.optional()
|
|
110
|
+
});
|
|
111
|
+
export const UpdateProjectSchema = CreateProjectSchema.partial();
|
|
112
|
+
// --- Tasks ---
|
|
113
|
+
const taskFields = {
|
|
114
|
+
title: nonEmpty,
|
|
115
|
+
description: z.string().optional(),
|
|
116
|
+
status: z.string().optional(),
|
|
117
|
+
semanticStatus: SemanticStatusSchema.optional(),
|
|
118
|
+
priority: z.string().optional(),
|
|
119
|
+
taskType: z.string().optional(),
|
|
120
|
+
assigneeId: z.string().optional(),
|
|
121
|
+
assignees: z
|
|
122
|
+
.array(strictObject({
|
|
123
|
+
id: z.string(),
|
|
124
|
+
name: z.string().optional(),
|
|
125
|
+
role: z.string().optional(),
|
|
126
|
+
type: z.enum(['user', 'agent', 'team']).optional(),
|
|
127
|
+
avatarUrl: z.string().optional()
|
|
128
|
+
}))
|
|
129
|
+
.optional(),
|
|
130
|
+
reporterId: z.string().optional(),
|
|
131
|
+
reviewerId: z.string().optional(),
|
|
132
|
+
iterationId: z.string().optional(),
|
|
133
|
+
teamId: z.string().optional(),
|
|
134
|
+
containerId: z.string().optional(),
|
|
135
|
+
deliverableId: z.string().optional(),
|
|
136
|
+
plannedStartDate: isoString.optional(),
|
|
137
|
+
actualStartDate: isoString.optional(),
|
|
138
|
+
actualEndDate: isoString.optional(),
|
|
139
|
+
completedAt: isoString.optional(),
|
|
140
|
+
dueDate: isoString.optional(),
|
|
141
|
+
estimatedHours: z.number().nonnegative().optional(),
|
|
142
|
+
loggedHours: z.number().nonnegative().optional(),
|
|
143
|
+
actualHours: z.number().nonnegative().optional(),
|
|
144
|
+
billableHours: z.number().nonnegative().optional(),
|
|
145
|
+
estimatedDurationMinutes: z.number().nonnegative().optional(),
|
|
146
|
+
actualDurationMinutes: z.number().nonnegative().optional(),
|
|
147
|
+
billableDurationMinutes: z.number().nonnegative().optional(),
|
|
148
|
+
actualDurationSeconds: z.number().nonnegative().optional(),
|
|
149
|
+
inProgressSince: isoString.nullable().optional(),
|
|
150
|
+
blockedDurationSeconds: z.number().nonnegative().optional(),
|
|
151
|
+
blockedSince: isoString.nullable().optional(),
|
|
152
|
+
progress: z.number().min(0).max(100).optional(),
|
|
153
|
+
isBlocked: z.boolean().optional(),
|
|
154
|
+
blockedReason: z.string().nullable().optional(),
|
|
155
|
+
tags: z.array(z.string()).optional(),
|
|
156
|
+
todos: z
|
|
157
|
+
.array(strictObject({
|
|
158
|
+
id: z.string(),
|
|
159
|
+
title: z.string(),
|
|
160
|
+
completed: z.boolean(),
|
|
161
|
+
createdAt: isoString.optional(),
|
|
162
|
+
completedAt: isoString.optional()
|
|
163
|
+
}))
|
|
164
|
+
.optional(),
|
|
165
|
+
customFields: customFields.optional(),
|
|
166
|
+
parentId: z.string().optional()
|
|
167
|
+
};
|
|
168
|
+
export const CreateTaskSchema = strictObject({ projectId: nonEmpty, ...taskFields });
|
|
169
|
+
export const UpdateTaskSchema = strictObject(taskFields).partial();
|
|
170
|
+
// --- Dependencies ---
|
|
171
|
+
export const CreateDependencySchema = strictObject({
|
|
172
|
+
dependsOnTaskId: nonEmpty,
|
|
173
|
+
type: z.enum(['blocking', 'blocked_by', 'relates_to']).default('blocking')
|
|
174
|
+
});
|
|
175
|
+
// --- Deliverables ---
|
|
176
|
+
const deliverableFields = {
|
|
177
|
+
title: nonEmpty,
|
|
178
|
+
description: z.string().optional(),
|
|
179
|
+
status: z.string().optional(),
|
|
180
|
+
format: z.string().optional(),
|
|
181
|
+
specs: z.record(z.unknown()).optional(),
|
|
182
|
+
leadId: z.string().optional(),
|
|
183
|
+
reviewerId: z.string().optional(),
|
|
184
|
+
dueDate: isoString.optional(),
|
|
185
|
+
deliveredAt: isoString.optional(),
|
|
186
|
+
outputUrls: z.array(z.string()).optional(),
|
|
187
|
+
customFields: customFields.optional()
|
|
188
|
+
};
|
|
189
|
+
export const CreateDeliverableSchema = strictObject({ projectId: nonEmpty, ...deliverableFields });
|
|
190
|
+
export const UpdateDeliverableSchema = strictObject(deliverableFields).partial();
|
|
191
|
+
// --- Teams ---
|
|
192
|
+
export const CreateTeamSchema = strictObject({
|
|
193
|
+
name: nonEmpty,
|
|
194
|
+
description: z.string().optional(),
|
|
195
|
+
leaderId: z.string().optional(),
|
|
196
|
+
memberIds: z.array(z.string()).default([]),
|
|
197
|
+
weeklyCapacityHours: z.number().nonnegative().optional(),
|
|
198
|
+
schedule: WorkScheduleSchema.optional()
|
|
199
|
+
});
|
|
200
|
+
export const UpdateTeamSchema = CreateTeamSchema.partial();
|
|
201
|
+
// --- Containers ---
|
|
202
|
+
const containerFields = {
|
|
203
|
+
name: nonEmpty,
|
|
204
|
+
description: z.string().optional(),
|
|
205
|
+
parentId: z.string().optional(),
|
|
206
|
+
type: z.string().optional(),
|
|
207
|
+
color: z.string().optional()
|
|
208
|
+
};
|
|
209
|
+
export const CreateContainerSchema = strictObject({ projectId: nonEmpty, ...containerFields });
|
|
210
|
+
export const UpdateContainerSchema = strictObject(containerFields).partial();
|
|
211
|
+
// --- Iterations ---
|
|
212
|
+
const iterationFields = {
|
|
213
|
+
name: nonEmpty,
|
|
214
|
+
goal: z.string().optional(),
|
|
215
|
+
type: z.string().optional(),
|
|
216
|
+
startDate: isoString.optional(),
|
|
217
|
+
endDate: isoString.optional(),
|
|
218
|
+
status: z.enum(['planning', 'active', 'completed']).default('planning')
|
|
219
|
+
};
|
|
220
|
+
export const CreateIterationSchema = strictObject({ projectId: nonEmpty, ...iterationFields });
|
|
221
|
+
export const UpdateIterationSchema = z
|
|
222
|
+
.object({ ...iterationFields, status: z.enum(['planning', 'active', 'completed']) })
|
|
223
|
+
.partial();
|
|
224
|
+
// --- Comments & Reactions ---
|
|
225
|
+
export const CreateCommentSchema = strictObject({
|
|
226
|
+
taskId: nonEmpty,
|
|
227
|
+
parentId: z.string().optional(),
|
|
228
|
+
content: nonEmpty,
|
|
229
|
+
mentions: z.array(z.string()).optional(),
|
|
230
|
+
metadata: metadata.optional()
|
|
231
|
+
});
|
|
232
|
+
export const UpdateCommentSchema = z
|
|
233
|
+
.object({ content: nonEmpty, mentions: z.array(z.string()), metadata })
|
|
234
|
+
.partial();
|
|
235
|
+
export const CommentReactionSchema = strictObject({
|
|
236
|
+
emoji: nonEmpty
|
|
237
|
+
});
|
|
238
|
+
// --- Attachments ---
|
|
239
|
+
const attachmentLinks = {
|
|
240
|
+
taskId: z.string().optional(),
|
|
241
|
+
projectId: z.string().optional(),
|
|
242
|
+
commentId: z.string().optional(),
|
|
243
|
+
artifactType: z.enum(['plan', 'spec', 'deliverable', 'review', 'general']).optional(),
|
|
244
|
+
metadata: metadata.optional()
|
|
245
|
+
};
|
|
246
|
+
export const CreateAttachmentSchema = strictObject({
|
|
247
|
+
...attachmentLinks,
|
|
248
|
+
filename: nonEmpty,
|
|
249
|
+
// Linked (rather than uploaded) files often have no known type or size.
|
|
250
|
+
mimeType: nonEmpty.default('application/octet-stream'),
|
|
251
|
+
sizeBytes: z.number().int().nonnegative().default(0),
|
|
252
|
+
url: nonEmpty,
|
|
253
|
+
storageKey: z.string().optional()
|
|
254
|
+
});
|
|
255
|
+
export const UploadAttachmentSchema = strictObject({
|
|
256
|
+
...attachmentLinks,
|
|
257
|
+
filename: nonEmpty,
|
|
258
|
+
data: z.string(),
|
|
259
|
+
mimeType: z.string().optional(),
|
|
260
|
+
pathPrefix: z.string().optional(),
|
|
261
|
+
encoding: z.enum(['base64', 'utf-8', 'binary']).optional()
|
|
262
|
+
});
|
|
263
|
+
export const PresignAttachmentSchema = strictObject({
|
|
264
|
+
storageKey: nonEmpty,
|
|
265
|
+
expiresInSeconds: z.number().int().positive().optional(),
|
|
266
|
+
contentType: z.string().optional()
|
|
267
|
+
});
|
|
268
|
+
// --- Time Tracking ---
|
|
269
|
+
export const LogTimeSchema = strictObject({
|
|
270
|
+
taskId: nonEmpty,
|
|
271
|
+
hours: z.number().positive(),
|
|
272
|
+
isBillable: z.boolean().optional(),
|
|
273
|
+
description: z.string().optional(),
|
|
274
|
+
loggedAt: isoString.optional()
|
|
275
|
+
});
|
|
276
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.test.d.ts","sourceRoot":"","sources":["../../src/schemas/schemas.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { CreateTaskSchema, UpdateTaskSchema, CreateWorkflowSchema, CreateTeamSchema, CreateIterationSchema, CreateCommentSchema, LogTimeSchema } from './index.js';
|
|
3
|
+
const keyChecks = [
|
|
4
|
+
true,
|
|
5
|
+
true,
|
|
6
|
+
// `workflow` is a denormalised copy resolved from `workflowId`, so it is not writable.
|
|
7
|
+
true,
|
|
8
|
+
true,
|
|
9
|
+
true,
|
|
10
|
+
true,
|
|
11
|
+
true,
|
|
12
|
+
true,
|
|
13
|
+
true,
|
|
14
|
+
true,
|
|
15
|
+
true,
|
|
16
|
+
// Reactions are managed through the reactions endpoints.
|
|
17
|
+
true,
|
|
18
|
+
true,
|
|
19
|
+
true,
|
|
20
|
+
true
|
|
21
|
+
];
|
|
22
|
+
describe('request schemas', () => {
|
|
23
|
+
it('cover the writable fields of each domain type', () => {
|
|
24
|
+
expect(keyChecks.every(Boolean)).toBe(true);
|
|
25
|
+
});
|
|
26
|
+
it('reject server-assigned, identity and unknown fields', () => {
|
|
27
|
+
for (const extra of [{ id: 'x' }, { projectId: 'other' }, { createdAt: '1999-01-01' }, { key: 'X-1' }, { junk: true }, { actorId: 'ceo' }]) {
|
|
28
|
+
const result = UpdateTaskSchema.safeParse({ title: 'ok', ...extra });
|
|
29
|
+
expect(result.success, JSON.stringify(extra)).toBe(false);
|
|
30
|
+
}
|
|
31
|
+
expect(CreateCommentSchema.safeParse({ taskId: 't1', content: 'hi', authorId: 'ceo' }).success).toBe(false);
|
|
32
|
+
// Nested objects are strict too
|
|
33
|
+
expect(UpdateTaskSchema.safeParse({ todos: [{ id: '1', title: 'a', completed: false, extra: 1 }] }).success).toBe(false);
|
|
34
|
+
expect(UpdateTaskSchema.parse({ title: 'ok' })).toEqual({ title: 'ok' });
|
|
35
|
+
});
|
|
36
|
+
it('reject wrong types and out-of-range values', () => {
|
|
37
|
+
expect(UpdateTaskSchema.safeParse({ status: 123 }).success).toBe(false);
|
|
38
|
+
expect(UpdateTaskSchema.safeParse({ progress: 140 }).success).toBe(false);
|
|
39
|
+
expect(CreateTaskSchema.safeParse({ projectId: 'p1' }).success).toBe(false);
|
|
40
|
+
expect(LogTimeSchema.safeParse({ taskId: 't1', hours: 0 }).success).toBe(false);
|
|
41
|
+
});
|
|
42
|
+
it('apply defaults for optional collections and enums', () => {
|
|
43
|
+
expect(CreateTeamSchema.parse({ name: 'Core' }).memberIds).toEqual([]);
|
|
44
|
+
expect(CreateIterationSchema.parse({ projectId: 'p1', name: 'S1' }).status).toBe('planning');
|
|
45
|
+
expect(CreateWorkflowSchema.parse({ name: 'W', statuses: [] }).transitions).toEqual([]);
|
|
46
|
+
});
|
|
47
|
+
it('keep lifecycle fields writable for imports and backfills', () => {
|
|
48
|
+
const parsed = CreateTaskSchema.parse({
|
|
49
|
+
projectId: 'p1',
|
|
50
|
+
title: 'Imported',
|
|
51
|
+
completedAt: '2026-01-02T00:00:00.000Z',
|
|
52
|
+
actualStartDate: '2026-01-01T00:00:00.000Z'
|
|
53
|
+
});
|
|
54
|
+
expect(parsed.completedAt).toBe('2026-01-02T00:00:00.000Z');
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
//# sourceMappingURL=schemas.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.test.js","sourceRoot":"","sources":["../../src/schemas/schemas.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@critical-path/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.0",
|
|
4
4
|
"description": "Core headless domain engine, plugin architecture, and data stores for Critical Path",
|
|
5
5
|
"author": "Jack James",
|
|
6
6
|
"license": "MIT",
|
|
@@ -13,8 +13,12 @@
|
|
|
13
13
|
"types": "./dist/index.d.ts",
|
|
14
14
|
"exports": {
|
|
15
15
|
".": {
|
|
16
|
-
"
|
|
17
|
-
"
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./schemas": {
|
|
20
|
+
"types": "./dist/schemas/index.d.ts",
|
|
21
|
+
"import": "./dist/schemas/index.js"
|
|
18
22
|
}
|
|
19
23
|
},
|
|
20
24
|
"devDependencies": {
|
|
@@ -25,6 +29,9 @@
|
|
|
25
29
|
"engines": {
|
|
26
30
|
"node": ">=24.0.0"
|
|
27
31
|
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"zod": "^3.25.76"
|
|
34
|
+
},
|
|
28
35
|
"scripts": {
|
|
29
36
|
"build": "tsc --build",
|
|
30
37
|
"test": "vitest run",
|
package/src/domain/errors.ts
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Thrown when input fails a domain rule. Route handlers map it to HTTP 400.
|
|
3
3
|
*/
|
|
4
|
+
export interface ValidationIssue {
|
|
5
|
+
/** Dot-separated path to the invalid field, e.g. `todos.0.title`. Empty for the whole payload. */
|
|
6
|
+
path: string;
|
|
7
|
+
message: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
4
10
|
export class ValidationError extends Error {
|
|
5
|
-
|
|
11
|
+
public readonly issues?: ValidationIssue[];
|
|
12
|
+
|
|
13
|
+
constructor(message: string, issues?: ValidationIssue[]) {
|
|
6
14
|
super(message);
|
|
7
15
|
this.name = 'ValidationError';
|
|
16
|
+
this.issues = issues;
|
|
8
17
|
}
|
|
9
18
|
}
|
|
10
19
|
|
package/src/engine/actor.test.ts
CHANGED
|
@@ -10,7 +10,8 @@ describe('CriticalPathEngine.withActor', () => {
|
|
|
10
10
|
const task = await alice.createTask({ projectId: project.id, title: 'Scoped' });
|
|
11
11
|
expect(task.reporterId).toBe('alice');
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
// Identity in the payload is not part of the update type at all; cast to simulate an untyped caller
|
|
14
|
+
await alice.updateTask(task.id, { title: 'Renamed', actorId: 'ceo', actor: { userId: 'ceo' } } as any);
|
|
14
15
|
const comment = await alice.addComment({ taskId: task.id, content: 'hi', authorId: 'ceo', authorType: 'agent' });
|
|
15
16
|
const reacted = await alice.addCommentReaction(comment.id, { emoji: '👍', userId: 'ceo' });
|
|
16
17
|
const entry = await alice.logTime({ taskId: task.id, hours: 1, userId: 'ceo' } as any);
|
package/src/engine/index.ts
CHANGED
|
@@ -511,12 +511,7 @@ export class CriticalPathEngine {
|
|
|
511
511
|
|
|
512
512
|
async updateTask(
|
|
513
513
|
id: string,
|
|
514
|
-
updates: Partial<Task
|
|
515
|
-
actorId?: string;
|
|
516
|
-
actorName?: string;
|
|
517
|
-
actorType?: string;
|
|
518
|
-
actor?: { userId: string; username?: string; actorType?: string };
|
|
519
|
-
},
|
|
514
|
+
updates: Partial<Task>,
|
|
520
515
|
options?: {
|
|
521
516
|
actorId?: string;
|
|
522
517
|
actorName?: string;
|
|
@@ -527,42 +522,15 @@ export class CriticalPathEngine {
|
|
|
527
522
|
const existing = await this.store.getTask(id);
|
|
528
523
|
if (!existing) return null;
|
|
529
524
|
|
|
530
|
-
//
|
|
531
|
-
// Explicit options from trusted server-side code still take precedence.
|
|
525
|
+
// Identity comes from trusted options or the withActor view, never from the update payload.
|
|
532
526
|
options = options ?? (this.actor ? { actor: this.actor } : undefined);
|
|
533
|
-
const
|
|
534
|
-
|
|
535
|
-
const actorId =
|
|
536
|
-
options?.actorId ||
|
|
537
|
-
claimed?.actorId ||
|
|
538
|
-
options?.actor?.userId ||
|
|
539
|
-
claimed?.actor?.userId ||
|
|
540
|
-
'system';
|
|
527
|
+
const actorId = options?.actorId || options?.actor?.userId || 'system';
|
|
541
528
|
const actorName =
|
|
542
|
-
options?.actorName ||
|
|
543
|
-
claimed?.actorName ||
|
|
544
|
-
options?.actor?.username ||
|
|
545
|
-
claimed?.actor?.username ||
|
|
546
|
-
(actorId === 'system' ? 'System' : undefined);
|
|
529
|
+
options?.actorName || options?.actor?.username || (actorId === 'system' ? 'System' : undefined);
|
|
547
530
|
const actorType =
|
|
548
|
-
options?.actorType ||
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
claimed?.actor?.actorType ||
|
|
552
|
-
(actorId === 'system' ? 'system' : 'user');
|
|
553
|
-
const actorObj = options?.actor || claimed?.actor || {
|
|
554
|
-
userId: actorId,
|
|
555
|
-
username: actorName,
|
|
556
|
-
actorType
|
|
557
|
-
};
|
|
558
|
-
|
|
559
|
-
const {
|
|
560
|
-
actorId: _aId,
|
|
561
|
-
actorName: _aName,
|
|
562
|
-
actorType: _aType,
|
|
563
|
-
actor: _aObj,
|
|
564
|
-
...taskUpdates
|
|
565
|
-
} = updates;
|
|
531
|
+
options?.actorType || options?.actor?.actorType || (actorId === 'system' ? 'system' : 'user');
|
|
532
|
+
const actorObj = options?.actor || { userId: actorId, username: actorName, actorType };
|
|
533
|
+
const taskUpdates = updates;
|
|
566
534
|
|
|
567
535
|
const project = await this.store.getProject(existing.projectId);
|
|
568
536
|
const workflow = await this.resolveProjectWorkflow(existing.projectId);
|
|
@@ -1139,10 +1107,12 @@ export class CriticalPathEngine {
|
|
|
1139
1107
|
return this.store.getComment(id);
|
|
1140
1108
|
}
|
|
1141
1109
|
|
|
1142
|
-
async addComment(
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1110
|
+
async addComment(
|
|
1111
|
+
input: Omit<Comment, 'id' | 'createdAt' | 'updatedAt' | 'authorId'> & { authorId?: string }
|
|
1112
|
+
): Promise<Comment> {
|
|
1113
|
+
const comment: Omit<Comment, 'id' | 'createdAt' | 'updatedAt'> = this.actor
|
|
1114
|
+
? { ...input, authorId: this.actor.userId, authorType: this.actor.actorType ?? 'user' }
|
|
1115
|
+
: { ...input, authorId: input.authorId ?? 'system' };
|
|
1146
1116
|
const mentions = comment.mentions ?? extractMentions(comment.content);
|
|
1147
1117
|
const created = await this.store.addComment({ ...comment, mentions });
|
|
1148
1118
|
const now = new Date().toISOString();
|
|
@@ -1208,8 +1178,8 @@ export class CriticalPathEngine {
|
|
|
1208
1178
|
return deleted;
|
|
1209
1179
|
}
|
|
1210
1180
|
|
|
1211
|
-
async addCommentReaction(commentId: string,
|
|
1212
|
-
|
|
1181
|
+
async addCommentReaction(commentId: string, input: { emoji: string; userId?: string }): Promise<Comment | null> {
|
|
1182
|
+
const reaction = { emoji: input.emoji, userId: this.actor?.userId ?? input.userId ?? 'system' };
|
|
1213
1183
|
const existing = await this.store.getComment(commentId);
|
|
1214
1184
|
if (!existing) return null;
|
|
1215
1185
|
|
|
@@ -1254,8 +1224,8 @@ export class CriticalPathEngine {
|
|
|
1254
1224
|
return updated;
|
|
1255
1225
|
}
|
|
1256
1226
|
|
|
1257
|
-
async removeCommentReaction(commentId: string,
|
|
1258
|
-
|
|
1227
|
+
async removeCommentReaction(commentId: string, input: { emoji: string; userId?: string }): Promise<Comment | null> {
|
|
1228
|
+
const reaction = { emoji: input.emoji, userId: this.actor?.userId ?? input.userId ?? 'system' };
|
|
1259
1229
|
const existing = await this.store.getComment(commentId);
|
|
1260
1230
|
if (!existing) return null;
|
|
1261
1231
|
|
|
@@ -1299,10 +1269,12 @@ export class CriticalPathEngine {
|
|
|
1299
1269
|
return this.store.getAttachment(id);
|
|
1300
1270
|
}
|
|
1301
1271
|
|
|
1302
|
-
async createAttachment(
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1272
|
+
async createAttachment(
|
|
1273
|
+
input: Omit<Attachment, 'id' | 'createdAt' | 'updatedAt' | 'uploaderId'> & { uploaderId?: string }
|
|
1274
|
+
): Promise<Attachment> {
|
|
1275
|
+
const attachment: Omit<Attachment, 'id' | 'createdAt' | 'updatedAt'> = this.actor
|
|
1276
|
+
? { ...input, uploaderId: this.actor.userId, uploaderType: this.actor.actorType ?? 'user' }
|
|
1277
|
+
: { ...input, uploaderId: input.uploaderId ?? 'system' };
|
|
1306
1278
|
validateAttachmentUrl(attachment.url);
|
|
1307
1279
|
const created = await this.store.createAttachment(attachment);
|
|
1308
1280
|
const now = new Date().toISOString();
|
|
@@ -1356,7 +1328,7 @@ export class CriticalPathEngine {
|
|
|
1356
1328
|
taskId?: string;
|
|
1357
1329
|
projectId?: string;
|
|
1358
1330
|
commentId?: string;
|
|
1359
|
-
uploaderId
|
|
1331
|
+
uploaderId?: string;
|
|
1360
1332
|
uploaderType?: 'user' | 'agent' | 'system';
|
|
1361
1333
|
artifactType?: 'plan' | 'spec' | 'deliverable' | 'review' | 'general';
|
|
1362
1334
|
metadata?: Record<string, unknown>;
|
package/src/index.test.ts
CHANGED
|
@@ -485,11 +485,7 @@ describe('CriticalPathEngine Core Tests', () => {
|
|
|
485
485
|
});
|
|
486
486
|
|
|
487
487
|
// Update with explicit actor (e.g. human user updating an assigned agent task)
|
|
488
|
-
await engine.updateTask(task.id, {
|
|
489
|
-
status: 'in_progress',
|
|
490
|
-
actorId: 'user_human_42',
|
|
491
|
-
actorName: 'Jack James'
|
|
492
|
-
});
|
|
488
|
+
await engine.updateTask(task.id, { status: 'in_progress' }, { actorId: 'user_human_42', actorName: 'Jack James' });
|
|
493
489
|
|
|
494
490
|
const activities = await engine.store.getActivities({ taskId: task.id });
|
|
495
491
|
const statusActivity = activities.find((a) => a.action === 'task.status_changed');
|