@company-semantics/contracts 0.103.2 → 0.104.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@company-semantics/contracts",
3
- "version": "0.103.2",
3
+ "version": "0.104.1",
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",
@@ -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;
@@ -2739,6 +2781,26 @@ export interface operations {
2739
2781
  };
2740
2782
  };
2741
2783
  };
2784
+ getHealthDetails: {
2785
+ parameters: {
2786
+ query?: never;
2787
+ header?: never;
2788
+ path?: never;
2789
+ cookie?: never;
2790
+ };
2791
+ requestBody?: never;
2792
+ responses: {
2793
+ /** @description System health state */
2794
+ 200: {
2795
+ headers: {
2796
+ [name: string]: unknown;
2797
+ };
2798
+ content: {
2799
+ "application/json": components["schemas"]["HealthStateResponse"];
2800
+ };
2801
+ };
2802
+ };
2803
+ };
2742
2804
  startAuth: {
2743
2805
  parameters: {
2744
2806
  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
+ }
@@ -18,6 +18,7 @@ const ALL_STATES: ExecutionState[] = [
18
18
  'completed',
19
19
  'completed_with_rollbacks',
20
20
  'failed_retryable',
21
+ 'failed_exhausted',
21
22
  'failed_terminal',
22
23
  'failed_with_partial_execution',
23
24
  'cancelled',
@@ -25,6 +25,7 @@ export const LIFECYCLE_DECISIONS: DecisionTable = {
25
25
  completed: 'already_confirmed',
26
26
  completed_with_rollbacks: 'already_confirmed',
27
27
  failed_retryable: 'conflict',
28
+ failed_exhausted: 'conflict',
28
29
  failed_terminal: 'conflict',
29
30
  failed_with_partial_execution: 'conflict',
30
31
  undone: 'conflict',
@@ -39,6 +40,7 @@ export const LIFECYCLE_DECISIONS: DecisionTable = {
39
40
  completed: 'conflict',
40
41
  completed_with_rollbacks: 'conflict',
41
42
  failed_retryable: 'conflict',
43
+ failed_exhausted: 'conflict',
42
44
  failed_terminal: 'conflict',
43
45
  failed_with_partial_execution: 'conflict',
44
46
  undone: 'conflict',
@@ -12,6 +12,7 @@
12
12
  * │ │ │ ├──→ completed
13
13
  * │ │ │ ├──→ completed_with_rollbacks
14
14
  * │ │ │ ├──→ failed_retryable ──→ ready (retry)
15
+ * │ │ │ │ └──→ failed_exhausted
15
16
  * │ │ │ ├──→ failed_terminal
16
17
  * │ │ │ ├──→ failed_with_partial_execution
17
18
  * │ │ │ └──→ cancelled
@@ -61,6 +62,7 @@ export type ExecutionState =
61
62
  | 'completed'
62
63
  | 'completed_with_rollbacks'
63
64
  | 'failed_retryable'
65
+ | 'failed_exhausted'
64
66
  | 'failed_terminal'
65
67
  | 'failed_with_partial_execution'
66
68
  | 'cancelled'
@@ -78,7 +80,8 @@ export const VALID_TRANSITIONS: Record<ExecutionState, readonly ExecutionState[]
78
80
  ],
79
81
  completed: ['undone'],
80
82
  completed_with_rollbacks: [],
81
- failed_retryable: ['ready'],
83
+ failed_retryable: ['ready', 'failed_exhausted'],
84
+ failed_exhausted: [],
82
85
  failed_terminal: [],
83
86
  failed_with_partial_execution: [],
84
87
  cancelled: [],
package/src/index.ts CHANGED
@@ -540,9 +540,17 @@ 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'
@@ -0,0 +1,2 @@
1
+ export type { Secret } from './secret';
2
+ export { wrapSecret, unwrapSecret } from './secret';
@@ -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
+ }