@company-semantics/contracts 0.104.0 → 0.105.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 +6 -1
- package/src/api/generated.ts +125 -4
- package/src/errors/index.ts +37 -0
- package/src/index.ts +12 -0
- package/src/security/index.ts +2 -0
- package/src/security/secret.ts +47 -0
- package/src/types/analytics.ts +14 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@company-semantics/contracts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.105.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -101,6 +101,11 @@
|
|
|
101
101
|
"vitest": "^4.0.16",
|
|
102
102
|
"yaml": "^2.8.3"
|
|
103
103
|
},
|
|
104
|
+
"pnpm": {
|
|
105
|
+
"overrides": {
|
|
106
|
+
"picomatch": ">=4.0.4"
|
|
107
|
+
}
|
|
108
|
+
},
|
|
104
109
|
"lint-staged": {
|
|
105
110
|
"*.ts": "bash -c 'tsc -b --noEmit'",
|
|
106
111
|
"*.md": "markdownlint-cli2",
|
package/src/api/generated.ts
CHANGED
|
@@ -25,6 +25,28 @@ export interface paths {
|
|
|
25
25
|
patch?: never;
|
|
26
26
|
trace?: never;
|
|
27
27
|
};
|
|
28
|
+
"/healthz/details": {
|
|
29
|
+
parameters: {
|
|
30
|
+
query?: never;
|
|
31
|
+
header?: never;
|
|
32
|
+
path?: never;
|
|
33
|
+
cookie?: never;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Detailed system health state
|
|
37
|
+
* @description Returns system health derived from alert engine and windowed metrics.
|
|
38
|
+
* Includes health status, trend, active alerts, and key metrics.
|
|
39
|
+
* Must NOT depend on database availability.
|
|
40
|
+
*/
|
|
41
|
+
get: operations["getHealthDetails"];
|
|
42
|
+
put?: never;
|
|
43
|
+
post?: never;
|
|
44
|
+
delete?: never;
|
|
45
|
+
options?: never;
|
|
46
|
+
head?: never;
|
|
47
|
+
patch?: never;
|
|
48
|
+
trace?: never;
|
|
49
|
+
};
|
|
28
50
|
"/auth/start": {
|
|
29
51
|
parameters: {
|
|
30
52
|
query?: never;
|
|
@@ -1902,6 +1924,26 @@ export interface components {
|
|
|
1902
1924
|
/** @description Current application environment */
|
|
1903
1925
|
app_env: string;
|
|
1904
1926
|
};
|
|
1927
|
+
HealthStateResponse: {
|
|
1928
|
+
/** @enum {string} */
|
|
1929
|
+
status: "healthy" | "degraded" | "critical";
|
|
1930
|
+
/** @enum {string} */
|
|
1931
|
+
trend: "stable" | "worsening" | "improving";
|
|
1932
|
+
alerts: Record<string, never>[];
|
|
1933
|
+
metrics: {
|
|
1934
|
+
errorRate: number;
|
|
1935
|
+
p95Latency: number;
|
|
1936
|
+
activeExecutions: number;
|
|
1937
|
+
droppedEvents: {
|
|
1938
|
+
log: number;
|
|
1939
|
+
metric: number;
|
|
1940
|
+
alert: number;
|
|
1941
|
+
trace: number;
|
|
1942
|
+
};
|
|
1943
|
+
};
|
|
1944
|
+
/** @description Unix timestamp (milliseconds) of last health state computation */
|
|
1945
|
+
lastUpdated: number;
|
|
1946
|
+
};
|
|
1905
1947
|
MeResponse: {
|
|
1906
1948
|
/** Format: uuid */
|
|
1907
1949
|
userId: string;
|
|
@@ -1944,12 +1986,16 @@ export interface components {
|
|
|
1944
1986
|
};
|
|
1945
1987
|
UserOrgMembership: {
|
|
1946
1988
|
/** Format: uuid */
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1989
|
+
userId: string;
|
|
1990
|
+
/** Format: uuid */
|
|
1991
|
+
orgId: string;
|
|
1992
|
+
orgName: string;
|
|
1993
|
+
orgSlug: string;
|
|
1950
1994
|
role: components["schemas"]["WorkspaceRole"];
|
|
1951
1995
|
/** Format: date-time */
|
|
1952
1996
|
joinedAt: string;
|
|
1997
|
+
isActive: boolean;
|
|
1998
|
+
orgType: components["schemas"]["OrgType"];
|
|
1953
1999
|
};
|
|
1954
2000
|
SetActiveOrgRequest: {
|
|
1955
2001
|
/**
|
|
@@ -2136,7 +2182,60 @@ export interface components {
|
|
|
2136
2182
|
};
|
|
2137
2183
|
/** @description AI usage summary for an organization */
|
|
2138
2184
|
OrgExecutionSummary: {
|
|
2139
|
-
|
|
2185
|
+
period: {
|
|
2186
|
+
/** Format: date-time */
|
|
2187
|
+
start: string;
|
|
2188
|
+
/** Format: date-time */
|
|
2189
|
+
end: string;
|
|
2190
|
+
};
|
|
2191
|
+
summary: components["schemas"]["UnifiedUsageSummary"];
|
|
2192
|
+
daily: components["schemas"]["UnifiedDailyUsage"][];
|
|
2193
|
+
byProfile: components["schemas"]["UnifiedProfileUsage"][];
|
|
2194
|
+
byUser: components["schemas"]["UnifiedUserUsage"][];
|
|
2195
|
+
byModel: components["schemas"]["UnifiedModelUsage"][];
|
|
2196
|
+
byFeature: components["schemas"]["UnifiedFeatureUsage"][];
|
|
2197
|
+
};
|
|
2198
|
+
UnifiedUsageSummary: {
|
|
2199
|
+
executions: number;
|
|
2200
|
+
totalCostUsd: string;
|
|
2201
|
+
totalTokens: number;
|
|
2202
|
+
avgDurationMs: number;
|
|
2203
|
+
failureRate: number;
|
|
2204
|
+
};
|
|
2205
|
+
UnifiedDailyUsage: {
|
|
2206
|
+
date: string;
|
|
2207
|
+
executions: number;
|
|
2208
|
+
totalCostUsd: string;
|
|
2209
|
+
};
|
|
2210
|
+
UnifiedProfileUsage: {
|
|
2211
|
+
profile: string;
|
|
2212
|
+
executions: number;
|
|
2213
|
+
percentOfTotal: number;
|
|
2214
|
+
totalCostUsd: string;
|
|
2215
|
+
avgDurationMs: number;
|
|
2216
|
+
failureRate: number;
|
|
2217
|
+
};
|
|
2218
|
+
UnifiedUserUsage: {
|
|
2219
|
+
/** Format: uuid */
|
|
2220
|
+
userId: string;
|
|
2221
|
+
email: string;
|
|
2222
|
+
executions: number;
|
|
2223
|
+
totalCostUsd: string;
|
|
2224
|
+
totalTokens: number;
|
|
2225
|
+
favoriteProfile: string;
|
|
2226
|
+
};
|
|
2227
|
+
UnifiedModelUsage: {
|
|
2228
|
+
model: string;
|
|
2229
|
+
provider: string;
|
|
2230
|
+
totalTokens: number;
|
|
2231
|
+
estimatedCostUsd: string;
|
|
2232
|
+
requestCount: number;
|
|
2233
|
+
};
|
|
2234
|
+
UnifiedFeatureUsage: {
|
|
2235
|
+
feature: string;
|
|
2236
|
+
totalTokens: number;
|
|
2237
|
+
estimatedCostUsd: string;
|
|
2238
|
+
requestCount: number;
|
|
2140
2239
|
};
|
|
2141
2240
|
ErrorResponse: {
|
|
2142
2241
|
error: string;
|
|
@@ -2462,6 +2561,8 @@ export interface components {
|
|
|
2462
2561
|
OrgAuthPolicy: {
|
|
2463
2562
|
requireSSO: boolean;
|
|
2464
2563
|
allowedProviders: string[];
|
|
2564
|
+
/** @description True when the requesting admin's own SSO session was revoked by this operation */
|
|
2565
|
+
selfRevoked?: boolean;
|
|
2465
2566
|
};
|
|
2466
2567
|
CreateInviteRequest: {
|
|
2467
2568
|
/**
|
|
@@ -2739,6 +2840,26 @@ export interface operations {
|
|
|
2739
2840
|
};
|
|
2740
2841
|
};
|
|
2741
2842
|
};
|
|
2843
|
+
getHealthDetails: {
|
|
2844
|
+
parameters: {
|
|
2845
|
+
query?: never;
|
|
2846
|
+
header?: never;
|
|
2847
|
+
path?: never;
|
|
2848
|
+
cookie?: never;
|
|
2849
|
+
};
|
|
2850
|
+
requestBody?: never;
|
|
2851
|
+
responses: {
|
|
2852
|
+
/** @description System health state */
|
|
2853
|
+
200: {
|
|
2854
|
+
headers: {
|
|
2855
|
+
[name: string]: unknown;
|
|
2856
|
+
};
|
|
2857
|
+
content: {
|
|
2858
|
+
"application/json": components["schemas"]["HealthStateResponse"];
|
|
2859
|
+
};
|
|
2860
|
+
};
|
|
2861
|
+
};
|
|
2862
|
+
};
|
|
2742
2863
|
startAuth: {
|
|
2743
2864
|
parameters: {
|
|
2744
2865
|
query?: never;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical error response types for all API surfaces.
|
|
3
|
+
*
|
|
4
|
+
* These types are the single source of truth for the error response shape
|
|
5
|
+
* across HTTP, streaming, agents, and the execution system.
|
|
6
|
+
*
|
|
7
|
+
* @see ADR-BE-098 for design rationale
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** Field-level validation detail for VALIDATION_ERROR responses. */
|
|
11
|
+
export interface ValidationDetail {
|
|
12
|
+
/** Field path (e.g. 'email', 'settings.name'). */
|
|
13
|
+
field: string
|
|
14
|
+
/** Human-readable error message for this field. */
|
|
15
|
+
message: string
|
|
16
|
+
/** Machine-readable sub-code (e.g. 'too_short', 'invalid_format') for frontend logic. */
|
|
17
|
+
code?: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Canonical error response shape returned by all API surfaces. */
|
|
21
|
+
export interface ErrorResponse {
|
|
22
|
+
/** Domain-specific error code (e.g. INVITE_EXPIRED, SSO_REQUIRED). */
|
|
23
|
+
error: string
|
|
24
|
+
/** HTTP status code — lives in payload for transport portability across HTTP, streaming, agents, execution system. */
|
|
25
|
+
status: number
|
|
26
|
+
/** Optional human-readable message — safe default applied by handler when absent. */
|
|
27
|
+
message?: string
|
|
28
|
+
/** Validation field-level details — only present for VALIDATION_ERROR. */
|
|
29
|
+
details?: ValidationDetail[]
|
|
30
|
+
/**
|
|
31
|
+
* Structured extension fields (e.g. ssoUrl, orgId).
|
|
32
|
+
*
|
|
33
|
+
* Conventions: camelCase keys, domain-scoped, shallow values,
|
|
34
|
+
* serializable, stable keys, no duplication of top-level fields.
|
|
35
|
+
*/
|
|
36
|
+
meta?: Record<string, unknown>
|
|
37
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -540,9 +540,21 @@ export { resolveScope, toQueryKey, fromQueryKey, resourceRelationships, matchesR
|
|
|
540
540
|
// Resource response wrapper (typed versioning for cache invalidation)
|
|
541
541
|
export type { ResourceResponse } from './resource-response'
|
|
542
542
|
|
|
543
|
+
// Error response types (canonical shape for all API surfaces)
|
|
544
|
+
// @see ADR-BE-098 for design rationale
|
|
545
|
+
export type { ValidationDetail, ErrorResponse } from './errors/index'
|
|
546
|
+
|
|
543
547
|
// OpenAPI generated types (from openapi/backend.yaml)
|
|
544
548
|
// @see src/api/README.md for codegen details
|
|
545
549
|
export type { paths, components, operations } from './api/index'
|
|
546
550
|
|
|
547
551
|
// OpenAPI route registry (generated from openapi/backend.yaml)
|
|
548
552
|
export { openApiRoutes, type OpenApiRoute, type OpenApiMethod } from './generated/openapi-routes'
|
|
553
|
+
|
|
554
|
+
// Secret wrapper (multi-surface redaction for sensitive values)
|
|
555
|
+
export type { Secret } from './security/index'
|
|
556
|
+
export { wrapSecret, unwrapSecret } from './security/index'
|
|
557
|
+
|
|
558
|
+
// Analytics response metadata (shared vocabulary for OLTP/OLAP separation)
|
|
559
|
+
// @see ADR-CTRL-053 for design rationale
|
|
560
|
+
export type { AnalyticsResponseMeta } from './types/analytics'
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret<T> — branded wrapper that prevents accidental secret leakage.
|
|
3
|
+
*
|
|
4
|
+
* Multi-surface protection:
|
|
5
|
+
* - toString() → [REDACTED] — template literals, string concatenation, error messages
|
|
6
|
+
* - toJSON() → [REDACTED] — JSON.stringify (API responses, serialization)
|
|
7
|
+
* - Symbol.toPrimitive → [REDACTED] — implicit type coercion
|
|
8
|
+
*
|
|
9
|
+
* Use wrapSecret() to wrap a value, unwrapSecret() to extract it.
|
|
10
|
+
* The __secret marker enables external detection (e.g., Pino serializers).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
// @vocabulary-exempt: Class required for prototype method control (toString/toJSON/Symbol.toPrimitive)
|
|
14
|
+
class SecretValue<T> {
|
|
15
|
+
readonly __secret = true as const;
|
|
16
|
+
private readonly _value: T;
|
|
17
|
+
|
|
18
|
+
constructor(value: T) {
|
|
19
|
+
this._value = value;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
unwrap(): T {
|
|
23
|
+
return this._value;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
toString(): string {
|
|
27
|
+
return '[REDACTED]';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
toJSON(): string {
|
|
31
|
+
return '[REDACTED]';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
[Symbol.toPrimitive](): string {
|
|
35
|
+
return '[REDACTED]';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type Secret<T> = SecretValue<T>;
|
|
40
|
+
|
|
41
|
+
export function wrapSecret<T>(value: T): Secret<T> {
|
|
42
|
+
return new SecretValue(value);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function unwrapSecret<T>(secret: Secret<T>): T {
|
|
46
|
+
return secret.unwrap();
|
|
47
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metadata included in every analytics-backed API response.
|
|
3
|
+
* Enables consumers to know data freshness and which backend served the query.
|
|
4
|
+
*
|
|
5
|
+
* See ADR-CTRL-053 D8: Data Freshness Contract.
|
|
6
|
+
*/
|
|
7
|
+
export interface AnalyticsResponseMeta {
|
|
8
|
+
/** Replication lag from OLTP in milliseconds. 0 when source is 'oltp'. */
|
|
9
|
+
readonly dataFreshnessMs: number;
|
|
10
|
+
/** Which backend served this response. */
|
|
11
|
+
readonly source: 'oltp' | 'olap';
|
|
12
|
+
/** ISO 8601 timestamp: when the data was current as of. */
|
|
13
|
+
readonly timestamp: string;
|
|
14
|
+
}
|