@ontologie/mock-server 0.1.0-preview.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 ADDED
@@ -0,0 +1,74 @@
1
+ # @dataforge/mock-server
2
+
3
+ In-process mock server for local SDK development. Exposes `createMockServer()` returning a `createFetch()` function compatible with the global `fetch` API.
4
+
5
+ ## Status — V1.0 (post-Phase-5)
6
+
7
+ | Surface | Status | Notes |
8
+ |---------|--------|-------|
9
+ | Read paths (`ObjectSet.fetchPage`, manifest, types, link-types, graph traverse/neighbors/paths) | ✅ Supported | Returns deterministic fixtures matching staging shapes |
10
+ | Action describe (`GET /api/v1/actions/:key/describe`) | ✅ Supported | Returns stub action descriptor |
11
+ | Calendar / Audit / Forms / Scenarios / Decision-compares (read+write) | ✅ Supported | In-memory state, deterministic round-trips |
12
+ | **V1 REST instance CRUD** (`POST /api/v1/object-types/:apiName/instances`, `PUT/DELETE /api/v1/instances/:id`, `/instances/batch`) | ✅ **Supported (Phase 5)** | In-memory store, version increment on update, soft delete |
13
+ | **ActionBuilder** (`POST /api/v1/actions/:key/dry-run` and `/invoke`) | ✅ **Supported (Phase 5)** | Returns `PlanArtifactV1` + `ActionResult` stubs |
14
+ | Legacy CQRS writes (`POST /api/commands/execute`, `/api/commands/batch`) | ⚠️ Returns 501 `MOCK_LEGACY_CQRS_DEPRECATED` | Defensive guard for legacy callers — current SDK uses REST routes above |
15
+
16
+ ## Usage
17
+
18
+ ```ts
19
+ import { createMockServer } from '@dataforge/mock-server';
20
+ import { createClient } from '@dataforge/sdk-client';
21
+
22
+ const mock = createMockServer();
23
+ globalThis.fetch = mock.createFetch();
24
+
25
+ const client = createClient({
26
+ baseUrl: 'http://mock.dataforge.local',
27
+ apiKey: 'mock-key',
28
+ workspaceId: 'mock-ws',
29
+ });
30
+
31
+ // Reads — fully supported:
32
+ const types = await client.ontology.types.list();
33
+ const result = await client.ontology.Employee.where(e => e.salary.gt(50000)).fetchPage();
34
+
35
+ // Writes — fully supported (Phase 5):
36
+ const employee = await client.ontology.Employee.create({ name: 'Alice', salary: 60000 });
37
+ const updated = await client.ontology.Employee.update(employee.data.id, { salary: 70000 });
38
+ await client.ontology.Employee.delete(employee.data.id);
39
+
40
+ // Batch operations:
41
+ const batch = await client.ontology.Employee.batchCreate([
42
+ { name: 'Bob' },
43
+ { name: 'Charlie' },
44
+ ]);
45
+
46
+ // Actions:
47
+ const plan = await client.actions.on('Contract').action('approve').target('con-1').dryRun();
48
+ const result2 = await client.actions.on('Contract').action('approve').applyPlan(plan.planId);
49
+ ```
50
+
51
+ ## Phase 5 implementation details (closes #1076)
52
+
53
+ Phase 5 of epic [#1077](https://github.com/growthsystemes/dataforge/issues/1077) wires real handlers for V1 REST routes that the SDK uses post-Phase-4 (PR #1099). Pre-Phase-5 these returned 501. Now :
54
+
55
+ | Route | Behavior |
56
+ |-------|----------|
57
+ | `POST /api/v1/object-types/:apiName/instances` | Stores in `MockServer.objects` Map, returns `{success, data: {id, object_type_id, data, version: 1, status: 'active', ...}}` |
58
+ | `POST /api/v1/object-types/:apiName/instances/batch` | Iterates `body.updates[]`, dispatches by op `type`, returns `{succeeded, failed, results[]}` |
59
+ | `PUT /api/v1/instances/:id` | Cross-type lookup, version increment, returns updated instance. 404 if not found |
60
+ | `DELETE /api/v1/instances/:id` | Cross-type lookup, removes from store, returns `{success, data: {id, status: 'deleted'}}`. 404 if not found |
61
+ | `POST /api/v1/actions/:key/dry-run` | Returns minimal `PlanArtifactV1` stub with `canApply: true`, signature placeholders |
62
+ | `POST /api/v1/actions/:key/invoke` | Returns `ActionResult` stub with `runId`, `actionKey`, empty `editedRefs` + `blockedSideEffects` |
63
+
64
+ ## Legacy CQRS writes (501 mitigation)
65
+
66
+ `POST /api/commands/execute` and `/api/commands/batch` now return `MOCK_LEGACY_CQRS_DEPRECATED` 501 with a message explaining that the SDK uses REST routes post-Phase-4. This is a defensive guard for legacy callers. Current SDK code does not hit these paths.
67
+
68
+ ## Cross-references
69
+
70
+ - Epic : [#1077 Track G-bis](https://github.com/growthsystemes/dataforge/issues/1077)
71
+ - Audit : [`docs/quality/COMMAND-PRIMITIVE-AUDIT-2026-05-01.md`](https://github.com/growthsystemes/dataforge/blob/staging/docs/quality/COMMAND-PRIMITIVE-AUDIT-2026-05-01.md)
72
+ - Phase 4 (root cause fix) : [#1099](https://github.com/growthsystemes/dataforge/pull/1099)
73
+ - Issue : [#1076](https://github.com/growthsystemes/dataforge/issues/1076) — closed by this PR
74
+ - Parity test : [`src/server.parity.test.ts`](src/server.parity.test.ts) — 23 tests covering reads + writes + actions + legacy 501 guard
@@ -0,0 +1,267 @@
1
+ /**
2
+ * Default test fixtures for the mock server.
3
+ *
4
+ * Ontology data mirrors the shared sample-ontology seed (5 types, ~30 props, 8 links).
5
+ * SOT: sdk/sample-ontology/seed.ts — keep in sync.
6
+ *
7
+ * Covers M1-M7 SDK features: ontology objects, dashboard, calendar,
8
+ * audit, forms, scenarios, and decision-compare.
9
+ */
10
+ export interface MockObject {
11
+ $primaryKey: string;
12
+ $objectType: string;
13
+ $version: number;
14
+ [key: string]: unknown;
15
+ }
16
+ export interface MockEdge {
17
+ sourceKey: string;
18
+ targetKey: string;
19
+ linkType: string;
20
+ }
21
+ export declare const defaultFixtures: {
22
+ objectTypes: {
23
+ apiName: string;
24
+ displayName: string;
25
+ description: string;
26
+ properties: {
27
+ apiName: string;
28
+ displayName: string;
29
+ dataType: string;
30
+ required: boolean;
31
+ }[];
32
+ }[];
33
+ linkTypes: ({
34
+ apiName: string;
35
+ displayName: string;
36
+ sourceTypeApiName: string;
37
+ targetTypeApiName: string;
38
+ cardinality: "1:N";
39
+ relationshipType: string;
40
+ inverseName: string;
41
+ properties: never[];
42
+ } | {
43
+ apiName: string;
44
+ displayName: string;
45
+ sourceTypeApiName: string;
46
+ targetTypeApiName: string;
47
+ cardinality: "N:1";
48
+ relationshipType: string;
49
+ inverseName: string;
50
+ properties: never[];
51
+ } | {
52
+ apiName: string;
53
+ displayName: string;
54
+ sourceTypeApiName: string;
55
+ targetTypeApiName: string;
56
+ cardinality: "N:N";
57
+ relationshipType: string;
58
+ inverseName: string;
59
+ properties: never[];
60
+ })[];
61
+ objects: Map<string, MockObject[]>;
62
+ edges: MockEdge[];
63
+ dashboardKpis: {
64
+ name: string;
65
+ value: number;
66
+ category: string;
67
+ }[];
68
+ dashboardStats: {
69
+ totalNodes: number;
70
+ totalEdges: number;
71
+ activeWorkflows: number;
72
+ agentConversations24h: number;
73
+ kpis: {
74
+ name: string;
75
+ value: number;
76
+ unit: string;
77
+ }[];
78
+ };
79
+ dashboardTimeseries: {
80
+ data: {
81
+ timestamp: string;
82
+ value: number;
83
+ }[];
84
+ };
85
+ calendarEvents: ({
86
+ id: string;
87
+ calendarId: string;
88
+ title: string;
89
+ startTime: string;
90
+ endTime: string;
91
+ allDay: boolean;
92
+ recurrence: null;
93
+ createdAt: string;
94
+ } | {
95
+ id: string;
96
+ calendarId: string;
97
+ title: string;
98
+ startTime: string;
99
+ endTime: string;
100
+ allDay: boolean;
101
+ recurrence: string;
102
+ createdAt: string;
103
+ })[];
104
+ auditEvents: ({
105
+ id: string;
106
+ eventType: string;
107
+ actor: {
108
+ type: string;
109
+ id: string;
110
+ name: string;
111
+ };
112
+ entityType: string;
113
+ entityId: string;
114
+ changes: {
115
+ field: string;
116
+ from: null;
117
+ to: string;
118
+ }[];
119
+ timestamp: string;
120
+ workspaceId: string;
121
+ } | {
122
+ id: string;
123
+ eventType: string;
124
+ actor: {
125
+ type: string;
126
+ id: string;
127
+ name: string;
128
+ };
129
+ entityType: string;
130
+ entityId: string;
131
+ changes: {
132
+ field: string;
133
+ from: string;
134
+ to: string;
135
+ }[];
136
+ timestamp: string;
137
+ workspaceId: string;
138
+ })[];
139
+ forms: ({
140
+ id: string;
141
+ name: string;
142
+ description: string;
143
+ status: string;
144
+ fields: ({
145
+ id: string;
146
+ type: string;
147
+ label: string;
148
+ required: boolean;
149
+ options?: undefined;
150
+ } | {
151
+ id: string;
152
+ type: string;
153
+ label: string;
154
+ required: boolean;
155
+ options: string[];
156
+ })[];
157
+ submitCount: number;
158
+ createdAt: string;
159
+ updatedAt: string;
160
+ } | {
161
+ id: string;
162
+ name: string;
163
+ description: string;
164
+ status: string;
165
+ fields: ({
166
+ id: string;
167
+ type: string;
168
+ label: string;
169
+ required: boolean;
170
+ validation?: undefined;
171
+ } | {
172
+ id: string;
173
+ type: string;
174
+ label: string;
175
+ required: boolean;
176
+ validation: {
177
+ min: number;
178
+ max: number;
179
+ };
180
+ })[];
181
+ submitCount: number;
182
+ createdAt: string;
183
+ updatedAt: string;
184
+ })[];
185
+ formSubmissions: {
186
+ id: string;
187
+ formId: string;
188
+ data: {
189
+ 'Full Name': string;
190
+ Email: string;
191
+ Department: string;
192
+ };
193
+ submittedAt: string;
194
+ }[];
195
+ scenarios: ({
196
+ id: string;
197
+ name: string;
198
+ description: string;
199
+ status: string;
200
+ baseVersion: number;
201
+ results: {
202
+ affectedInstances: number;
203
+ totalDelta: number;
204
+ };
205
+ createdBy: string;
206
+ createdAt: string;
207
+ updatedAt: string;
208
+ } | {
209
+ id: string;
210
+ name: string;
211
+ description: string;
212
+ status: string;
213
+ baseVersion: number;
214
+ results: {
215
+ affectedInstances?: undefined;
216
+ totalDelta?: undefined;
217
+ };
218
+ createdBy: string;
219
+ createdAt: string;
220
+ updatedAt: string;
221
+ })[];
222
+ decisionCompareEstimate: {
223
+ estimatedTokens: number;
224
+ estimatedCost: number;
225
+ proofLevel: string;
226
+ estimatedDurationMs: number;
227
+ dimensions: {
228
+ name: string;
229
+ weight: number;
230
+ }[];
231
+ };
232
+ decisionCompareSubmit: {
233
+ runId: string;
234
+ status: string;
235
+ createdAt: string;
236
+ };
237
+ decisionCompareReport: {
238
+ runId: string;
239
+ version: number;
240
+ verdict: string;
241
+ confidence: number;
242
+ summary: string;
243
+ dimensions: {
244
+ name: string;
245
+ optionA: number;
246
+ optionB: number;
247
+ winner: string;
248
+ }[];
249
+ sealedAt: string;
250
+ integrityHash: string;
251
+ };
252
+ decisionCompareEvidence: {
253
+ runId: string;
254
+ claims: {
255
+ id: string;
256
+ text: string;
257
+ supported: boolean;
258
+ sources: {
259
+ type: string;
260
+ reference: string;
261
+ confidence: number;
262
+ }[];
263
+ }[];
264
+ integrityHash: string;
265
+ };
266
+ };
267
+ //# sourceMappingURL=fixtures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../src/fixtures.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAsJD,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2N3B,CAAC"}