@shipeasy/openapi 2.2.0 → 2.3.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.
Files changed (43) hide show
  1. package/dist/{chunk-643YSMLU.js → chunk-LYNWK55D.js} +23 -1
  2. package/dist/chunk-LYNWK55D.js.map +1 -0
  3. package/dist/{chunk-MRW3DJ57.js → chunk-PRN4AEAM.js} +250 -100
  4. package/dist/chunk-PRN4AEAM.js.map +1 -0
  5. package/dist/{client-K0ShmsC7.d.ts → client-DO5HTb_L.d.ts} +690 -143
  6. package/dist/client.d.ts +1 -1
  7. package/dist/client.js +7 -1
  8. package/dist/custom.js +4 -4
  9. package/dist/custom.js.map +1 -1
  10. package/dist/index.d.ts +2 -2
  11. package/dist/index.js +8 -2
  12. package/dist/index.js.map +1 -1
  13. package/dist/schemas.d.ts +686 -73
  14. package/dist/schemas.js +41 -5
  15. package/openapi.json +1486 -521
  16. package/openapi.yaml +1016 -350
  17. package/package.json +1 -1
  18. package/spec/components/errors.yaml +30 -1
  19. package/spec/components/schemas/common.yaml +6 -0
  20. package/spec/components/schemas/errors-api.yaml +66 -3
  21. package/spec/components/schemas/experiment-api-row.yaml +293 -0
  22. package/spec/components/schemas/experiments.yaml +54 -299
  23. package/spec/components/schemas/gates.yaml +19 -0
  24. package/spec/components/schemas/keys.yaml +2 -1
  25. package/spec/components/schemas/metrics.yaml +17 -17
  26. package/spec/components/schemas/ops.yaml +101 -0
  27. package/spec/components/schemas/projects.yaml +119 -1
  28. package/spec/components/schemas/universes.yaml +83 -1
  29. package/spec/openapi.yaml +14 -0
  30. package/spec/paths/alert-rules.yaml +1 -0
  31. package/spec/paths/configs.yaml +1 -0
  32. package/spec/paths/errors.yaml +96 -2
  33. package/spec/paths/events.yaml +1 -0
  34. package/spec/paths/experiments.yaml +8 -0
  35. package/spec/paths/gates.yaml +1 -0
  36. package/spec/paths/keys.yaml +1 -0
  37. package/spec/paths/killswitches.yaml +1 -0
  38. package/spec/paths/metrics.yaml +1 -0
  39. package/spec/paths/ops.yaml +111 -0
  40. package/spec/paths/projects.yaml +2 -2
  41. package/spec/paths/universes.yaml +1 -0
  42. package/dist/chunk-643YSMLU.js.map +0 -1
  43. package/dist/chunk-MRW3DJ57.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shipeasy/openapi",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "Shipeasy admin OpenAPI 3.2 spec (hand-authored, single source of truth) + the generated TypeScript client, Zod schemas, and types. Consumed by @shipeasy/cli and @shipeasy/mcp.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -17,6 +17,17 @@ ErrorCode:
17
17
  - GROUPS_WEIGHT_SUM
18
18
  - EVENT_PENDING
19
19
  - INTERNAL
20
+ - PLAN_LIMIT
21
+ # Experiments
22
+ - EXPERIMENT_NO_GOAL_METRIC
23
+ - EXPERIMENT_ARCHIVED_RESTART
24
+ - EXPERIMENT_RESTORE_INVALID
25
+ - EXPERIMENT_NOT_RUNNING
26
+ - EXPERIMENT_RUNNING_ARCHIVE
27
+ - EXPERIMENT_IMMUTABLE_FIELD
28
+ # Metrics
29
+ - METRIC_NOT_FOUND
30
+ - METRIC_UNKNOWN_ID
20
31
  x-enum-descriptions:
21
32
  BAD_REQUEST: Malformed request (bad JSON, missing project scope).
22
33
  UNAUTHORIZED: Missing or invalid admin SDK key.
@@ -33,9 +44,18 @@ ErrorCode:
33
44
  GROUPS_WEIGHT_SUM: Experiment group weights must sum to 10000 (basis points).
34
45
  EVENT_PENDING: The referenced event is still pending review and cannot back a metric yet.
35
46
  INTERNAL: Unexpected server error.
47
+ PLAN_LIMIT: The action would exceed a plan quota (e.g. the tier's maximum experiments, metrics, or configs). Upgrade the plan or archive an existing resource.
48
+ EXPERIMENT_NO_GOAL_METRIC: The experiment has no goal metric set, which the requested action requires.
49
+ EXPERIMENT_ARCHIVED_RESTART: An archived experiment cannot be restarted.
50
+ EXPERIMENT_RESTORE_INVALID: The experiment cannot be restored from its current state.
51
+ EXPERIMENT_NOT_RUNNING: The action requires the experiment to be running.
52
+ EXPERIMENT_RUNNING_ARCHIVE: A running experiment cannot be archived — stop it first.
53
+ EXPERIMENT_IMMUTABLE_FIELD: A field that is immutable while the experiment is running was modified.
54
+ METRIC_NOT_FOUND: The referenced metric does not exist or is not visible to the caller.
55
+ METRIC_UNKNOWN_ID: The supplied metric id is malformed or not recognised.
36
56
  Error:
37
57
  type: object
38
- description: Uniform error envelope returned by every admin endpoint on a non-2xx status. `error` is the human-readable message; `code` is the stable machine code (present whenever the failure maps to a catalogued `ErrorCode`); `detail` carries extra context (validation paths, conflicting field); `instructions` is optional actionable guidance for resolving the error.
58
+ description: Uniform error envelope returned by every admin endpoint on a non-2xx status. `error` is the human-readable message; `code` is the stable machine code (present whenever the failure maps to a catalogued `ErrorCode`); `detail` carries extra context (validation paths, conflicting field); `fields` maps each failing input field to its own message; `instructions` is optional actionable guidance for resolving the error; `schema` echoes back the expected JSON Schema when a value failed schema validation.
39
59
  required:
40
60
  - error
41
61
  additionalProperties: false
@@ -48,6 +68,15 @@ Error:
48
68
  detail:
49
69
  type: string
50
70
  description: Extra context (validation details, conflicting field, referenced row).
71
+ fields:
72
+ type: object
73
+ additionalProperties:
74
+ type: string
75
+ description: Per-field validation messages, keyed by the submitted field's path (dot-notation for nested fields, e.g. `groups.0.weight`). Present when structural validation failed on one or more specific input fields, so a client form can attach each message to its own input instead of collapsing everything into one banner.
51
76
  instructions:
52
77
  type: string
53
78
  description: Actionable guidance for resolving this error — what to check or change next.
79
+ schema:
80
+ type: object
81
+ additionalProperties: true
82
+ description: The expected JSON Schema (draft 2020-12) the submitted value must satisfy. Returned only when a value failed schema validation (e.g. a config `value` that does not match its config's saved schema), so the caller can correct the value and retry without re-fetching.
@@ -88,5 +88,11 @@ ExperimentInlineMetric:
88
88
  enum: [count_users, count_events, retention_7d, retention_30d, sum, avg]
89
89
  description: Reducer for the `event` form. Defaults to `count_users`.
90
90
  value: { type: string, minLength: 1, maxLength: 256, description: Numeric event property for `sum`/`avg` (with `event`). }
91
+ min_effect_of_interest:
92
+ description: Per-experiment override of the metric's default minimum effect of interest (relative, 0–1) — the smallest change worth acting on for this experiment's decision. `null`/omitted inherits the metric default. For a guardrail, the non-inferiority margin.
93
+ default: null
94
+ anyOf:
95
+ - type: number
96
+ - type: "null"
91
97
  additionalProperties: false
92
98
  description: Inline metric — a DSL `query`, or an `event` (+ `aggregation`/`value`) the server compiles into one.
@@ -13,7 +13,11 @@ ErrorRecord:
13
13
  description: Project this issue belongs to.
14
14
  fingerprint:
15
15
  type: string
16
- description: Stable dedupe key (hash of `errorType` + normalized `message` + consequence). Unique per project — every occurrence with the same fingerprint folds into this one row.
16
+ description: >-
17
+ Stable dedupe key — the issue TITLE (hash of `errorType` + `subject` +
18
+ `outcome`, plus the violation name for violations). Unique per project —
19
+ every occurrence with the same title folds into this one row;
20
+ per-instance variety (message/stack/extras) lives in `occurrences`.
17
21
  causedByFingerprint:
18
22
  description: Fingerprint of the issue this one descends from — set when `see()` reported the same error (re-throw) or its `{ cause }` (wrap) at an inner boundary first. Points at another error's `fingerprint` in the same project (soft reference, no FK). `null` for a root issue.
19
23
  anyOf:
@@ -91,7 +95,13 @@ ErrorRecord:
91
95
  count:
92
96
  type: integer
93
97
  minimum: 1
94
- description: Number of folded occurrences for this fingerprint.
98
+ description: EXACT number of folded occurrences for this fingerprint — every occurrence increments it, regardless of detail-row sampling.
99
+ occurrences:
100
+ type: array
101
+ description: |-
102
+ Sampled per-instance detail rows behind this issue, newest first. Returned only by `GET /api/admin/errors/{id}` (never in list responses). The parent row's `count` / `firstSeenAt` / `lastSeenAt` are exact; these rows are a *sampled sketch* of the instances — exhaustive while the issue is small, thinning to roughly 1-in-10 past 10 occurrences, 1-in-100 past 100, and 1-in-1000 past 1000 (each row's `sampleRate` records the rate in force when it was kept), capped at the newest 100 rows.
103
+ items:
104
+ $ref: "#/ErrorOccurrence"
95
105
  status:
96
106
  type: string
97
107
  enum:
@@ -123,9 +133,62 @@ ErrorRecord:
123
133
  - createdAt
124
134
  - updatedAt
125
135
  additionalProperties: false
136
+ ErrorOccurrence:
137
+ type: object
138
+ description: One sampled instance behind a tracked error — the minimal per-occurrence payload (what varies between instances; everything else lives on the parent `ErrorRecord`).
139
+ properties:
140
+ id:
141
+ type: string
142
+ description: Stable opaque occurrence id.
143
+ message:
144
+ type: string
145
+ description: This instance's raw message (unlike the fingerprint, never normalized).
146
+ stack:
147
+ description: This instance's stack trace, or `null` if none was captured.
148
+ anyOf:
149
+ - type: string
150
+ - type: "null"
151
+ url:
152
+ description: This instance's raw URL (ids intact), or `null`.
153
+ anyOf:
154
+ - type: string
155
+ - type: "null"
156
+ env:
157
+ description: Published env this instance ran against, or `null`.
158
+ anyOf:
159
+ - type: string
160
+ - type: "null"
161
+ side:
162
+ description: Which SDK side reported it — `client` or `server`. `null` if unknown.
163
+ anyOf:
164
+ - type: string
165
+ - type: "null"
166
+ sdkVersion:
167
+ description: "`@shipeasy/sdk` version of this instance, or `null`."
168
+ anyOf:
169
+ - type: string
170
+ - type: "null"
171
+ extrasJson:
172
+ description: This instance's sanitized extras, JSON-encoded. `null` if none.
173
+ anyOf:
174
+ - type: string
175
+ - type: "null"
176
+ sampleRate:
177
+ type: integer
178
+ minimum: 1
179
+ description: 1-in-N sampling rate in force when this instance was kept (`1` = the issue was still being recorded exhaustively).
180
+ seenAt:
181
+ type: string
182
+ description: ISO-8601 timestamp this instance was ingested.
183
+ required:
184
+ - id
185
+ - message
186
+ - sampleRate
187
+ - seenAt
188
+ additionalProperties: false
126
189
  ListErrorsResponse:
127
190
  type: array
128
- description: A bare JSON array of tracked errors, ordered by `lastSeenAt` descending. There is no pagination envelope — `limit` caps the page size.
191
+ description: A bare JSON array of tracked errors, ordered by `lastSeenAt` descending. There is no pagination envelope — `limit` caps the page size. List rows never include `occurrences` — read one error to get them.
129
192
  items:
130
193
  $ref: "#/ErrorRecord"
131
194
  UpdateErrorStatusRequest:
@@ -0,0 +1,293 @@
1
+ # The single wire shape for an experiment row, shared by `ListExperimentsResponse`
2
+ # (`data[]` items) and `GET /api/admin/experiments/{id}`. The app projects every
3
+ # experiment through one `toExperimentApiRow` allow-list at the HTTP boundary, so
4
+ # both endpoints return the SAME object — this schema is that allow-list.
5
+ #
6
+ # Two tiers of fields:
7
+ # • base (always present) — persisted columns + the pool-slice / headroom /
8
+ # version fields the serializer defaults (`?? null` / `?? 0` / `?? 1`), so
9
+ # they appear on every row. These are `required`.
10
+ # • enriched (list only) — verdict + goal/guardrail summary + exposure spark +
11
+ # resolved creator/editor emails. The list handler derives them for every
12
+ # row; the by-id handler returns the raw row, so they are `undefined` and
13
+ # drop out of the JSON. They are therefore OPTIONAL (present on list rows,
14
+ # absent on the by-id detail) — never `required`.
15
+ ExperimentApiRow:
16
+ type: object
17
+ properties:
18
+ id:
19
+ type: string
20
+ description: Stable opaque experiment id (`exp_…`).
21
+ name:
22
+ type: string
23
+ maxLength: 128
24
+ pattern: ^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$
25
+ description: Stable experiment key. Single segment or `folder.name` (a-z, 0-9, `_`/`-`; max 128 chars). Used by SDKs as `Shipeasy.getExperiment(user, '<name>')`. Immutable after create.
26
+ description:
27
+ anyOf:
28
+ - type: string
29
+ - type: "null"
30
+ hypothesis:
31
+ anyOf:
32
+ - type: string
33
+ - type: "null"
34
+ tag:
35
+ anyOf:
36
+ - type: string
37
+ - type: "null"
38
+ ownerEmail:
39
+ anyOf:
40
+ - type: string
41
+ - type: "null"
42
+ audience:
43
+ anyOf:
44
+ - type: string
45
+ - type: "null"
46
+ bucketBy:
47
+ anyOf:
48
+ - type: string
49
+ minLength: 1
50
+ maxLength: 128
51
+ pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$
52
+ description: User-attribute name used as the bucketing key — e.g. `user_id` (default), `session_id`, `device_id`, or a custom attribute like `company_id` to keep a whole org on one variant. Defaults to `user_id` when omitted.
53
+ - type: "null"
54
+ folder:
55
+ anyOf:
56
+ - type: string
57
+ - type: "null"
58
+ status:
59
+ type: string
60
+ enum:
61
+ - draft
62
+ - running
63
+ - stopped
64
+ - archived
65
+ universe:
66
+ type: string
67
+ description: Universe name this experiment draws from.
68
+ targetingGate:
69
+ anyOf:
70
+ - type: string
71
+ - type: "null"
72
+ holdoutGate:
73
+ anyOf:
74
+ - type: string
75
+ - type: "null"
76
+ description: Per-experiment holdout gate name (a `holdout`-type flag), or `null`.
77
+ allocationPct:
78
+ type: integer
79
+ minimum: -9007199254740991
80
+ maximum: 9007199254740991
81
+ description: Allocation in basis points (0–10000).
82
+ reservedHeadroom:
83
+ type: integer
84
+ minimum: 0
85
+ maximum: 10000
86
+ description: Basis points of the split reserved for appended variants (group weights sum to 10000 − this).
87
+ hashVersion:
88
+ type: integer
89
+ minimum: 1
90
+ description: Bucketing hash algorithm version for the experiment's pool slice (§B4). Defaults to 1.
91
+ poolOffsetBp:
92
+ anyOf:
93
+ - type: integer
94
+ minimum: 0
95
+ maximum: 10000
96
+ - type: "null"
97
+ description: Basis-point offset of the experiment's contiguous slice in the universe pool, or `null` before a slice is allocated.
98
+ poolSizeBp:
99
+ anyOf:
100
+ - type: integer
101
+ minimum: 0
102
+ maximum: 10000
103
+ - type: "null"
104
+ description: Basis-point width of the experiment's pool slice (equal to its allocation), or `null` before a slice is allocated.
105
+ salt:
106
+ type: string
107
+ params:
108
+ type: object
109
+ additionalProperties:
110
+ type: string
111
+ enum:
112
+ - string
113
+ - bool
114
+ - number
115
+ groups:
116
+ type: array
117
+ items:
118
+ type: object
119
+ properties:
120
+ name:
121
+ type: string
122
+ minLength: 1
123
+ maxLength: 64
124
+ description: Group label (e.g. `control`, `treatment_a`). Max 64 chars.
125
+ weight:
126
+ type: integer
127
+ minimum: 0
128
+ maximum: 10000
129
+ description: Allocation weight in basis points (0–10000). The sum across all groups must equal exactly **10000** (100%).
130
+ params:
131
+ default: {}
132
+ description: Per-group parameter values delivered to the SDK when a caller is hashed into this group. Keys must match the experiment's `params` schema.
133
+ type: object
134
+ additionalProperties: {}
135
+ required:
136
+ - name
137
+ - weight
138
+ additionalProperties: false
139
+ description: One variant in the experiment. Weights across all groups must sum to 10000.
140
+ significanceThreshold:
141
+ type: number
142
+ minRuntimeDays:
143
+ type: integer
144
+ minimum: -9007199254740991
145
+ maximum: 9007199254740991
146
+ minSampleSize:
147
+ type: integer
148
+ minimum: -9007199254740991
149
+ maximum: 9007199254740991
150
+ sequentialTesting:
151
+ type: boolean
152
+ startedAt:
153
+ anyOf:
154
+ - type: string
155
+ - type: "null"
156
+ description: ISO-8601 timestamp the experiment last transitioned to `running`, or `null`.
157
+ stoppedAt:
158
+ anyOf:
159
+ - type: string
160
+ - type: "null"
161
+ updatedAt:
162
+ type: string
163
+ version:
164
+ anyOf:
165
+ - type: integer
166
+ - type: "null"
167
+ description: Save counter (number of published edits), or `null` on pre-versioning rows.
168
+ creatorEmail:
169
+ anyOf:
170
+ - type: string
171
+ - type: "null"
172
+ description: "Resolved creator email (`created_by` → users). Enriched field: present on list rows, omitted from the by-id detail."
173
+ updaterEmail:
174
+ anyOf:
175
+ - type: string
176
+ - type: "null"
177
+ description: "Resolved last-editor email (`updated_by` → users). Enriched field: present on list rows, omitted from the by-id detail."
178
+ verdict:
179
+ type: string
180
+ enum:
181
+ - ship
182
+ - hold
183
+ - wait
184
+ - invalid
185
+ - draft
186
+ description: "Answer-first decision from the goal metric + guardrails + SRM vs. the significance threshold and min runtime: `ship`, `hold`, `wait`, `invalid`, `draft`. Enriched field: list rows only."
187
+ verdictTitle:
188
+ type: string
189
+ description: "Expanded verdict headline the results hero renders. Enriched field: list rows only."
190
+ verdictWhy:
191
+ type: string
192
+ description: "Verdict rationale the results hero renders. Enriched field: list rows only."
193
+ goalMetric:
194
+ anyOf:
195
+ - type: object
196
+ properties:
197
+ id:
198
+ type: string
199
+ name:
200
+ type: string
201
+ required:
202
+ - id
203
+ - name
204
+ additionalProperties: false
205
+ - type: "null"
206
+ description: "The experiment's goal metric `{ id, name }`, or `null` when none is set. Enriched field: list rows only."
207
+ guardrails:
208
+ type: array
209
+ items:
210
+ type: object
211
+ properties:
212
+ id:
213
+ type: string
214
+ name:
215
+ type: string
216
+ eventName:
217
+ anyOf:
218
+ - type: string
219
+ - type: "null"
220
+ required:
221
+ - id
222
+ - name
223
+ additionalProperties: false
224
+ description: "Guardrail metrics `{ id, name, eventName? }`. Enriched field: list rows only."
225
+ guardrailCount:
226
+ type: integer
227
+ minimum: 0
228
+ description: "Number of guardrail metrics. Enriched field: list rows only."
229
+ primaryLiftPct:
230
+ anyOf:
231
+ - type: number
232
+ - type: "null"
233
+ description: "Goal-metric lift of the leading variant vs. control, in percent, or `null` when not yet computed. Enriched field: list rows only."
234
+ significancePct:
235
+ anyOf:
236
+ - type: number
237
+ - type: "null"
238
+ description: "Statistical significance (1 − p) as a percent, or `null` when not yet computed. Enriched field: list rows only."
239
+ sampleSize:
240
+ anyOf:
241
+ - type: integer
242
+ - type: "null"
243
+ description: "Total distinct units analysed, or `null` when not yet computed. Enriched field: list rows only."
244
+ exposure:
245
+ type: array
246
+ items:
247
+ type: object
248
+ properties:
249
+ ds:
250
+ type: string
251
+ value:
252
+ type: number
253
+ required:
254
+ - ds
255
+ - value
256
+ additionalProperties: false
257
+ description: "Cumulative unique-users-enrolled series for the exposure sparkline. Enriched field: list rows only."
258
+ exposureTotal:
259
+ anyOf:
260
+ - type: integer
261
+ - type: "null"
262
+ description: "Total distinct units ever exposed (sparkline headline), or `null`. Enriched field: list rows only."
263
+ required:
264
+ - id
265
+ - name
266
+ - description
267
+ - hypothesis
268
+ - tag
269
+ - ownerEmail
270
+ - audience
271
+ - bucketBy
272
+ - folder
273
+ - status
274
+ - universe
275
+ - targetingGate
276
+ - holdoutGate
277
+ - allocationPct
278
+ - reservedHeadroom
279
+ - hashVersion
280
+ - poolOffsetBp
281
+ - poolSizeBp
282
+ - salt
283
+ - params
284
+ - groups
285
+ - significanceThreshold
286
+ - minRuntimeDays
287
+ - minSampleSize
288
+ - sequentialTesting
289
+ - startedAt
290
+ - stoppedAt
291
+ - updatedAt
292
+ - version
293
+ additionalProperties: false