@critical-path/core 0.35.0 → 0.36.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/dist/engine/index.d.ts +2 -0
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/index.js +25 -2
- package/dist/engine/index.js.map +1 -1
- package/dist/types/index.d.ts +11 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +5 -1
- package/CHANGELOG.md +0 -584
- package/dist/deliverables.test.d.ts +0 -2
- package/dist/deliverables.test.d.ts.map +0 -1
- package/dist/deliverables.test.js +0 -232
- package/dist/deliverables.test.js.map +0 -1
- package/dist/domain/calendar.test.d.ts +0 -2
- package/dist/domain/calendar.test.d.ts.map +0 -1
- package/dist/domain/calendar.test.js +0 -181
- package/dist/domain/calendar.test.js.map +0 -1
- package/dist/domain/cpm.test.d.ts +0 -2
- package/dist/domain/cpm.test.d.ts.map +0 -1
- package/dist/domain/cpm.test.js +0 -166
- package/dist/domain/cpm.test.js.map +0 -1
- package/dist/domain/ddd.test.d.ts +0 -2
- package/dist/domain/ddd.test.d.ts.map +0 -1
- package/dist/domain/ddd.test.js +0 -349
- package/dist/domain/ddd.test.js.map +0 -1
- package/dist/domain/ladder.test.d.ts +0 -2
- package/dist/domain/ladder.test.d.ts.map +0 -1
- package/dist/domain/ladder.test.js +0 -213
- package/dist/domain/ladder.test.js.map +0 -1
- package/dist/domain/metrics.test.d.ts +0 -2
- package/dist/domain/metrics.test.d.ts.map +0 -1
- package/dist/domain/metrics.test.js +0 -252
- package/dist/domain/metrics.test.js.map +0 -1
- package/dist/domain/task-duration.test.d.ts +0 -2
- package/dist/domain/task-duration.test.d.ts.map +0 -1
- package/dist/domain/task-duration.test.js +0 -307
- package/dist/domain/task-duration.test.js.map +0 -1
- package/dist/domain/workload.test.d.ts +0 -2
- package/dist/domain/workload.test.d.ts.map +0 -1
- package/dist/domain/workload.test.js +0 -261
- package/dist/domain/workload.test.js.map +0 -1
- package/dist/engine/actor.test.d.ts +0 -2
- package/dist/engine/actor.test.d.ts.map +0 -1
- package/dist/engine/actor.test.js +0 -54
- package/dist/engine/actor.test.js.map +0 -1
- package/dist/engine/authorization.test.d.ts +0 -2
- package/dist/engine/authorization.test.d.ts.map +0 -1
- package/dist/engine/authorization.test.js +0 -154
- package/dist/engine/authorization.test.js.map +0 -1
- package/dist/engine/cascade.test.d.ts +0 -2
- package/dist/engine/cascade.test.d.ts.map +0 -1
- package/dist/engine/cascade.test.js +0 -99
- package/dist/engine/cascade.test.js.map +0 -1
- package/dist/engine/config.test.d.ts +0 -2
- package/dist/engine/config.test.d.ts.map +0 -1
- package/dist/engine/config.test.js +0 -46
- package/dist/engine/config.test.js.map +0 -1
- package/dist/engine/entity-events.test.d.ts +0 -2
- package/dist/engine/entity-events.test.d.ts.map +0 -1
- package/dist/engine/entity-events.test.js +0 -61
- package/dist/engine/entity-events.test.js.map +0 -1
- package/dist/index.test.d.ts +0 -2
- package/dist/index.test.d.ts.map +0 -1
- package/dist/index.test.js +0 -429
- package/dist/index.test.js.map +0 -1
- package/dist/plugins/plugins.test.d.ts +0 -2
- package/dist/plugins/plugins.test.d.ts.map +0 -1
- package/dist/plugins/plugins.test.js +0 -137
- package/dist/plugins/plugins.test.js.map +0 -1
- package/dist/schemas/schemas.test.d.ts +0 -2
- package/dist/schemas/schemas.test.d.ts.map +0 -1
- package/dist/schemas/schemas.test.js +0 -58
- package/dist/schemas/schemas.test.js.map +0 -1
- package/dist/status.test.d.ts +0 -2
- package/dist/status.test.d.ts.map +0 -1
- package/dist/status.test.js +0 -295
- package/dist/status.test.js.map +0 -1
- package/dist/storage/storage.test.d.ts +0 -2
- package/dist/storage/storage.test.d.ts.map +0 -1
- package/dist/storage/storage.test.js +0 -236
- package/dist/storage/storage.test.js.map +0 -1
- package/dist/store/conformance.test.d.ts +0 -2
- package/dist/store/conformance.test.d.ts.map +0 -1
- package/dist/store/conformance.test.js +0 -15
- package/dist/store/conformance.test.js.map +0 -1
- package/dist/store/firebase.test.d.ts +0 -2
- package/dist/store/firebase.test.d.ts.map +0 -1
- package/dist/store/firebase.test.js +0 -103
- package/dist/store/firebase.test.js.map +0 -1
- package/dist/store/query.test.d.ts +0 -2
- package/dist/store/query.test.d.ts.map +0 -1
- package/dist/store/query.test.js +0 -89
- package/dist/store/query.test.js.map +0 -1
- package/dist/store/sqlite.test.d.ts +0 -2
- package/dist/store/sqlite.test.d.ts.map +0 -1
- package/dist/store/sqlite.test.js +0 -177
- package/dist/store/sqlite.test.js.map +0 -1
- package/dist/task-state.test.d.ts +0 -2
- package/dist/task-state.test.d.ts.map +0 -1
- package/dist/task-state.test.js +0 -423
- package/dist/task-state.test.js.map +0 -1
- package/dist/use-case-validation.test.d.ts +0 -2
- package/dist/use-case-validation.test.d.ts.map +0 -1
- package/dist/use-case-validation.test.js +0 -281
- package/dist/use-case-validation.test.js.map +0 -1
- package/dist/utils/fractional-index.test.d.ts +0 -2
- package/dist/utils/fractional-index.test.d.ts.map +0 -1
- package/dist/utils/fractional-index.test.js +0 -182
- package/dist/utils/fractional-index.test.js.map +0 -1
- package/dist/utils/key.test.d.ts +0 -2
- package/dist/utils/key.test.d.ts.map +0 -1
- package/dist/utils/key.test.js +0 -65
- package/dist/utils/key.test.js.map +0 -1
- package/dist/utils/mentions.test.d.ts +0 -2
- package/dist/utils/mentions.test.d.ts.map +0 -1
- package/dist/utils/mentions.test.js +0 -114
- package/dist/utils/mentions.test.js.map +0 -1
- package/dist/webhooks/webhooks.test.d.ts +0 -2
- package/dist/webhooks/webhooks.test.d.ts.map +0 -1
- package/dist/webhooks/webhooks.test.js +0 -154
- package/dist/webhooks/webhooks.test.js.map +0 -1
- package/src/deliverables.test.ts +0 -284
- package/src/domain/authorization.ts +0 -82
- package/src/domain/calendar.test.ts +0 -216
- package/src/domain/calendar.ts +0 -502
- package/src/domain/cpm.test.ts +0 -189
- package/src/domain/cpm.ts +0 -258
- package/src/domain/custom-fields.ts +0 -172
- package/src/domain/ddd.test.ts +0 -442
- package/src/domain/entities.ts +0 -798
- package/src/domain/errors.ts +0 -38
- package/src/domain/events.ts +0 -369
- package/src/domain/graph.ts +0 -70
- package/src/domain/index.ts +0 -12
- package/src/domain/ladder.test.ts +0 -251
- package/src/domain/ladder.ts +0 -474
- package/src/domain/metrics.test.ts +0 -288
- package/src/domain/metrics.ts +0 -497
- package/src/domain/task-duration.test.ts +0 -354
- package/src/domain/workload.test.ts +0 -311
- package/src/domain/workload.ts +0 -457
- package/src/engine/actor.test.ts +0 -63
- package/src/engine/authorization.test.ts +0 -199
- package/src/engine/cascade.test.ts +0 -121
- package/src/engine/config.test.ts +0 -51
- package/src/engine/entity-events.test.ts +0 -67
- package/src/engine/index.ts +0 -2472
- package/src/index.test.ts +0 -514
- package/src/index.ts +0 -9
- package/src/plugins/index.ts +0 -103
- package/src/plugins/plugins.test.ts +0 -161
- package/src/schemas/index.ts +0 -402
- package/src/schemas/schemas.test.ts +0 -116
- package/src/status.test.ts +0 -354
- package/src/storage/file-storage.ts +0 -200
- package/src/storage/firebase-storage.ts +0 -209
- package/src/storage/index.ts +0 -3
- package/src/storage/s3.ts +0 -151
- package/src/storage/storage.test.ts +0 -274
- package/src/store/conformance.test.ts +0 -15
- package/src/store/firebase.test.ts +0 -131
- package/src/store/firebase.ts +0 -658
- package/src/store/index.ts +0 -623
- package/src/store/query.test.ts +0 -110
- package/src/store/query.ts +0 -113
- package/src/store/sqlite.test.ts +0 -218
- package/src/store/sqlite.ts +0 -1480
- package/src/task-state.test.ts +0 -506
- package/src/testing/conformance.ts +0 -319
- package/src/testing/index.ts +0 -1
- package/src/types/index.ts +0 -859
- package/src/use-case-validation.test.ts +0 -324
- package/src/utils/fractional-index.test.ts +0 -228
- package/src/utils/fractional-index.ts +0 -254
- package/src/utils/index.ts +0 -7
- package/src/utils/key.test.ts +0 -76
- package/src/utils/key.ts +0 -62
- package/src/utils/mentions.test.ts +0 -132
- package/src/utils/mentions.ts +0 -131
- package/src/utils/status.ts +0 -419
- package/src/utils/workflow.ts +0 -306
- package/src/webhooks/dispatcher.ts +0 -190
- package/src/webhooks/index.ts +0 -2
- package/src/webhooks/signature.ts +0 -57
- package/src/webhooks/webhooks.test.ts +0 -201
- package/tsconfig.json +0 -8
- package/tsconfig.tsbuildinfo +0 -1
package/src/types/index.ts
DELETED
|
@@ -1,859 +0,0 @@
|
|
|
1
|
-
export type DefaultPriority = 'urgent' | 'high' | 'medium' | 'low' | 'none';
|
|
2
|
-
export type Priority = DefaultPriority | (string & {});
|
|
3
|
-
|
|
4
|
-
export type DefaultTaskStatus = 'backlog' | 'todo' | 'in_progress' | 'in_review' | 'done' | 'canceled';
|
|
5
|
-
export type TaskStatus = DefaultTaskStatus | (string & {});
|
|
6
|
-
|
|
7
|
-
export type SemanticStatus = 'not_started' | 'in_progress' | 'completed' | 'canceled';
|
|
8
|
-
|
|
9
|
-
export interface StatusDefinition {
|
|
10
|
-
key: string;
|
|
11
|
-
label: string;
|
|
12
|
-
category: SemanticStatus;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface TaskDerivedStatus {
|
|
16
|
-
semanticStatus: SemanticStatus;
|
|
17
|
-
isReady: boolean;
|
|
18
|
-
isBlocked: boolean;
|
|
19
|
-
blockingTaskIds: string[];
|
|
20
|
-
isOverdue: boolean;
|
|
21
|
-
isUpcoming: boolean;
|
|
22
|
-
isUnplanned: boolean;
|
|
23
|
-
isUnassigned: boolean;
|
|
24
|
-
isStalled: boolean;
|
|
25
|
-
isOverEstimate: boolean;
|
|
26
|
-
isPaceWarning: boolean;
|
|
27
|
-
isDone: boolean;
|
|
28
|
-
isActive: boolean;
|
|
29
|
-
isCancelled: boolean;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export type TaskLifecycleState = TaskDerivedStatus;
|
|
33
|
-
|
|
34
|
-
export type Role = 'admin' | 'project_manager' | 'contributor' | 'viewer';
|
|
35
|
-
|
|
36
|
-
export interface WorkingHoursRange {
|
|
37
|
-
start: string; // "09:00" (HH:MM 24-hour format)
|
|
38
|
-
end: string; // "17:00"
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export interface DaySchedule {
|
|
42
|
-
dayOfWeek: number; // 0 = Sunday, 1 = Monday, ..., 6 = Saturday
|
|
43
|
-
isWorkingDay: boolean;
|
|
44
|
-
hours?: WorkingHoursRange[];
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export interface Holiday {
|
|
48
|
-
date: string; // "YYYY-MM-DD"
|
|
49
|
-
name?: string;
|
|
50
|
-
halfDay?: boolean; // if true, counts as 50% working hours
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export interface WorkSchedule {
|
|
54
|
-
id?: string;
|
|
55
|
-
name?: string;
|
|
56
|
-
timezone?: string; // Informational (e.g. "UTC", "America/New_York")
|
|
57
|
-
defaultHoursPerDay?: number; // Default: 8
|
|
58
|
-
days: DaySchedule[];
|
|
59
|
-
holidays?: Holiday[];
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export interface User {
|
|
63
|
-
id: string;
|
|
64
|
-
name: string;
|
|
65
|
-
email: string;
|
|
66
|
-
avatarUrl?: string;
|
|
67
|
-
role: Role;
|
|
68
|
-
weeklyCapacityHours?: number;
|
|
69
|
-
schedule?: WorkSchedule;
|
|
70
|
-
createdAt: string;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export interface Team {
|
|
74
|
-
id: string;
|
|
75
|
-
name: string;
|
|
76
|
-
description?: string;
|
|
77
|
-
leaderId?: string;
|
|
78
|
-
memberIds: string[];
|
|
79
|
-
weeklyCapacityHours?: number;
|
|
80
|
-
schedule?: WorkSchedule;
|
|
81
|
-
/** Tenant that owns the team. Set by the engine from the creating actor. */
|
|
82
|
-
tenantId?: string;
|
|
83
|
-
createdAt: string;
|
|
84
|
-
updatedAt: string;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export interface CustomFieldDefinition {
|
|
88
|
-
id: string;
|
|
89
|
-
key: string;
|
|
90
|
-
label: string;
|
|
91
|
-
/** A built-in type, or a type registered by a plugin's `customFieldTypes`. */
|
|
92
|
-
type: 'text' | 'number' | 'date' | 'boolean' | 'single_select' | 'multi_select' | 'user' | (string & {});
|
|
93
|
-
options?: string[];
|
|
94
|
-
required?: boolean;
|
|
95
|
-
defaultValue?: unknown;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export interface WorkflowTransition {
|
|
99
|
-
id?: string;
|
|
100
|
-
name?: string;
|
|
101
|
-
fromStatusKey: string | '*';
|
|
102
|
-
toStatusKey: string;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export interface TaskTypeDefinition {
|
|
106
|
-
key: string;
|
|
107
|
-
label: string;
|
|
108
|
-
description?: string;
|
|
109
|
-
icon?: string;
|
|
110
|
-
defaultStatusKey?: string;
|
|
111
|
-
workflowId?: string;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
export interface Workflow {
|
|
115
|
-
id: string;
|
|
116
|
-
name: string;
|
|
117
|
-
description?: string;
|
|
118
|
-
statuses: StatusDefinition[];
|
|
119
|
-
transitions: WorkflowTransition[];
|
|
120
|
-
taskTypes?: TaskTypeDefinition[];
|
|
121
|
-
defaultStatusKey?: string;
|
|
122
|
-
isDefault?: boolean;
|
|
123
|
-
/** Tenant that owns the workflow. Set by the engine from the creating actor. */
|
|
124
|
-
tenantId?: string;
|
|
125
|
-
createdAt: string;
|
|
126
|
-
updatedAt: string;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export interface Project {
|
|
130
|
-
id: string;
|
|
131
|
-
key?: string; // e.g. "CP" or "PROJ"
|
|
132
|
-
name: string;
|
|
133
|
-
description?: string;
|
|
134
|
-
ownerId?: string;
|
|
135
|
-
/** Project membership and roles, used by role-based authorization policies. */
|
|
136
|
-
members?: ProjectMember[];
|
|
137
|
-
/** Tenant that owns the project. Set by the engine from the creating actor; never from payloads. */
|
|
138
|
-
tenantId?: string;
|
|
139
|
-
teamIds?: string[]; // team IDs
|
|
140
|
-
workflowId?: string;
|
|
141
|
-
workflow?: Workflow;
|
|
142
|
-
taskTypes?: TaskTypeDefinition[];
|
|
143
|
-
statusDefinitions?: StatusDefinition[];
|
|
144
|
-
priorityDefinitions?: Array<{ key: string; label: string; level?: number }>;
|
|
145
|
-
customFieldDefinitions?: CustomFieldDefinition[];
|
|
146
|
-
schedule?: WorkSchedule;
|
|
147
|
-
startDate?: string;
|
|
148
|
-
targetEndDate?: string;
|
|
149
|
-
createdAt: string;
|
|
150
|
-
updatedAt: string;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
export interface TaskContainer {
|
|
154
|
-
id: string;
|
|
155
|
-
projectId: string;
|
|
156
|
-
name: string;
|
|
157
|
-
description?: string;
|
|
158
|
-
parentId?: string; // nested container hierarchy (e.g., folder -> epic -> group)
|
|
159
|
-
type?: 'epic' | 'group' | 'section' | 'folder' | string;
|
|
160
|
-
color?: string;
|
|
161
|
-
createdAt: string;
|
|
162
|
-
updatedAt: string;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export interface TaskDependency {
|
|
166
|
-
id: string;
|
|
167
|
-
taskId: string;
|
|
168
|
-
dependsOnTaskId: string;
|
|
169
|
-
type: 'blocking' | 'blocked_by' | 'relates_to';
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
export interface TaskDependencyGraph {
|
|
173
|
-
taskId: string;
|
|
174
|
-
upstreamTasks: Task[]; // tasks that this task depends on
|
|
175
|
-
downstreamTasks: Task[]; // tasks that depend on this task
|
|
176
|
-
dependencies: TaskDependency[];
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
export interface TaskTodoItem {
|
|
180
|
-
id: string;
|
|
181
|
-
title: string;
|
|
182
|
-
completed: boolean;
|
|
183
|
-
createdAt?: string;
|
|
184
|
-
completedAt?: string;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
export interface TaskAssignee {
|
|
188
|
-
id: string;
|
|
189
|
-
name?: string;
|
|
190
|
-
role?: string;
|
|
191
|
-
type?: 'user' | 'agent' | 'team';
|
|
192
|
-
avatarUrl?: string;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
export interface Task {
|
|
196
|
-
id: string;
|
|
197
|
-
projectId: string;
|
|
198
|
-
key?: string; // e.g. "MOB-12"
|
|
199
|
-
title: string;
|
|
200
|
-
description?: string;
|
|
201
|
-
status: TaskStatus;
|
|
202
|
-
semanticStatus?: SemanticStatus;
|
|
203
|
-
priority: Priority;
|
|
204
|
-
taskType?: string; // e.g. "bug", "feature", "task", "epic"
|
|
205
|
-
assigneeId?: string;
|
|
206
|
-
assignees?: TaskAssignee[];
|
|
207
|
-
reporterId?: string;
|
|
208
|
-
reviewerId?: string;
|
|
209
|
-
iterationId?: string;
|
|
210
|
-
teamId?: string;
|
|
211
|
-
containerId?: string;
|
|
212
|
-
deliverableId?: string; // Direct link to parent deliverable
|
|
213
|
-
plannedStartDate?: string;
|
|
214
|
-
actualStartDate?: string;
|
|
215
|
-
actualEndDate?: string;
|
|
216
|
-
completedAt?: string;
|
|
217
|
-
dueDate?: string;
|
|
218
|
-
// Duration & Effort (in hours and/or minutes)
|
|
219
|
-
estimatedHours?: number;
|
|
220
|
-
loggedHours?: number;
|
|
221
|
-
actualHours?: number;
|
|
222
|
-
billableHours?: number;
|
|
223
|
-
estimatedDurationMinutes?: number;
|
|
224
|
-
actualDurationMinutes?: number;
|
|
225
|
-
billableDurationMinutes?: number;
|
|
226
|
-
/** Cumulative active execution time spent in 'in_progress' status (in seconds) */
|
|
227
|
-
actualDurationSeconds?: number;
|
|
228
|
-
/** Transient ISO timestamp marking the start of current 'in_progress' session (null when not in_progress) */
|
|
229
|
-
inProgressSince?: string | null;
|
|
230
|
-
/** Cumulative duration spent in blocked state while in progress (in seconds) */
|
|
231
|
-
blockedDurationSeconds?: number;
|
|
232
|
-
/** Transient ISO timestamp marking when the task became blocked while in progress (null when not blocked or not in_progress) */
|
|
233
|
-
blockedSince?: string | null;
|
|
234
|
-
// Progress (0 to 100 percentage)
|
|
235
|
-
progress?: number;
|
|
236
|
-
isBlocked?: boolean;
|
|
237
|
-
blockedReason?: string | null;
|
|
238
|
-
tags?: string[];
|
|
239
|
-
todos?: TaskTodoItem[];
|
|
240
|
-
customFields?: Record<string, unknown>;
|
|
241
|
-
parentId?: string; // Subtask support
|
|
242
|
-
createdAt: string;
|
|
243
|
-
updatedAt: string;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
export type CreateTaskInput = Omit<Task, 'id' | 'createdAt' | 'updatedAt' | 'status' | 'priority'> & {
|
|
247
|
-
status?: TaskStatus;
|
|
248
|
-
priority?: Priority;
|
|
249
|
-
};
|
|
250
|
-
|
|
251
|
-
export type DeliverableStatus =
|
|
252
|
-
| 'draft'
|
|
253
|
-
| 'planned'
|
|
254
|
-
| 'in_production'
|
|
255
|
-
| 'internal_review'
|
|
256
|
-
| 'client_review'
|
|
257
|
-
| 'revision_requested'
|
|
258
|
-
| 'approved'
|
|
259
|
-
| 'delivered'
|
|
260
|
-
| 'canceled'
|
|
261
|
-
| (string & {});
|
|
262
|
-
|
|
263
|
-
export interface Deliverable {
|
|
264
|
-
id: string;
|
|
265
|
-
projectId: string;
|
|
266
|
-
title: string;
|
|
267
|
-
description?: string;
|
|
268
|
-
status: DeliverableStatus;
|
|
269
|
-
format?: string; // e.g., '16:9 4K ProRes', 'Figma', 'PDF'
|
|
270
|
-
specs?: Record<string, unknown>; // Technical specifications (resolution, frame rate, etc.)
|
|
271
|
-
leadId?: string; // Creative director or lead creator
|
|
272
|
-
reviewerId?: string; // Approver or client reviewer
|
|
273
|
-
dueDate?: string;
|
|
274
|
-
deliveredAt?: string;
|
|
275
|
-
outputUrls?: string[]; // Links to final rendered assets, exports, or storage keys
|
|
276
|
-
customFields?: Record<string, unknown>;
|
|
277
|
-
createdAt: string;
|
|
278
|
-
updatedAt: string;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
export interface DeliverableSummary {
|
|
282
|
-
deliverable: Deliverable;
|
|
283
|
-
totalTasks: number;
|
|
284
|
-
completedTasks: number;
|
|
285
|
-
activeTasks: number;
|
|
286
|
-
progressPercentage: number;
|
|
287
|
-
estimatedHours: number;
|
|
288
|
-
loggedHours: number;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
export type CreateDeliverableInput = Omit<Deliverable, 'id' | 'createdAt' | 'updatedAt' | 'status'> & {
|
|
292
|
-
status?: DeliverableStatus;
|
|
293
|
-
};
|
|
294
|
-
|
|
295
|
-
export type CreateProjectInput = Omit<Project, 'id' | 'createdAt' | 'updatedAt'>;
|
|
296
|
-
|
|
297
|
-
export interface Iteration {
|
|
298
|
-
id: string;
|
|
299
|
-
projectId: string;
|
|
300
|
-
name: string;
|
|
301
|
-
goal?: string;
|
|
302
|
-
type?: 'sprint' | 'cycle' | 'milestone' | string;
|
|
303
|
-
startDate?: string;
|
|
304
|
-
endDate?: string;
|
|
305
|
-
status: 'planning' | 'active' | 'completed';
|
|
306
|
-
createdAt: string;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
export type AuthorType = 'user' | 'agent' | 'system';
|
|
310
|
-
|
|
311
|
-
/** The identity a mutation is attributed to (see `CriticalPathEngine.withActor`). */
|
|
312
|
-
export interface Actor {
|
|
313
|
-
userId: string;
|
|
314
|
-
username?: string;
|
|
315
|
-
actorType?: AuthorType;
|
|
316
|
-
/**
|
|
317
|
-
* Tenant the actor belongs to. When set, the actor only sees projects, workflows and teams
|
|
318
|
-
* with the same `tenantId`, and everything it creates is stamped with it.
|
|
319
|
-
*/
|
|
320
|
-
tenantId?: string;
|
|
321
|
-
/** Workspace-wide roles, e.g. `['admin']`. Interpreted by the authorization policy. */
|
|
322
|
-
roles?: string[];
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
/** A user's role on a project. */
|
|
326
|
-
export type ProjectRole = Role;
|
|
327
|
-
|
|
328
|
-
export interface ProjectMember {
|
|
329
|
-
userId: string;
|
|
330
|
-
role: ProjectRole;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
export interface CommentReaction {
|
|
334
|
-
emoji: string;
|
|
335
|
-
userId: string;
|
|
336
|
-
createdAt?: string;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
export interface Comment {
|
|
340
|
-
id: string;
|
|
341
|
-
taskId: string;
|
|
342
|
-
authorId: string;
|
|
343
|
-
authorType?: AuthorType;
|
|
344
|
-
parentId?: string; // Threaded reply support
|
|
345
|
-
content: string;
|
|
346
|
-
mentions?: string[];
|
|
347
|
-
reactions?: CommentReaction[];
|
|
348
|
-
metadata?: Record<string, unknown>;
|
|
349
|
-
createdAt: string;
|
|
350
|
-
updatedAt: string;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
export interface Attachment {
|
|
354
|
-
id: string;
|
|
355
|
-
taskId?: string;
|
|
356
|
-
projectId?: string;
|
|
357
|
-
commentId?: string;
|
|
358
|
-
uploaderId: string;
|
|
359
|
-
uploaderType?: AuthorType;
|
|
360
|
-
filename: string;
|
|
361
|
-
mimeType: string;
|
|
362
|
-
sizeBytes: number;
|
|
363
|
-
url: string;
|
|
364
|
-
storageKey?: string;
|
|
365
|
-
artifactType?: 'plan' | 'spec' | 'deliverable' | 'review' | 'general';
|
|
366
|
-
metadata?: Record<string, unknown>;
|
|
367
|
-
createdAt: string;
|
|
368
|
-
updatedAt: string;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
export type CreateAttachmentInput = Omit<Attachment, 'id' | 'createdAt' | 'updatedAt'>;
|
|
372
|
-
|
|
373
|
-
export interface UploadFileInput {
|
|
374
|
-
filename: string;
|
|
375
|
-
data: Uint8Array | ArrayBuffer | Buffer | Blob | string;
|
|
376
|
-
mimeType?: string;
|
|
377
|
-
pathPrefix?: string;
|
|
378
|
-
encoding?: 'base64' | 'utf-8' | 'binary';
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
export interface UploadFileResult {
|
|
382
|
-
storageKey: string;
|
|
383
|
-
url: string;
|
|
384
|
-
sizeBytes: number;
|
|
385
|
-
mimeType: string;
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
export interface PresignedUrlOptions {
|
|
389
|
-
storageKey: string;
|
|
390
|
-
expiresInSeconds?: number;
|
|
391
|
-
contentType?: string;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
export interface PresignedUploadResult {
|
|
395
|
-
uploadUrl: string;
|
|
396
|
-
storageKey: string;
|
|
397
|
-
method?: 'PUT' | 'POST';
|
|
398
|
-
headers?: Record<string, string>;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
export interface FileStorageAdapter {
|
|
402
|
-
upload(input: UploadFileInput): Promise<UploadFileResult>;
|
|
403
|
-
delete(storageKey: string): Promise<boolean>;
|
|
404
|
-
download?(storageKey: string): Promise<Buffer | Uint8Array>;
|
|
405
|
-
getDownloadUrl?(storageKey: string): Promise<string>;
|
|
406
|
-
getPresignedUploadUrl?(options: PresignedUrlOptions): Promise<PresignedUploadResult>;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
export interface TimeEntry {
|
|
410
|
-
id: string;
|
|
411
|
-
taskId: string;
|
|
412
|
-
userId: string;
|
|
413
|
-
hours: number;
|
|
414
|
-
isBillable?: boolean;
|
|
415
|
-
description?: string;
|
|
416
|
-
loggedAt: string;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
export interface Activity {
|
|
420
|
-
id: string;
|
|
421
|
-
projectId?: string;
|
|
422
|
-
taskId?: string;
|
|
423
|
-
actorId: string;
|
|
424
|
-
action: string;
|
|
425
|
-
details: Record<string, unknown>;
|
|
426
|
-
createdAt: string;
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
export interface Webhook {
|
|
430
|
-
id: string;
|
|
431
|
-
name: string;
|
|
432
|
-
url: string;
|
|
433
|
-
/** HMAC-SHA256 signing secret. Never returned by engine reads (see `PublicWebhook`). */
|
|
434
|
-
secret?: string;
|
|
435
|
-
/** Event names to deliver, or `'*'` for every event. */
|
|
436
|
-
events: WebhookEvent[];
|
|
437
|
-
active: boolean;
|
|
438
|
-
/** Tenant whose events this webhook receives. Set from the creating actor. */
|
|
439
|
-
tenantId?: string;
|
|
440
|
-
createdAt: string;
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
/** A webhook as returned by engine and API reads: the secret is replaced by `hasSecret`. */
|
|
444
|
-
export type PublicWebhook = Omit<Webhook, 'secret'> & { hasSecret: boolean };
|
|
445
|
-
|
|
446
|
-
/**
|
|
447
|
-
* Webhook subscriptions use domain event names (e.g. `task.created`, `time.logged`); see
|
|
448
|
-
* `CriticalPathDomainEvent` in `domain/events.ts`. `'*'` subscribes to everything.
|
|
449
|
-
*/
|
|
450
|
-
export type WebhookEvent = import('../domain/events.js').CriticalPathDomainEvent['name'] | '*';
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* Lifecycle hooks, run in plugin registration order.
|
|
454
|
-
*
|
|
455
|
-
* - `before*` hooks may transform the input or throw to abort the operation. Their output is
|
|
456
|
-
* validated (workflow transitions, custom fields) exactly like caller input, and they cannot
|
|
457
|
-
* move a task to another project.
|
|
458
|
-
* - `after*` hooks run once the change is stored. Errors are logged and do not fail the call.
|
|
459
|
-
*/
|
|
460
|
-
export interface PluginHooks {
|
|
461
|
-
beforeTaskCreate?: (task: Partial<Task>) => Promise<Partial<Task>> | Partial<Task>;
|
|
462
|
-
afterTaskCreate?: (task: Task) => Promise<void> | void;
|
|
463
|
-
beforeTaskUpdate?: (id: string, updates: Partial<Task>) => Promise<Partial<Task>> | Partial<Task>;
|
|
464
|
-
afterTaskUpdate?: (task: Task, previousState: Task) => Promise<void> | void;
|
|
465
|
-
beforeTaskDelete?: (id: string, task: Task) => Promise<void> | void;
|
|
466
|
-
afterTaskDelete?: (id: string, task: Task) => Promise<void> | void;
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
/** A custom field type contributed by a plugin, e.g. `url` or `currency`. */
|
|
470
|
-
export interface CustomFieldType {
|
|
471
|
-
/** The `type` value used in `CustomFieldDefinition`s. Must not clash with a built-in type. */
|
|
472
|
-
type: string;
|
|
473
|
-
label?: string;
|
|
474
|
-
/** Returns an error message for an invalid value, or nothing when valid. Not called for empty values. */
|
|
475
|
-
validate: (value: unknown, definition: CustomFieldDefinition) => string | null | undefined | void;
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
/** Context passed to plugin routes and middleware. */
|
|
479
|
-
export interface PluginRequestContext {
|
|
480
|
-
/** The engine as the calling actor (authorization and tenancy apply). */
|
|
481
|
-
engine: import('../engine/index.js').CriticalPathEngine;
|
|
482
|
-
/** The caller resolved by the router's `getContext`, if any. */
|
|
483
|
-
context?: Record<string, unknown> & { userId?: string };
|
|
484
|
-
url: URL;
|
|
485
|
-
/** Path parameters from the route pattern, e.g. `{ projectId: 'p1' }` for `/reports/:projectId`. */
|
|
486
|
-
params: Record<string, string>;
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
export interface PluginRoute {
|
|
490
|
-
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
491
|
-
/** Path below the router's base, with `:name` parameters, e.g. `/reports/:projectId`. */
|
|
492
|
-
path: string;
|
|
493
|
-
handler: (request: Request, ctx: PluginRequestContext) => Response | Promise<Response>;
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
/**
|
|
497
|
-
* Wraps every routed request (after authentication). Call `next()` to continue, or return a
|
|
498
|
-
* `Response` to short-circuit (e.g. rate limiting).
|
|
499
|
-
*/
|
|
500
|
-
export type PluginMiddleware = (
|
|
501
|
-
request: Request,
|
|
502
|
-
ctx: Omit<PluginRequestContext, 'params'>,
|
|
503
|
-
next: () => Promise<Response>
|
|
504
|
-
) => Response | Promise<Response>;
|
|
505
|
-
|
|
506
|
-
export interface CriticalPathPlugin {
|
|
507
|
-
id: string;
|
|
508
|
-
name: string;
|
|
509
|
-
version: string;
|
|
510
|
-
description?: string;
|
|
511
|
-
hooks?: PluginHooks;
|
|
512
|
-
/** Additional custom field types projects can use in `customFieldDefinitions`. */
|
|
513
|
-
customFieldTypes?: CustomFieldType[];
|
|
514
|
-
/** Runs once when the engine starts; `engine.ready` resolves after every plugin's `init`. */
|
|
515
|
-
init?: (engine: import('../engine/index.js').CriticalPathEngine) => Promise<void> | void;
|
|
516
|
-
/** HTTP routes served by `@critical-path/server`, matched before built-in routes. */
|
|
517
|
-
routes?: PluginRoute[];
|
|
518
|
-
/** Middleware run by `@critical-path/server` around every routed request. */
|
|
519
|
-
middleware?: PluginMiddleware;
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
export interface CriticalPathConfig {
|
|
523
|
-
/**
|
|
524
|
-
* Authorization policy applied to every call made through a `withActor` view (which is how
|
|
525
|
-
* `@critical-path/server` and the MCP server call the engine). Calls on the base engine are
|
|
526
|
-
* trusted. Use `createRolePolicy()` for project-membership roles, or supply your own.
|
|
527
|
-
* When omitted, actors may do anything within their tenant.
|
|
528
|
-
*/
|
|
529
|
-
authorize?: AuthorizationPolicy;
|
|
530
|
-
/**
|
|
531
|
-
* Storage adapter instance, e.g. `new SQLiteStore({ filename: 'app.db' })` or
|
|
532
|
-
* `new FirebaseStore({ db })`. Defaults to an `InMemoryStore`.
|
|
533
|
-
*/
|
|
534
|
-
store?: import('../store/index.js').StorageAdapter;
|
|
535
|
-
/**
|
|
536
|
-
* Your app's user directory: names, weekly capacity and work schedules used by workload and
|
|
537
|
-
* capacity calculations. Critical Path does not store users; pass a list, or a function
|
|
538
|
-
* (called per calculation, with the calling actor) that loads them from your auth system.
|
|
539
|
-
*/
|
|
540
|
-
users?: User[] | ((actor?: Actor) => User[] | Promise<User[]>);
|
|
541
|
-
fileStorage?: FileStorageAdapter;
|
|
542
|
-
plugins?: CriticalPathPlugin[];
|
|
543
|
-
/** Static webhooks (not stored or editable through the API). */
|
|
544
|
-
webhooks?: Omit<Webhook, 'id' | 'createdAt'>[];
|
|
545
|
-
/** Delivery behaviour: queue, timeouts, retries, private URL policy, failure callbacks. */
|
|
546
|
-
webhookDelivery?: import('../webhooks/dispatcher.js').WebhookDeliveryOptions;
|
|
547
|
-
defaultSchedule?: WorkSchedule;
|
|
548
|
-
initialData?: {
|
|
549
|
-
projects?: Project[];
|
|
550
|
-
tasks?: Task[];
|
|
551
|
-
/** Added to the user directory (see `CriticalPathConfig.users`). */
|
|
552
|
-
users?: User[];
|
|
553
|
-
iterations?: Iteration[];
|
|
554
|
-
teams?: Team[];
|
|
555
|
-
containers?: TaskContainer[];
|
|
556
|
-
workflows?: Workflow[];
|
|
557
|
-
deliverables?: Deliverable[];
|
|
558
|
-
};
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
// ==========================================
|
|
562
|
-
// Ladder of Abstraction Types
|
|
563
|
-
// ==========================================
|
|
564
|
-
|
|
565
|
-
export type AbstractionLevel = 'macro' | 'standard' | 'concrete' | 'all';
|
|
566
|
-
|
|
567
|
-
export type MacroPhaseHealth = 'on_track' | 'at_risk' | 'blocked' | 'overdue' | 'completed';
|
|
568
|
-
|
|
569
|
-
export interface MacroPhaseRollup {
|
|
570
|
-
id: string; // containerId, iterationId, deliverableId, or 'unassigned'
|
|
571
|
-
type: 'container' | 'iteration' | 'deliverable' | 'phase';
|
|
572
|
-
name: string;
|
|
573
|
-
description?: string;
|
|
574
|
-
startDate?: string;
|
|
575
|
-
endDate?: string;
|
|
576
|
-
durationHours: number;
|
|
577
|
-
totalTasks: number;
|
|
578
|
-
completedTasks: number;
|
|
579
|
-
inProgressTasks: number;
|
|
580
|
-
blockedTasks: number;
|
|
581
|
-
progressPercentage: number;
|
|
582
|
-
totalEstimatedHours: number;
|
|
583
|
-
totalLoggedHours: number;
|
|
584
|
-
isCritical: boolean;
|
|
585
|
-
criticalTaskCount: number;
|
|
586
|
-
health: MacroPhaseHealth;
|
|
587
|
-
taskIds: string[];
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
export interface MacroTimelineSummary {
|
|
591
|
-
projectId: string;
|
|
592
|
-
projectName: string;
|
|
593
|
-
overallStartDate?: string;
|
|
594
|
-
overallEndDate?: string;
|
|
595
|
-
projectedFinishDate?: string;
|
|
596
|
-
totalDurationHours: number;
|
|
597
|
-
criticalPathDurationHours: number;
|
|
598
|
-
overallProgressPercentage: number;
|
|
599
|
-
health: MacroPhaseHealth;
|
|
600
|
-
totalTasks: number;
|
|
601
|
-
completedTasks: number;
|
|
602
|
-
inProgressTasks: number;
|
|
603
|
-
blockedTasks: number;
|
|
604
|
-
totalEstimatedHours: number;
|
|
605
|
-
totalLoggedHours: number;
|
|
606
|
-
phases: MacroPhaseRollup[];
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
export interface TaskCriticalPathSchedule {
|
|
610
|
-
taskId: string;
|
|
611
|
-
earlyStart: number;
|
|
612
|
-
earlyFinish: number;
|
|
613
|
-
lateStart: number;
|
|
614
|
-
lateFinish: number;
|
|
615
|
-
totalSlack: number;
|
|
616
|
-
isCritical: boolean;
|
|
617
|
-
durationHours?: number;
|
|
618
|
-
earlyStartDate?: string;
|
|
619
|
-
earlyFinishDate?: string;
|
|
620
|
-
lateStartDate?: string;
|
|
621
|
-
lateFinishDate?: string;
|
|
622
|
-
slackWorkingHours?: number;
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
export interface CriticalPathAnalysis {
|
|
626
|
-
projectId: string;
|
|
627
|
-
calculatedAt: string;
|
|
628
|
-
totalDurationHours: number;
|
|
629
|
-
totalWorkingHours?: number;
|
|
630
|
-
projectStartDate?: string;
|
|
631
|
-
projectEndDate?: string;
|
|
632
|
-
criticalTaskIds: string[];
|
|
633
|
-
tasks: TaskCriticalPathSchedule[];
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
export interface ConcreteEvidenceSummary {
|
|
637
|
-
attachmentCount: number;
|
|
638
|
-
deliverableCount: number;
|
|
639
|
-
todoCount: number;
|
|
640
|
-
completedTodoCount: number;
|
|
641
|
-
timeEntryCount: number;
|
|
642
|
-
totalLoggedHours: number;
|
|
643
|
-
hasVisualAsset: boolean;
|
|
644
|
-
lastActivityAt?: string;
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
export interface StandardTaskTimelineItem extends Task {
|
|
648
|
-
cpm?: TaskCriticalPathSchedule;
|
|
649
|
-
blockingTaskIds: string[];
|
|
650
|
-
dependentTaskIds: string[];
|
|
651
|
-
childTaskIds: string[];
|
|
652
|
-
concreteEvidenceSummary: ConcreteEvidenceSummary;
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
export interface RealityDelta {
|
|
656
|
-
plannedStartDate?: string;
|
|
657
|
-
actualStartDate?: string;
|
|
658
|
-
dueDate?: string;
|
|
659
|
-
actualEndDate?: string;
|
|
660
|
-
estimatedHours: number;
|
|
661
|
-
loggedHours: number;
|
|
662
|
-
varianceHours: number; // loggedHours - estimatedHours
|
|
663
|
-
effortVarianceHours?: number; // loggedHours - estimatedHours (effort variance)
|
|
664
|
-
durationVarianceHours?: number; // actual duration hours - planned duration hours
|
|
665
|
-
scheduleVarianceDays?: number; // days difference between planned/due vs actual
|
|
666
|
-
scheduleVarianceWorkingDays?: number; // working days difference between planned/due vs actual
|
|
667
|
-
accuracyRatio?: number; // loggedHours / estimatedHours (estimation accuracy ratio)
|
|
668
|
-
isOverdue: boolean;
|
|
669
|
-
isOverEstimate: boolean;
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
export type ProgressInferenceSource = 'explicit' | 'todos' | 'time_effort' | 'schedule_elapsed' | 'blended';
|
|
673
|
-
|
|
674
|
-
export interface TaskProgressInference {
|
|
675
|
-
progressPercentage: number;
|
|
676
|
-
source: ProgressInferenceSource;
|
|
677
|
-
isExplicit: boolean;
|
|
678
|
-
breakdown: {
|
|
679
|
-
explicitProgress?: number;
|
|
680
|
-
todoProgress?: number;
|
|
681
|
-
effortProgress?: number;
|
|
682
|
-
scheduleProgress?: number;
|
|
683
|
-
};
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
export type ProgressCurveProfile =
|
|
687
|
-
| 'linear'
|
|
688
|
-
| 's_curve'
|
|
689
|
-
| 'early_surge'
|
|
690
|
-
| 'late_rush'
|
|
691
|
-
| 'stalled'
|
|
692
|
-
| 'insufficient_data';
|
|
693
|
-
|
|
694
|
-
export interface TaskProgressHistoryPoint {
|
|
695
|
-
timestamp: string;
|
|
696
|
-
progress: number;
|
|
697
|
-
inferredProgress?: number;
|
|
698
|
-
status: TaskStatus;
|
|
699
|
-
semanticStatus?: SemanticStatus;
|
|
700
|
-
action: string;
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
export interface TaskProgressHistory {
|
|
704
|
-
taskId: string;
|
|
705
|
-
points: TaskProgressHistoryPoint[];
|
|
706
|
-
curveProfile: ProgressCurveProfile;
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
export interface TaskEVM {
|
|
710
|
-
plannedValue: number; // PV (expected hours)
|
|
711
|
-
earnedValue: number; // EV (earned hours)
|
|
712
|
-
actualCost: number; // AC (logged hours)
|
|
713
|
-
costVariance: number; // CV = EV - AC
|
|
714
|
-
scheduleVariance: number; // SV = EV - PV
|
|
715
|
-
costPerformanceIndex: number; // CPI = EV / AC
|
|
716
|
-
schedulePerformanceIndex: number; // SPI = EV / PV
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
export interface TaskInferredActuals {
|
|
720
|
-
actualStartDate?: string;
|
|
721
|
-
actualEndDate?: string;
|
|
722
|
-
isStartDateInferred: boolean;
|
|
723
|
-
isEndDateInferred: boolean;
|
|
724
|
-
activeWorkingHours?: number;
|
|
725
|
-
/** Calendar elapsed hours between actualStartDate and actualEndDate */
|
|
726
|
-
calendarDurationHours?: number;
|
|
727
|
-
/** Cumulative active execution duration in seconds */
|
|
728
|
-
actualDurationSeconds?: number;
|
|
729
|
-
/** Cumulative duration spent in blocked state while in progress (in seconds) */
|
|
730
|
-
blockedDurationSeconds?: number;
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
export interface TaskMetrics {
|
|
734
|
-
taskId: string;
|
|
735
|
-
inferredActuals: TaskInferredActuals;
|
|
736
|
-
realityDelta: RealityDelta;
|
|
737
|
-
progress: TaskProgressInference;
|
|
738
|
-
evm: TaskEVM;
|
|
739
|
-
progressHistory: TaskProgressHistory;
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
export interface ConcreteTaskEvidence {
|
|
743
|
-
taskId: string;
|
|
744
|
-
attachments: Attachment[];
|
|
745
|
-
deliverables: Deliverable[];
|
|
746
|
-
todos: TaskTodoItem[];
|
|
747
|
-
timeEntries: TimeEntry[];
|
|
748
|
-
dailyEffortDistribution: Array<{ date: string; hours: number }>;
|
|
749
|
-
activities: Activity[];
|
|
750
|
-
realityDelta: RealityDelta;
|
|
751
|
-
evidenceSummary: ConcreteEvidenceSummary;
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
export interface TimelineLadderOptions {
|
|
755
|
-
level?: AbstractionLevel;
|
|
756
|
-
containerId?: string;
|
|
757
|
-
iterationId?: string;
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
export interface TimelineLadder {
|
|
761
|
-
projectId: string;
|
|
762
|
-
generatedAt: string;
|
|
763
|
-
level: AbstractionLevel;
|
|
764
|
-
macro?: MacroTimelineSummary;
|
|
765
|
-
standard?: {
|
|
766
|
-
tasks: StandardTaskTimelineItem[];
|
|
767
|
-
criticalPathTaskIds: string[];
|
|
768
|
-
dependencies: TaskDependency[];
|
|
769
|
-
totalDurationHours: number;
|
|
770
|
-
};
|
|
771
|
-
concrete?: Record<string, ConcreteTaskEvidence>;
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
export interface TaskLadderView {
|
|
775
|
-
taskId: string;
|
|
776
|
-
macroPhase?: MacroPhaseRollup;
|
|
777
|
-
standard: StandardTaskTimelineItem;
|
|
778
|
-
concrete: ConcreteTaskEvidence;
|
|
779
|
-
metrics?: TaskMetrics;
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
export type WorkloadInterval = 'day' | 'week' | 'month';
|
|
783
|
-
export type WorkloadGroupBy = 'assignee' | 'team' | 'taskType' | 'priority' | 'status';
|
|
784
|
-
export type WorkloadMetric = 'scheduled' | 'logged' | 'remaining' | 'blended';
|
|
785
|
-
|
|
786
|
-
export interface WorkloadBucket {
|
|
787
|
-
date: string; // ISO date string e.g. "2026-09-14" (start of bucket)
|
|
788
|
-
timestamp: number; // Unix timestamp in ms
|
|
789
|
-
totalHours: number;
|
|
790
|
-
values: Record<string, number>; // Dimension key to hours: { [dimensionKey]: hours }
|
|
791
|
-
capacity?: Record<string, number>; // Dimension key to available capacity hours: { [dimensionKey]: capacityHours }
|
|
792
|
-
totalCapacity?: number;
|
|
793
|
-
utilizationRatio?: number; // totalHours / totalCapacity
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
export interface WorkloadDistribution {
|
|
797
|
-
projectId?: string;
|
|
798
|
-
startDate: string;
|
|
799
|
-
endDate: string;
|
|
800
|
-
interval: WorkloadInterval;
|
|
801
|
-
groupBy: WorkloadGroupBy;
|
|
802
|
-
metric: WorkloadMetric;
|
|
803
|
-
seriesKeys: string[]; // Unique series keys sorted across all buckets
|
|
804
|
-
seriesLabels: Record<string, string>; // Human-readable labels e.g. { [key]: "Alice" }
|
|
805
|
-
buckets: WorkloadBucket[];
|
|
806
|
-
totalHours: number;
|
|
807
|
-
totalCapacity?: number;
|
|
808
|
-
averageUtilization?: number;
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
export interface WorkloadDistributionOptions {
|
|
812
|
-
startDate?: string;
|
|
813
|
-
endDate?: string;
|
|
814
|
-
interval?: WorkloadInterval; // default: 'week'
|
|
815
|
-
groupBy?: WorkloadGroupBy; // default: 'assignee'
|
|
816
|
-
metric?: WorkloadMetric; // default: 'blended'
|
|
817
|
-
defaultWeeklyCapacityHours?: number; // default: 40
|
|
818
|
-
capacityOverrides?: Record<string, number>; // e.g. { [assigneeOrTeamId]: weeklyCapacityHours }
|
|
819
|
-
schedule?: WorkSchedule;
|
|
820
|
-
userSchedules?: Record<string, WorkSchedule>;
|
|
821
|
-
teamSchedules?: Record<string, WorkSchedule>;
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
// ==========================================
|
|
825
|
-
// Authorization
|
|
826
|
-
// ==========================================
|
|
827
|
-
|
|
828
|
-
/**
|
|
829
|
-
* Operations the engine authorizes. Project-scoped actions are checked against a project;
|
|
830
|
-
* `project.create` and `workspace.manage` (workflows, teams, webhooks) are workspace-level.
|
|
831
|
-
*/
|
|
832
|
-
export type AuthorizationAction =
|
|
833
|
-
| 'project.read'
|
|
834
|
-
| 'project.create'
|
|
835
|
-
| 'project.update'
|
|
836
|
-
| 'project.delete'
|
|
837
|
-
| 'project.manage_members'
|
|
838
|
-
| 'task.create'
|
|
839
|
-
| 'task.update'
|
|
840
|
-
| 'task.delete'
|
|
841
|
-
| 'comment.create'
|
|
842
|
-
| 'comment.moderate'
|
|
843
|
-
| 'attachment.create'
|
|
844
|
-
| 'attachment.delete'
|
|
845
|
-
| 'time.log'
|
|
846
|
-
| 'plan.manage'
|
|
847
|
-
| 'workspace.manage';
|
|
848
|
-
|
|
849
|
-
export interface AuthorizationRequest {
|
|
850
|
-
actor: Actor;
|
|
851
|
-
action: AuthorizationAction;
|
|
852
|
-
/** The project the action targets, for project-scoped actions. */
|
|
853
|
-
project?: Project;
|
|
854
|
-
/** The specific record, when relevant (e.g. the comment being edited). */
|
|
855
|
-
resource?: { type: 'task' | 'comment' | 'attachment'; ownerId?: string };
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
export type AuthorizationPolicy = (request: AuthorizationRequest) => boolean | Promise<boolean>;
|
|
859
|
-
|