@company-semantics/contracts 93.0.0 → 93.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -4
- package/src/__tests__/resource-keys.test.ts +2 -0
- package/src/api/generated-spec-hash.ts +2 -2
- package/src/api/generated.ts +183 -0
- package/src/chat/__tests__/page-context.test.ts +22 -43
- package/src/chat/__tests__/runtime-profile.test.ts +20 -44
- package/src/generated/openapi-routes.ts +2 -0
- package/src/resource-key-tables.ts +2 -0
- package/src/resource-key-types.ts +6 -0
- package/src/resource-keys.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@company-semantics/contracts",
|
|
3
|
-
"version": "93.
|
|
3
|
+
"version": "93.2.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -168,7 +168,7 @@
|
|
|
168
168
|
"pnpm": {
|
|
169
169
|
"overrides": {
|
|
170
170
|
"brace-expansion@<5.0.11": ">=5.0.11",
|
|
171
|
-
"smol-toml@<1.
|
|
171
|
+
"smol-toml@<1.9.0": ">=1.9.0",
|
|
172
172
|
"minimatch@<10.2.3": ">=10.2.3",
|
|
173
173
|
"nanoid@<3.3.18": ">=3.3.18",
|
|
174
174
|
"js-yaml@>=4.0.0 <4.3.2": ">=4.3.2 <5.0.0",
|
|
@@ -181,7 +181,8 @@
|
|
|
181
181
|
"postcss@<8.5.23": ">=8.5.23",
|
|
182
182
|
"source-map-js@<1.2.2": ">=1.2.2",
|
|
183
183
|
"markdown-it@<14.2.0": ">=14.2.0",
|
|
184
|
-
"@humanfs/node@<0.16.8": ">=0.16.8 <0.17.0"
|
|
184
|
+
"@humanfs/node@<0.16.8": ">=0.16.8 <0.17.0",
|
|
185
|
+
"katex@<0.18.2": ">=0.18.2 <0.19.0"
|
|
185
186
|
}
|
|
186
187
|
},
|
|
187
188
|
"lint-staged": {
|
|
@@ -189,5 +190,5 @@
|
|
|
189
190
|
"*.md": "markdownlint-cli2",
|
|
190
191
|
"package.json": "node -e \"JSON.parse(require('fs').readFileSync('package.json'))\""
|
|
191
192
|
},
|
|
192
|
-
"securityRequirementsVersion": "
|
|
193
|
+
"securityRequirementsVersion": "71a26f10642b9fc598f6da99c75200fd174ebd0e6a9e32437a3f1b245e906792"
|
|
193
194
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// AUTO-GENERATED — do not edit. Run pnpm generate:spec-hash to regenerate.
|
|
2
|
-
export const SPEC_HASH = '
|
|
3
|
-
export const SPEC_HASH_FULL = '
|
|
2
|
+
export const SPEC_HASH = 'a57011cbdcd2' as const;
|
|
3
|
+
export const SPEC_HASH_FULL = 'a57011cbdcd2d9be32d330cc97eb33954aaa55d6936e0f644496644e0bb66e11' as const;
|
package/src/api/generated.ts
CHANGED
|
@@ -3911,6 +3911,40 @@ export interface paths {
|
|
|
3911
3911
|
patch?: never;
|
|
3912
3912
|
trace?: never;
|
|
3913
3913
|
};
|
|
3914
|
+
"/api/factory/lineage": {
|
|
3915
|
+
parameters: {
|
|
3916
|
+
query?: never;
|
|
3917
|
+
header?: never;
|
|
3918
|
+
path?: never;
|
|
3919
|
+
cookie?: never;
|
|
3920
|
+
};
|
|
3921
|
+
/** Read change lineage: each release with its commits, PRDs, workers, run and health */
|
|
3922
|
+
get: operations["factoryLineage"];
|
|
3923
|
+
put?: never;
|
|
3924
|
+
post?: never;
|
|
3925
|
+
delete?: never;
|
|
3926
|
+
options?: never;
|
|
3927
|
+
head?: never;
|
|
3928
|
+
patch?: never;
|
|
3929
|
+
trace?: never;
|
|
3930
|
+
};
|
|
3931
|
+
"/api/factory/production": {
|
|
3932
|
+
parameters: {
|
|
3933
|
+
query?: never;
|
|
3934
|
+
header?: never;
|
|
3935
|
+
path?: never;
|
|
3936
|
+
cookie?: never;
|
|
3937
|
+
};
|
|
3938
|
+
/** Read the production view: each production signal with its verdict, age, staleness and breach run */
|
|
3939
|
+
get: operations["factoryProduction"];
|
|
3940
|
+
put?: never;
|
|
3941
|
+
post?: never;
|
|
3942
|
+
delete?: never;
|
|
3943
|
+
options?: never;
|
|
3944
|
+
head?: never;
|
|
3945
|
+
patch?: never;
|
|
3946
|
+
trace?: never;
|
|
3947
|
+
};
|
|
3914
3948
|
"/api/factory/quality/changes": {
|
|
3915
3949
|
parameters: {
|
|
3916
3950
|
query?: never;
|
|
@@ -6893,6 +6927,13 @@ export interface components {
|
|
|
6893
6927
|
requiredScope?: string;
|
|
6894
6928
|
};
|
|
6895
6929
|
};
|
|
6930
|
+
workspace?: {
|
|
6931
|
+
manageSettings: {
|
|
6932
|
+
/** @enum {string} */
|
|
6933
|
+
state: "allowed" | "blocked";
|
|
6934
|
+
requiredScope?: string;
|
|
6935
|
+
};
|
|
6936
|
+
};
|
|
6896
6937
|
};
|
|
6897
6938
|
chatMentions: boolean;
|
|
6898
6939
|
chatMultiParty: boolean;
|
|
@@ -9253,6 +9294,11 @@ export interface components {
|
|
|
9253
9294
|
};
|
|
9254
9295
|
eventTimestamp: string;
|
|
9255
9296
|
}[];
|
|
9297
|
+
pausedAuth?: {
|
|
9298
|
+
since: string;
|
|
9299
|
+
lane: number;
|
|
9300
|
+
reason: string | null;
|
|
9301
|
+
} | null;
|
|
9256
9302
|
}[];
|
|
9257
9303
|
};
|
|
9258
9304
|
FactorySnapshotResponse: {
|
|
@@ -9389,6 +9435,72 @@ export interface components {
|
|
|
9389
9435
|
[key: string]: unknown;
|
|
9390
9436
|
} | null;
|
|
9391
9437
|
};
|
|
9438
|
+
FactoryLineageResponse: {
|
|
9439
|
+
releases: {
|
|
9440
|
+
key: string;
|
|
9441
|
+
manifestId: string | null;
|
|
9442
|
+
stationId: string;
|
|
9443
|
+
/** @enum {string} */
|
|
9444
|
+
status: "in_progress" | "applied" | "rolled_back";
|
|
9445
|
+
intendedAt: string | null;
|
|
9446
|
+
appliedAt: string | null;
|
|
9447
|
+
durationMs: number | null;
|
|
9448
|
+
surfaces: string[];
|
|
9449
|
+
shas: {
|
|
9450
|
+
[key: string]: string;
|
|
9451
|
+
} | null;
|
|
9452
|
+
run: {
|
|
9453
|
+
id: string;
|
|
9454
|
+
attempt: number;
|
|
9455
|
+
repository: string;
|
|
9456
|
+
url: string;
|
|
9457
|
+
} | null;
|
|
9458
|
+
health: {
|
|
9459
|
+
/** @enum {string} */
|
|
9460
|
+
releaseInvariant: "ok" | "failed" | "unproven" | "unknown";
|
|
9461
|
+
/** @enum {string} */
|
|
9462
|
+
windowMetric: "ok" | "failed" | "unproven" | "unknown";
|
|
9463
|
+
/** @enum {string} */
|
|
9464
|
+
pointProbe: "ok" | "failed" | "unproven" | "unknown";
|
|
9465
|
+
rolledBack: boolean;
|
|
9466
|
+
} | null;
|
|
9467
|
+
commitsRecorded: boolean;
|
|
9468
|
+
changesTruncated: boolean;
|
|
9469
|
+
changes: {
|
|
9470
|
+
repo: string;
|
|
9471
|
+
sha: string;
|
|
9472
|
+
prdId: string | null;
|
|
9473
|
+
pr: number | null;
|
|
9474
|
+
worker: {
|
|
9475
|
+
stationId: string;
|
|
9476
|
+
executorId: string;
|
|
9477
|
+
} | null;
|
|
9478
|
+
}[];
|
|
9479
|
+
}[];
|
|
9480
|
+
};
|
|
9481
|
+
FactoryProductionResponse: {
|
|
9482
|
+
generatedAt: string;
|
|
9483
|
+
signals: {
|
|
9484
|
+
/** @enum {string} */
|
|
9485
|
+
signal: "api_availability" | "http_5xx" | "latency_p95" | "ecs_tasks" | "database" | "deploy_lag" | "app_host_edge" | "chat_success" | "ingestion_backlog" | "release_safety";
|
|
9486
|
+
/** @enum {string} */
|
|
9487
|
+
source: "hosted" | "computed";
|
|
9488
|
+
targetText: string;
|
|
9489
|
+
cadenceMinutes: number;
|
|
9490
|
+
/** @enum {string} */
|
|
9491
|
+
verdict: "ok" | "breach" | "unavailable";
|
|
9492
|
+
value: number | null;
|
|
9493
|
+
target: number | null;
|
|
9494
|
+
unit: string | null;
|
|
9495
|
+
detail: string | null;
|
|
9496
|
+
windowMinutes: number | null;
|
|
9497
|
+
sampledAt: string | null;
|
|
9498
|
+
ageSeconds: number | null;
|
|
9499
|
+
stale: boolean;
|
|
9500
|
+
consecutiveBreaches: number;
|
|
9501
|
+
passRate30d: number | null;
|
|
9502
|
+
}[];
|
|
9503
|
+
};
|
|
9392
9504
|
CreateQualityChangeResponse: {
|
|
9393
9505
|
/** Format: uuid */
|
|
9394
9506
|
planId: string;
|
|
@@ -17897,6 +18009,77 @@ export interface operations {
|
|
|
17897
18009
|
};
|
|
17898
18010
|
};
|
|
17899
18011
|
};
|
|
18012
|
+
factoryLineage: {
|
|
18013
|
+
parameters: {
|
|
18014
|
+
query?: {
|
|
18015
|
+
limit?: number;
|
|
18016
|
+
prdId?: string;
|
|
18017
|
+
};
|
|
18018
|
+
header?: never;
|
|
18019
|
+
path?: never;
|
|
18020
|
+
cookie?: never;
|
|
18021
|
+
};
|
|
18022
|
+
requestBody?: never;
|
|
18023
|
+
responses: {
|
|
18024
|
+
/** @description Lineage records, newest release first */
|
|
18025
|
+
200: {
|
|
18026
|
+
headers: {
|
|
18027
|
+
[name: string]: unknown;
|
|
18028
|
+
};
|
|
18029
|
+
content: {
|
|
18030
|
+
"application/json": components["schemas"]["FactoryLineageResponse"];
|
|
18031
|
+
};
|
|
18032
|
+
};
|
|
18033
|
+
/** @description Not authenticated */
|
|
18034
|
+
401: {
|
|
18035
|
+
headers: {
|
|
18036
|
+
[name: string]: unknown;
|
|
18037
|
+
};
|
|
18038
|
+
content?: never;
|
|
18039
|
+
};
|
|
18040
|
+
/** @description Not an internal admin */
|
|
18041
|
+
403: {
|
|
18042
|
+
headers: {
|
|
18043
|
+
[name: string]: unknown;
|
|
18044
|
+
};
|
|
18045
|
+
content?: never;
|
|
18046
|
+
};
|
|
18047
|
+
};
|
|
18048
|
+
};
|
|
18049
|
+
factoryProduction: {
|
|
18050
|
+
parameters: {
|
|
18051
|
+
query?: never;
|
|
18052
|
+
header?: never;
|
|
18053
|
+
path?: never;
|
|
18054
|
+
cookie?: never;
|
|
18055
|
+
};
|
|
18056
|
+
requestBody?: never;
|
|
18057
|
+
responses: {
|
|
18058
|
+
/** @description The ten production signals */
|
|
18059
|
+
200: {
|
|
18060
|
+
headers: {
|
|
18061
|
+
[name: string]: unknown;
|
|
18062
|
+
};
|
|
18063
|
+
content: {
|
|
18064
|
+
"application/json": components["schemas"]["FactoryProductionResponse"];
|
|
18065
|
+
};
|
|
18066
|
+
};
|
|
18067
|
+
/** @description Not authenticated */
|
|
18068
|
+
401: {
|
|
18069
|
+
headers: {
|
|
18070
|
+
[name: string]: unknown;
|
|
18071
|
+
};
|
|
18072
|
+
content?: never;
|
|
18073
|
+
};
|
|
18074
|
+
/** @description Not an internal admin */
|
|
18075
|
+
403: {
|
|
18076
|
+
headers: {
|
|
18077
|
+
[name: string]: unknown;
|
|
18078
|
+
};
|
|
18079
|
+
content?: never;
|
|
18080
|
+
};
|
|
18081
|
+
};
|
|
18082
|
+
};
|
|
17900
18083
|
createQualityChange: {
|
|
17901
18084
|
parameters: {
|
|
17902
18085
|
query?: never;
|
|
@@ -23,13 +23,21 @@
|
|
|
23
23
|
* no-sibling-imports invariant intact (the same pattern as
|
|
24
24
|
* runtime-profile.test.ts).
|
|
25
25
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
26
|
+
* Where the app is read from: `resolveSibling` (tests/workspace-sibling.ts), the
|
|
27
|
+
* workspace's sibling rule (ci ADR-CI-276): this session's app worktree when
|
|
28
|
+
* the session holds one, else app's committed origin/main; never a primary's
|
|
29
|
+
* working tree. It used to probe `<workspace>/company-semantics-app` (the
|
|
30
|
+
* PRIMARY) and `../company-semantics-app` from cwd for
|
|
31
|
+
* `src/platform/route-parser.ts`, a path app has since moved to
|
|
32
|
+
* `src/lib/nav/route-parser.ts`, so it skipped everywhere (ci ADR-CI-294
|
|
33
|
+
* follow-up). A moved file now fails the read.
|
|
34
|
+
*
|
|
35
|
+
* Inside the workspace a missing or unreadable app FAILS this file. The parity
|
|
36
|
+
* tests skip, and the inverted marker test says why, only in a standalone
|
|
37
|
+
* clone (no other company-semantics-* checkout beside it): contracts consumed
|
|
38
|
+
* from npm, or contracts CI, which by design has no app checkout because
|
|
39
|
+
* contracts is the root of the dependency tree.
|
|
30
40
|
*/
|
|
31
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
32
|
-
import { resolve, sep } from "node:path";
|
|
33
41
|
import { describe, it, expect } from "vitest";
|
|
34
42
|
import {
|
|
35
43
|
ChatPageContextSchema,
|
|
@@ -37,6 +45,7 @@ import {
|
|
|
37
45
|
CHAT_PAGE_SCOPES,
|
|
38
46
|
CHAT_PAGE_ENTITY_TYPES,
|
|
39
47
|
} from "../schemas.js";
|
|
48
|
+
import { resolveSibling } from "../../../tests/workspace-sibling.js";
|
|
40
49
|
|
|
41
50
|
// ---------------------------------------------------------------------------
|
|
42
51
|
// Fixtures
|
|
@@ -56,52 +65,22 @@ const A_DOCUMENT_BODY = `# Q3 plan\n${"Revenue grew. ".repeat(200)}`;
|
|
|
56
65
|
// Locating the app checkout that governs this run
|
|
57
66
|
// ---------------------------------------------------------------------------
|
|
58
67
|
|
|
59
|
-
|
|
60
|
-
* Probed in order:
|
|
61
|
-
* 1. The app worktree mirroring this one. Ralph checks the same branch of
|
|
62
|
-
* every repo out at the same relative path, so a contracts worktree has an
|
|
63
|
-
* app worktree beside it carrying the branch's route grammar. The app MAIN
|
|
64
|
-
* checkout sits on another branch entirely, and comparing against it would
|
|
65
|
-
* report drift for a value this branch already corrected.
|
|
66
|
-
* 2. The app main checkout in the same workspace.
|
|
67
|
-
* 3. The plain sibling guess, for a non-worktree local dev layout.
|
|
68
|
-
*/
|
|
69
|
-
function resolveAppRoot(): string | undefined {
|
|
70
|
-
const candidates: string[] = [];
|
|
71
|
-
|
|
72
|
-
const segments = process.cwd().split(sep);
|
|
73
|
-
const contractsIdx = segments.lastIndexOf("company-semantics-contracts");
|
|
74
|
-
if (contractsIdx !== -1) {
|
|
75
|
-
const workspaceRoot = segments.slice(0, contractsIdx).join(sep);
|
|
76
|
-
const worktreeSuffix = segments.slice(contractsIdx + 1);
|
|
77
|
-
const appRoot = resolve(workspaceRoot, "company-semantics-app");
|
|
78
|
-
if (worktreeSuffix.length > 0) {
|
|
79
|
-
candidates.push(resolve(appRoot, ...worktreeSuffix));
|
|
80
|
-
}
|
|
81
|
-
candidates.push(appRoot);
|
|
82
|
-
}
|
|
83
|
-
candidates.push(resolve(process.cwd(), "..", "company-semantics-app"));
|
|
84
|
-
|
|
85
|
-
return candidates.find((root) =>
|
|
86
|
-
existsSync(resolve(root, "src", "platform", "route-parser.ts")),
|
|
87
|
-
);
|
|
88
|
-
}
|
|
68
|
+
const APP_ROUTE_PARSER = "src/lib/nav/route-parser.ts";
|
|
89
69
|
|
|
90
|
-
|
|
91
|
-
|
|
70
|
+
// Throws (failing this file loudly) inside the workspace when the app cannot
|
|
71
|
+
// be resolved; null only in a standalone clone.
|
|
72
|
+
const app = await resolveSibling("company-semantics-app");
|
|
73
|
+
const appAvailable = app !== null;
|
|
92
74
|
|
|
93
75
|
/** The body of the app's `export type Route = ...;` union, as a string. */
|
|
94
76
|
function appRouteUnionSource(): string {
|
|
95
|
-
const source =
|
|
96
|
-
resolve(APP_ROOT!, "src", "platform", "route-parser.ts"),
|
|
97
|
-
"utf8",
|
|
98
|
-
);
|
|
77
|
+
const source = app!.read(APP_ROUTE_PARSER);
|
|
99
78
|
// Terminated by the blank line after the union, because `;` also ends every
|
|
100
79
|
// member field inside it.
|
|
101
80
|
const match = source.match(/export type Route =([\s\S]*?);\r?\n\r?\n/);
|
|
102
81
|
if (!match?.[1]) {
|
|
103
82
|
throw new Error(
|
|
104
|
-
|
|
83
|
+
`Could not locate the \`Route\` union in app ${APP_ROUTE_PARSER}. ` +
|
|
105
84
|
"If the declaration was renamed or restructured, update this test — do " +
|
|
106
85
|
"NOT delete it, or the view vocabulary can drift out of step unseen.",
|
|
107
86
|
);
|
|
@@ -18,59 +18,35 @@
|
|
|
18
18
|
* imports, keeping the contracts no-sibling-imports invariant intact (the
|
|
19
19
|
* same pattern as tests/org/reserved-slug-roundtrip.test.ts).
|
|
20
20
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
21
|
+
* Where the backend is read from: `resolveSibling` (tests/workspace-sibling.ts),
|
|
22
|
+
* the workspace's sibling rule (ci ADR-CI-276): this session's backend worktree
|
|
23
|
+
* when the session holds one, else backend's committed origin/main; never a
|
|
24
|
+
* primary's working tree, which may hold another session's uncommitted work.
|
|
25
|
+
* It used to probe `<workspace>/company-semantics-backend` (the PRIMARY) and
|
|
26
|
+
* `../company-semantics-backend` from cwd (ci ADR-CI-294 follow-up).
|
|
27
|
+
*
|
|
28
|
+
* Inside the workspace a missing or unreadable backend FAILS this file. The
|
|
29
|
+
* parity tests skip, and the inverted marker test says why, only in a
|
|
30
|
+
* standalone clone (no other company-semantics-* checkout beside it): contracts
|
|
31
|
+
* consumed from npm, or contracts CI, which by design has no backend checkout
|
|
32
|
+
* because contracts is the root of the dependency tree. Drift introduced on the
|
|
33
|
+
* backend side is therefore NOT gated by contracts CI; it is caught here in a
|
|
34
|
+
* workspace checkout.
|
|
27
35
|
*/
|
|
28
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
29
|
-
import { resolve, sep } from "node:path";
|
|
30
36
|
import { describe, it, expect } from "vitest";
|
|
31
37
|
import {
|
|
32
38
|
CHAT_RUNTIME_PROFILES,
|
|
33
39
|
DEFAULT_CHAT_RUNTIME_PROFILE,
|
|
34
40
|
} from "../runtime-profile.js";
|
|
41
|
+
import { resolveSibling } from "../../../tests/workspace-sibling.js";
|
|
35
42
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
* 1. The backend worktree mirroring this one. Ralph checks the same branch of
|
|
41
|
-
* every repo out at the same relative path, so a contracts worktree has a
|
|
42
|
-
* backend worktree beside it carrying the branch's constants. The backend
|
|
43
|
-
* MAIN checkout sits on another branch entirely, and comparing against it
|
|
44
|
-
* would report drift for a value this branch already corrected.
|
|
45
|
-
* 2. The backend main checkout in the same workspace.
|
|
46
|
-
* 3. The plain sibling guess, for a non-worktree local dev layout.
|
|
47
|
-
*/
|
|
48
|
-
function resolveBackendRoot(): string | undefined {
|
|
49
|
-
const candidates: string[] = [];
|
|
50
|
-
|
|
51
|
-
const segments = process.cwd().split(sep);
|
|
52
|
-
const contractsIdx = segments.lastIndexOf("company-semantics-contracts");
|
|
53
|
-
if (contractsIdx !== -1) {
|
|
54
|
-
const workspaceRoot = segments.slice(0, contractsIdx).join(sep);
|
|
55
|
-
const worktreeSuffix = segments.slice(contractsIdx + 1);
|
|
56
|
-
const backendRoot = resolve(workspaceRoot, "company-semantics-backend");
|
|
57
|
-
if (worktreeSuffix.length > 0) {
|
|
58
|
-
candidates.push(resolve(backendRoot, ...worktreeSuffix));
|
|
59
|
-
}
|
|
60
|
-
candidates.push(backendRoot);
|
|
61
|
-
}
|
|
62
|
-
candidates.push(resolve(process.cwd(), "..", "company-semantics-backend"));
|
|
63
|
-
|
|
64
|
-
return candidates.find((root) =>
|
|
65
|
-
existsSync(resolve(root, "src", "chat", "orchestrator", "factory.ts")),
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const BACKEND_ROOT = resolveBackendRoot();
|
|
70
|
-
const backendAvailable = BACKEND_ROOT !== undefined;
|
|
43
|
+
// Throws (failing this file loudly) inside the workspace when the backend
|
|
44
|
+
// cannot be resolved; null only in a standalone clone.
|
|
45
|
+
const backend = await resolveSibling("company-semantics-backend");
|
|
46
|
+
const backendAvailable = backend !== null;
|
|
71
47
|
|
|
72
48
|
function readBackendSource(...relative: string[]): string {
|
|
73
|
-
return
|
|
49
|
+
return backend!.read(relative.join("/"));
|
|
74
50
|
}
|
|
75
51
|
|
|
76
52
|
/** Extract the single capture of `pattern`, or explain what moved. */
|
|
@@ -95,6 +95,8 @@ export const openApiRoutes = {
|
|
|
95
95
|
'/api/executions/{executionId}/undo': ['POST'],
|
|
96
96
|
'/api/factory/floor': ['GET'],
|
|
97
97
|
'/api/factory/kpis': ['GET'],
|
|
98
|
+
'/api/factory/lineage': ['GET'],
|
|
99
|
+
'/api/factory/production': ['GET'],
|
|
98
100
|
'/api/factory/quality/changes': ['POST'],
|
|
99
101
|
'/api/factory/quality/corpus': ['GET'],
|
|
100
102
|
'/api/factory/quality/deployments': ['POST'],
|
|
@@ -161,6 +161,8 @@ export const SYSTEM_SCOPED_TYPES = [
|
|
|
161
161
|
"factoryFloor",
|
|
162
162
|
"factorySnapshot",
|
|
163
163
|
"factoryKpis",
|
|
164
|
+
"factoryLineage",
|
|
165
|
+
"factoryProduction",
|
|
164
166
|
] as const satisfies readonly SystemScopedType[];
|
|
165
167
|
|
|
166
168
|
/** Every literal `fromQueryKey` can route, across all five tables. */
|
|
@@ -157,6 +157,12 @@ export type ResourceKey =
|
|
|
157
157
|
// `useResource` disables a query whose `toQueryKey` throws, the panel it backs
|
|
158
158
|
// never fetched at all. An unregistered key is not a stale read, it is no read.
|
|
159
159
|
| { type: "factoryKpis"; scope: "system" }
|
|
160
|
+
// Change lineage over the release ledger (ADR-CONTRACTS-222, backend
|
|
161
|
+
// ADR-BE-926): each release with its commits, PRDs, workers, run and health.
|
|
162
|
+
| { type: "factoryLineage"; scope: "system" }
|
|
163
|
+
// The production view (ADR-CONTRACTS-224, backend ADR-BE-929): the ten
|
|
164
|
+
// production signals with verdict, age, staleness and breach run.
|
|
165
|
+
| { type: "factoryProduction"; scope: "system" }
|
|
160
166
|
// Everything awaiting the viewer's decision, across every domain
|
|
161
167
|
// (ADR-CONT-104). ORG-scoped, not user-scoped, even though the content is
|
|
162
168
|
// per-viewer: the bucket differs per org, so a user-keyed entry would serve
|
package/src/resource-keys.ts
CHANGED
|
@@ -137,6 +137,8 @@ export function toQueryKey(key: ResourceKey): readonly string[] {
|
|
|
137
137
|
case "factoryFloor":
|
|
138
138
|
case "factorySnapshot":
|
|
139
139
|
case "factoryKpis":
|
|
140
|
+
case "factoryLineage":
|
|
141
|
+
case "factoryProduction":
|
|
140
142
|
return [key.type, key.scope] as const;
|
|
141
143
|
|
|
142
144
|
default: {
|