@critical-path/core 0.22.0 → 0.24.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 +40 -0
- package/README.md +21 -0
- 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.d.ts +2 -0
- package/dist/engine/actor.test.d.ts.map +1 -0
- package/dist/engine/actor.test.js +53 -0
- package/dist/engine/actor.test.js.map +1 -0
- package/dist/engine/index.d.ts +12 -1
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/index.js +54 -20
- package/dist/engine/index.js.map +1 -1
- package/dist/schemas/index.d.ts +1941 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +289 -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 +58 -0
- package/dist/schemas/schemas.test.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +10 -3
- package/src/domain/errors.ts +10 -1
- package/src/engine/actor.test.ts +62 -0
- package/src/engine/index.ts +56 -20
- package/src/schemas/index.ts +337 -0
- package/src/schemas/schemas.test.ts +111 -0
- package/src/types/index.ts +7 -0
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# @critical-path/core
|
|
2
2
|
|
|
3
|
+
## 0.24.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- b54e22c: Validate request bodies with shared zod schemas and publish an OpenAPI document.
|
|
8
|
+
|
|
9
|
+
**@critical-path/core**
|
|
10
|
+
- New `@critical-path/core/schemas` subpath with create/update schemas for every resource and `parsePayload(schema, data)`. Kept off the package root so browser bundles do not include zod. `zod` is now a dependency of core.
|
|
11
|
+
- `ValidationError` carries an optional `issues: { path, message }[]`.
|
|
12
|
+
|
|
13
|
+
**@critical-path/server**
|
|
14
|
+
- All request bodies are validated. Invalid bodies return `400` with `issues`. Server-assigned fields (`id`, `createdAt`, `updatedAt`, task `key`, owning `projectId` on updates) and unknown keys are stripped, so a `PATCH` can no longer move a task to another project.
|
|
15
|
+
- Comments, reactions and attachments require an author unless `getContext` resolves the caller. Attachment `mimeType` and `sizeBytes` default to `application/octet-stream` and `0` for linked files.
|
|
16
|
+
- New `GET /openapi.json` and `buildOpenApiDocument()` (OpenAPI 3.1, request bodies generated from the validation schemas).
|
|
17
|
+
|
|
18
|
+
**@critical-path/mcp**
|
|
19
|
+
- Tool `inputSchema`s are generated from their zod schemas via the new `defineTool`, removing the hand-written JSON copies.
|
|
20
|
+
|
|
21
|
+
**@critical-path/svelte**
|
|
22
|
+
- Rebuilt with the bundled `@critical-path/mcp` changes.
|
|
23
|
+
|
|
24
|
+
## 0.23.0
|
|
25
|
+
|
|
26
|
+
### Minor Changes
|
|
27
|
+
|
|
28
|
+
- 6dd5529: Add request context, authentication hooks and actor attribution.
|
|
29
|
+
|
|
30
|
+
**@critical-path/core**
|
|
31
|
+
- New `engine.withActor(actor)` returns a per-request view that attributes every mutation (activity log, comment authors, reactions, time entries, attachment uploaders, task reporters) to the actor and ignores identity fields supplied in payloads. New exported `Actor` type.
|
|
32
|
+
|
|
33
|
+
**@critical-path/server**
|
|
34
|
+
- New router options, accepted by all adapters as a second argument: `getContext` (resolve the caller per request), `requireAuth` (401 without a user), `basePath` (exact mount path), and `cors` (origin allow-list, credentials, or `false`).
|
|
35
|
+
- With a resolved user, identity fields in request bodies (`actorId`, `authorId`, `userId`, `uploaderId`) are ignored. Reaction routes no longer require `userId` in the body when a user is resolved.
|
|
36
|
+
- `createSvelteKitHandler` options take `getContext(event)` so `event.locals` is available; `configOrRouter` is now optional.
|
|
37
|
+
- New `createUniversalHandler(config, options)` for Workers, Deno, Bun and Hono.
|
|
38
|
+
- `handleRequest(request, { getContext })` lets custom adapters supply a per-request resolver.
|
|
39
|
+
|
|
40
|
+
**@critical-path/mcp**
|
|
41
|
+
- CLI `--api` mode reads `CRITICAL_PATH_API_TOKEN` (sent as a Bearer token) and accepts repeatable `--header "Name: value"`, warning when credentials would go over plain http to a remote host.
|
|
42
|
+
|
|
3
43
|
## 0.22.0
|
|
4
44
|
|
|
5
45
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -122,6 +122,27 @@ try {
|
|
|
122
122
|
|
|
123
123
|
Cycle detection follows the full upstream chain, so indirect cycles (A → B → C → D → A) are rejected as well as direct ones.
|
|
124
124
|
|
|
125
|
+
#### Request Payload Schemas (`@critical-path/core/schemas`)
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
import { CreateTaskSchema, UpdateTaskSchema, parsePayload } from '@critical-path/core/schemas';
|
|
129
|
+
|
|
130
|
+
const input = parsePayload(CreateTaskSchema, await request.json()); // throws ValidationError with `issues`
|
|
131
|
+
await engine.createTask(input);
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Create and update schemas exist for workflows, projects, tasks, dependencies, deliverables, teams, containers, iterations, comments, reactions, attachments and time entries. They strip server-assigned fields and unknown keys. The schemas live on a subpath so importing `@critical-path/core` in a browser bundle does not pull in zod. A compile-time test fails the build if a domain type gains a field its schema lacks.
|
|
135
|
+
|
|
136
|
+
#### Attributing Mutations to a User (`withActor`)
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
const asAlice = engine.withActor({ userId: 'alice', username: 'Alice' });
|
|
140
|
+
await asAlice.updateTask(taskId, { status: 'in_progress' }); // activity actorId: 'alice'
|
|
141
|
+
await asAlice.addComment({ taskId, content: 'On it', authorId: 'ignored' }); // authorId: 'alice'
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
`withActor` returns a per-request view that shares the store, plugins and event bus with the base engine. On the view, identity fields in payloads (`actorId`, `authorId`, reaction `userId`, time entry `userId`, `uploaderId`) are replaced by the actor, and new tasks default `reporterId` to it. Explicit `updateTask(id, updates, { actorId })` options still win, for trusted server-side automation. `@critical-path/server` creates these views from its `getContext` option.
|
|
145
|
+
|
|
125
146
|
Other domain errors are exported for callers and route handlers to map: `ValidationError` (bad input, e.g. non-positive logged hours) and `NotFoundError` (missing referenced entity). `engine.deleteProject(id)` deletes a project and its tasks through `deleteTask`, then publishes `project.deleted`.
|
|
126
147
|
|
|
127
148
|
### 4. Tracking Creative Deliverables & Rollup Metrics
|
package/dist/domain/errors.d.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
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
|
+
}
|
|
4
9
|
export declare class ValidationError extends Error {
|
|
5
|
-
|
|
10
|
+
readonly issues?: ValidationIssue[];
|
|
11
|
+
constructor(message: string, issues?: ValidationIssue[]);
|
|
6
12
|
}
|
|
7
13
|
/**
|
|
8
14
|
* Thrown when a referenced entity does not exist. Route handlers map it to HTTP 404.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/domain/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,eAAgB,SAAQ,KAAK;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/domain/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kGAAkG;IAClG,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,eAAgB,SAAQ,KAAK;IACxC,SAAgB,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;gBAE/B,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,eAAe,EAAE;CAKxD;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;gBAC1B,OAAO,EAAE,MAAM;CAI5B"}
|
package/dist/domain/errors.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Thrown when input fails a domain rule. Route handlers map it to HTTP 400.
|
|
3
|
-
*/
|
|
4
1
|
export class ValidationError extends Error {
|
|
5
|
-
|
|
2
|
+
issues;
|
|
3
|
+
constructor(message, issues) {
|
|
6
4
|
super(message);
|
|
7
5
|
this.name = 'ValidationError';
|
|
6
|
+
this.issues = issues;
|
|
8
7
|
}
|
|
9
8
|
}
|
|
10
9
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/domain/errors.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/domain/errors.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxB,MAAM,CAAqB;IAE3C,YAAY,OAAe,EAAE,MAA0B;QACrD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actor.test.d.ts","sourceRoot":"","sources":["../../src/engine/actor.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { CriticalPathEngine } from '../index.js';
|
|
3
|
+
describe('CriticalPathEngine.withActor', () => {
|
|
4
|
+
it('attributes mutations to the scoped actor and ignores identity claimed in payloads', async () => {
|
|
5
|
+
const engine = new CriticalPathEngine();
|
|
6
|
+
const alice = engine.withActor({ userId: 'alice', username: 'Alice' });
|
|
7
|
+
const project = await alice.createProject({ key: 'ACT', name: 'Actors', ownerId: 'mallory' });
|
|
8
|
+
const task = await alice.createTask({ projectId: project.id, title: 'Scoped' });
|
|
9
|
+
expect(task.reporterId).toBe('alice');
|
|
10
|
+
await alice.updateTask(task.id, { title: 'Renamed', actorId: 'ceo', actor: { userId: 'ceo' } });
|
|
11
|
+
const comment = await alice.addComment({ taskId: task.id, content: 'hi', authorId: 'ceo', authorType: 'agent' });
|
|
12
|
+
const reacted = await alice.addCommentReaction(comment.id, { emoji: '👍', userId: 'ceo' });
|
|
13
|
+
const entry = await alice.logTime({ taskId: task.id, hours: 1, userId: 'ceo' });
|
|
14
|
+
const attachment = await alice.createAttachment({
|
|
15
|
+
taskId: task.id,
|
|
16
|
+
uploaderId: 'ceo',
|
|
17
|
+
filename: 'spec.md',
|
|
18
|
+
mimeType: 'text/markdown',
|
|
19
|
+
sizeBytes: 1,
|
|
20
|
+
url: 'https://example.com/spec.md'
|
|
21
|
+
});
|
|
22
|
+
expect(comment.authorId).toBe('alice');
|
|
23
|
+
expect(comment.authorType).toBe('user');
|
|
24
|
+
expect(reacted?.reactions?.[0].userId).toBe('alice');
|
|
25
|
+
expect(entry.userId).toBe('alice');
|
|
26
|
+
expect(attachment.uploaderId).toBe('alice');
|
|
27
|
+
const activities = await engine.store.getActivities({ projectId: project.id });
|
|
28
|
+
expect(activities.length).toBeGreaterThan(0);
|
|
29
|
+
expect(activities.every((a) => a.actorId === 'alice')).toBe(true);
|
|
30
|
+
});
|
|
31
|
+
it('does not change the base engine, and concurrent views stay isolated', async () => {
|
|
32
|
+
const engine = new CriticalPathEngine();
|
|
33
|
+
const project = await engine.createProject({ key: 'ISO', name: 'Isolation' });
|
|
34
|
+
const [a, b] = await Promise.all([
|
|
35
|
+
engine.withActor({ userId: 'a' }).createTask({ projectId: project.id, title: 'A' }),
|
|
36
|
+
engine.withActor({ userId: 'b' }).createTask({ projectId: project.id, title: 'B' })
|
|
37
|
+
]);
|
|
38
|
+
expect(a.reporterId).toBe('a');
|
|
39
|
+
expect(b.reporterId).toBe('b');
|
|
40
|
+
expect(engine.actor).toBeUndefined();
|
|
41
|
+
// Views share state with the base engine
|
|
42
|
+
expect(await engine.getTask(a.id)).not.toBeNull();
|
|
43
|
+
});
|
|
44
|
+
it('still lets explicit updateTask options override the scoped actor', async () => {
|
|
45
|
+
const engine = new CriticalPathEngine();
|
|
46
|
+
const project = await engine.createProject({ key: 'OPT', name: 'Options' });
|
|
47
|
+
const task = await engine.createTask({ projectId: project.id, title: 'T' });
|
|
48
|
+
await engine.withActor({ userId: 'alice' }).updateTask(task.id, { title: 'T2' }, { actorId: 'automation' });
|
|
49
|
+
const activities = await engine.store.getActivities({ taskId: task.id });
|
|
50
|
+
expect(activities.some((a) => a.actorId === 'automation')).toBe(true);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=actor.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actor.test.js","sourceRoot":"","sources":["../../src/engine/actor.test.ts"],"names":[],"mappings":"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"}
|
package/dist/engine/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CriticalPathConfig, Project, Task, TaskDependency, TaskDependencyGraph, Team, TaskContainer, Iteration, Comment, Attachment, FileStorageAdapter, UploadFileInput, PresignedUrlOptions, PresignedUploadResult, TimeEntry, Workflow, CreateTaskInput, Deliverable, DeliverableSummary, CreateDeliverableInput, TaskLifecycleState, CriticalPathAnalysis, TimelineLadder, TimelineLadderOptions, TaskLadderView, TaskMetrics, TaskProgressHistory, WorkloadDistribution, WorkloadDistributionOptions } from '../types/index.js';
|
|
1
|
+
import type { Actor, CriticalPathConfig, Project, Task, TaskDependency, TaskDependencyGraph, Team, TaskContainer, Iteration, Comment, Attachment, FileStorageAdapter, UploadFileInput, PresignedUrlOptions, PresignedUploadResult, TimeEntry, Workflow, CreateTaskInput, Deliverable, DeliverableSummary, CreateDeliverableInput, TaskLifecycleState, CriticalPathAnalysis, TimelineLadder, TimelineLadderOptions, TaskLadderView, TaskMetrics, TaskProgressHistory, WorkloadDistribution, WorkloadDistributionOptions } from '../types/index.js';
|
|
2
2
|
import { StorageAdapter } from '../store/index.js';
|
|
3
3
|
import { PluginRegistry } from '../plugins/index.js';
|
|
4
4
|
import { DomainEventBus } from '../domain/events.js';
|
|
@@ -11,7 +11,18 @@ export declare class CriticalPathEngine {
|
|
|
11
11
|
readonly plugins: PluginRegistry;
|
|
12
12
|
readonly events: DomainEventBus;
|
|
13
13
|
readonly ready: Promise<void>;
|
|
14
|
+
/** The identity mutations are attributed to. Set only on views returned by `withActor`. */
|
|
15
|
+
readonly actor?: Actor;
|
|
14
16
|
constructor(config?: CriticalPathConfig);
|
|
17
|
+
/**
|
|
18
|
+
* Returns a view of this engine that attributes every mutation to `actor`: activity log
|
|
19
|
+
* entries, comment authors, reactions, time entries, attachment uploaders and task reporters.
|
|
20
|
+
* Identity fields supplied in payloads are ignored on the view, so callers cannot claim to be
|
|
21
|
+
* someone else. The view shares the store, plugins and event bus, and does not modify this engine,
|
|
22
|
+
* so it is safe to create one per request.
|
|
23
|
+
*/
|
|
24
|
+
withActor(actor: Actor): CriticalPathEngine;
|
|
25
|
+
private actorIdOr;
|
|
15
26
|
private seedInitialData;
|
|
16
27
|
getWorkflows(): Promise<Workflow[]>;
|
|
17
28
|
getWorkflow(id: string): Promise<Workflow | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,OAAO,EACP,IAAI,EACJ,cAAc,EACd,mBAAmB,EACnB,IAAI,EACJ,aAAa,EACb,SAAS,EACT,OAAO,EACP,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,qBAAqB,EACrB,SAAS,EAET,QAAQ,EACR,eAAe,EAEf,WAAW,EACX,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,qBAAqB,EACrB,cAAc,EAId,WAAW,EACX,mBAAmB,EACnB,oBAAoB,EACpB,2BAA2B,EAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAiB,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAWrD,OAAO,EACL,cAAc,EA8Bf,MAAM,qBAAqB,CAAC;AAK7B,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEjE,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAG9B,qBAAa,kBAAkB;IAC7B,SAAgB,MAAM,EAAE,kBAAkB,CAAC;IAC3C,SAAgB,KAAK,EAAE,cAAc,CAAC;IACtC,SAAgB,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjD,SAAgB,OAAO,EAAE,cAAc,CAAC;IACxC,SAAgB,MAAM,EAAE,cAAc,CAAC;IACvC,SAAgB,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAqB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"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"}
|
package/dist/engine/index.js
CHANGED
|
@@ -19,6 +19,8 @@ export class CriticalPathEngine {
|
|
|
19
19
|
plugins;
|
|
20
20
|
events;
|
|
21
21
|
ready = Promise.resolve();
|
|
22
|
+
/** The identity mutations are attributed to. Set only on views returned by `withActor`. */
|
|
23
|
+
actor;
|
|
22
24
|
constructor(config = {}) {
|
|
23
25
|
this.config = config;
|
|
24
26
|
this.store = typeof config.store === 'object' && config.store !== null
|
|
@@ -36,6 +38,21 @@ export class CriticalPathEngine {
|
|
|
36
38
|
this.ready = this.seedInitialData(config.initialData);
|
|
37
39
|
}
|
|
38
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Returns a view of this engine that attributes every mutation to `actor`: activity log
|
|
43
|
+
* entries, comment authors, reactions, time entries, attachment uploaders and task reporters.
|
|
44
|
+
* Identity fields supplied in payloads are ignored on the view, so callers cannot claim to be
|
|
45
|
+
* someone else. The view shares the store, plugins and event bus, and does not modify this engine,
|
|
46
|
+
* so it is safe to create one per request.
|
|
47
|
+
*/
|
|
48
|
+
withActor(actor) {
|
|
49
|
+
const scoped = Object.create(this);
|
|
50
|
+
Object.defineProperty(scoped, 'actor', { value: Object.freeze({ ...actor }), enumerable: true });
|
|
51
|
+
return scoped;
|
|
52
|
+
}
|
|
53
|
+
actorIdOr(fallback) {
|
|
54
|
+
return this.actor?.userId ?? fallback;
|
|
55
|
+
}
|
|
39
56
|
async seedInitialData(data) {
|
|
40
57
|
if (data.workflows) {
|
|
41
58
|
for (const wf of data.workflows) {
|
|
@@ -93,7 +110,7 @@ export class CriticalPathEngine {
|
|
|
93
110
|
};
|
|
94
111
|
await this.events.publish(event);
|
|
95
112
|
await this.store.logActivity({
|
|
96
|
-
actorId: 'system',
|
|
113
|
+
actorId: this.actorIdOr('system'),
|
|
97
114
|
action: 'workflow.created',
|
|
98
115
|
details: { name: created.name }
|
|
99
116
|
});
|
|
@@ -117,7 +134,7 @@ export class CriticalPathEngine {
|
|
|
117
134
|
};
|
|
118
135
|
await this.events.publish(event);
|
|
119
136
|
await this.store.logActivity({
|
|
120
|
-
actorId: 'system',
|
|
137
|
+
actorId: this.actorIdOr('system'),
|
|
121
138
|
action: 'workflow.updated',
|
|
122
139
|
details: { name: updated.name }
|
|
123
140
|
});
|
|
@@ -142,7 +159,7 @@ export class CriticalPathEngine {
|
|
|
142
159
|
};
|
|
143
160
|
await this.events.publish(event);
|
|
144
161
|
await this.store.logActivity({
|
|
145
|
-
actorId: 'system',
|
|
162
|
+
actorId: this.actorIdOr('system'),
|
|
146
163
|
action: 'workflow.deleted',
|
|
147
164
|
details: { name: existing.name }
|
|
148
165
|
});
|
|
@@ -209,7 +226,7 @@ export class CriticalPathEngine {
|
|
|
209
226
|
await this.events.publish(event);
|
|
210
227
|
await this.store.logActivity({
|
|
211
228
|
projectId: created.id,
|
|
212
|
-
actorId: project.ownerId || 'system',
|
|
229
|
+
actorId: this.actorIdOr(project.ownerId || 'system'),
|
|
213
230
|
action: 'project.created',
|
|
214
231
|
details: { name: created.name, key: created.key }
|
|
215
232
|
});
|
|
@@ -234,7 +251,7 @@ export class CriticalPathEngine {
|
|
|
234
251
|
await this.events.publish(event);
|
|
235
252
|
await this.store.logActivity({
|
|
236
253
|
projectId: updated.id,
|
|
237
|
-
actorId: 'system',
|
|
254
|
+
actorId: this.actorIdOr('system'),
|
|
238
255
|
action: 'project.updated',
|
|
239
256
|
details: { name: updated.name }
|
|
240
257
|
});
|
|
@@ -271,7 +288,7 @@ export class CriticalPathEngine {
|
|
|
271
288
|
await this.events.publish(event);
|
|
272
289
|
await this.store.logActivity({
|
|
273
290
|
projectId: id,
|
|
274
|
-
actorId: 'system',
|
|
291
|
+
actorId: this.actorIdOr('system'),
|
|
275
292
|
action: 'project.deleted',
|
|
276
293
|
details: { name: existing.name, deletedTaskCount: deletedTaskIds.length }
|
|
277
294
|
});
|
|
@@ -287,6 +304,9 @@ export class CriticalPathEngine {
|
|
|
287
304
|
return this.store.getTask(id);
|
|
288
305
|
}
|
|
289
306
|
async createTask(taskInput) {
|
|
307
|
+
if (this.actor && !taskInput.reporterId) {
|
|
308
|
+
taskInput = { ...taskInput, reporterId: this.actor.userId };
|
|
309
|
+
}
|
|
290
310
|
const processedInput = await this.plugins.runBeforeTaskCreate(taskInput);
|
|
291
311
|
const projectId = processedInput.projectId || taskInput.projectId;
|
|
292
312
|
const project = await this.store.getProject(projectId);
|
|
@@ -361,7 +381,7 @@ export class CriticalPathEngine {
|
|
|
361
381
|
await this.store.logActivity({
|
|
362
382
|
projectId: created.projectId,
|
|
363
383
|
taskId: created.id,
|
|
364
|
-
actorId: created.reporterId || 'system',
|
|
384
|
+
actorId: this.actorIdOr(created.reporterId || 'system'),
|
|
365
385
|
action: 'task.created',
|
|
366
386
|
details: { title: created.title, status: created.status }
|
|
367
387
|
});
|
|
@@ -372,22 +392,26 @@ export class CriticalPathEngine {
|
|
|
372
392
|
const existing = await this.store.getTask(id);
|
|
373
393
|
if (!existing)
|
|
374
394
|
return null;
|
|
395
|
+
// On a withActor view, the scoped actor replaces any identity claimed in the payload.
|
|
396
|
+
// Explicit options from trusted server-side code still take precedence.
|
|
397
|
+
options = options ?? (this.actor ? { actor: this.actor } : undefined);
|
|
398
|
+
const claimed = this.actor ? undefined : updates;
|
|
375
399
|
const actorId = options?.actorId ||
|
|
376
|
-
|
|
400
|
+
claimed?.actorId ||
|
|
377
401
|
options?.actor?.userId ||
|
|
378
|
-
|
|
402
|
+
claimed?.actor?.userId ||
|
|
379
403
|
'system';
|
|
380
404
|
const actorName = options?.actorName ||
|
|
381
|
-
|
|
405
|
+
claimed?.actorName ||
|
|
382
406
|
options?.actor?.username ||
|
|
383
|
-
|
|
407
|
+
claimed?.actor?.username ||
|
|
384
408
|
(actorId === 'system' ? 'System' : undefined);
|
|
385
409
|
const actorType = options?.actorType ||
|
|
386
|
-
|
|
410
|
+
claimed?.actorType ||
|
|
387
411
|
options?.actor?.actorType ||
|
|
388
|
-
|
|
412
|
+
claimed?.actor?.actorType ||
|
|
389
413
|
(actorId === 'system' ? 'system' : 'user');
|
|
390
|
-
const actorObj = options?.actor ||
|
|
414
|
+
const actorObj = options?.actor || claimed?.actor || {
|
|
391
415
|
userId: actorId,
|
|
392
416
|
username: actorName,
|
|
393
417
|
actorType
|
|
@@ -726,7 +750,7 @@ export class CriticalPathEngine {
|
|
|
726
750
|
await this.store.logActivity({
|
|
727
751
|
projectId: downstream.projectId,
|
|
728
752
|
taskId: downstream.id,
|
|
729
|
-
actorId: 'system',
|
|
753
|
+
actorId: this.actorIdOr('system'),
|
|
730
754
|
action: 'task.unblocked',
|
|
731
755
|
details: { unblockedByTaskId: completedTask.id }
|
|
732
756
|
});
|
|
@@ -766,7 +790,7 @@ export class CriticalPathEngine {
|
|
|
766
790
|
await this.store.logActivity({
|
|
767
791
|
projectId: existing.projectId,
|
|
768
792
|
taskId: id,
|
|
769
|
-
actorId: 'system',
|
|
793
|
+
actorId: this.actorIdOr('system'),
|
|
770
794
|
action: 'task.deleted',
|
|
771
795
|
details: { title: existing.title }
|
|
772
796
|
});
|
|
@@ -878,7 +902,7 @@ export class CriticalPathEngine {
|
|
|
878
902
|
}
|
|
879
903
|
const fullEntry = {
|
|
880
904
|
...entry,
|
|
881
|
-
userId: entry.userId || task?.assigneeId || 'system',
|
|
905
|
+
userId: this.actor?.userId || entry.userId || task?.assigneeId || 'system',
|
|
882
906
|
loggedAt: entry.loggedAt
|
|
883
907
|
};
|
|
884
908
|
const created = await this.store.logTime(fullEntry);
|
|
@@ -902,6 +926,9 @@ export class CriticalPathEngine {
|
|
|
902
926
|
return this.store.getComment(id);
|
|
903
927
|
}
|
|
904
928
|
async addComment(comment) {
|
|
929
|
+
if (this.actor) {
|
|
930
|
+
comment = { ...comment, authorId: this.actor.userId, authorType: this.actor.actorType ?? 'user' };
|
|
931
|
+
}
|
|
905
932
|
const mentions = comment.mentions ?? extractMentions(comment.content);
|
|
906
933
|
const created = await this.store.addComment({ ...comment, mentions });
|
|
907
934
|
const now = new Date().toISOString();
|
|
@@ -960,6 +987,8 @@ export class CriticalPathEngine {
|
|
|
960
987
|
return deleted;
|
|
961
988
|
}
|
|
962
989
|
async addCommentReaction(commentId, reaction) {
|
|
990
|
+
if (this.actor)
|
|
991
|
+
reaction = { ...reaction, userId: this.actor.userId };
|
|
963
992
|
const existing = await this.store.getComment(commentId);
|
|
964
993
|
if (!existing)
|
|
965
994
|
return null;
|
|
@@ -1003,6 +1032,8 @@ export class CriticalPathEngine {
|
|
|
1003
1032
|
return updated;
|
|
1004
1033
|
}
|
|
1005
1034
|
async removeCommentReaction(commentId, reaction) {
|
|
1035
|
+
if (this.actor)
|
|
1036
|
+
reaction = { ...reaction, userId: this.actor.userId };
|
|
1006
1037
|
const existing = await this.store.getComment(commentId);
|
|
1007
1038
|
if (!existing)
|
|
1008
1039
|
return null;
|
|
@@ -1041,6 +1072,9 @@ export class CriticalPathEngine {
|
|
|
1041
1072
|
return this.store.getAttachment(id);
|
|
1042
1073
|
}
|
|
1043
1074
|
async createAttachment(attachment) {
|
|
1075
|
+
if (this.actor) {
|
|
1076
|
+
attachment = { ...attachment, uploaderId: this.actor.userId, uploaderType: this.actor.actorType ?? 'user' };
|
|
1077
|
+
}
|
|
1044
1078
|
validateAttachmentUrl(attachment.url);
|
|
1045
1079
|
const created = await this.store.createAttachment(attachment);
|
|
1046
1080
|
const now = new Date().toISOString();
|
|
@@ -1229,7 +1263,7 @@ export class CriticalPathEngine {
|
|
|
1229
1263
|
await this.events.publish(event);
|
|
1230
1264
|
await this.store.logActivity({
|
|
1231
1265
|
projectId: created.projectId,
|
|
1232
|
-
actorId: 'system',
|
|
1266
|
+
actorId: this.actorIdOr('system'),
|
|
1233
1267
|
action: 'deliverable.created',
|
|
1234
1268
|
details: { title: created.title, format: created.format }
|
|
1235
1269
|
});
|
|
@@ -1277,7 +1311,7 @@ export class CriticalPathEngine {
|
|
|
1277
1311
|
await this.events.publish(updateEvent);
|
|
1278
1312
|
await this.store.logActivity({
|
|
1279
1313
|
projectId: updated.projectId,
|
|
1280
|
-
actorId: 'system',
|
|
1314
|
+
actorId: this.actorIdOr('system'),
|
|
1281
1315
|
action: 'deliverable.updated',
|
|
1282
1316
|
details: { title: updated.title, status: updated.status }
|
|
1283
1317
|
});
|
|
@@ -1303,7 +1337,7 @@ export class CriticalPathEngine {
|
|
|
1303
1337
|
await this.events.publish(event);
|
|
1304
1338
|
await this.store.logActivity({
|
|
1305
1339
|
projectId: existing.projectId,
|
|
1306
|
-
actorId: 'system',
|
|
1340
|
+
actorId: this.actorIdOr('system'),
|
|
1307
1341
|
action: 'deliverable.deleted',
|
|
1308
1342
|
details: { title: existing.title }
|
|
1309
1343
|
});
|