@shipeasy/openapi 2.3.0 → 2.4.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-LYNWK55D.js → chunk-4QSU744W.js} +161 -1
  2. package/dist/chunk-4QSU744W.js.map +1 -0
  3. package/dist/{chunk-PRN4AEAM.js → chunk-ZPKHTUVV.js} +1004 -251
  4. package/dist/chunk-ZPKHTUVV.js.map +1 -0
  5. package/dist/{client-DO5HTb_L.d.ts → client-WGNXT4xl.d.ts} +5267 -2643
  6. package/dist/client.d.ts +1 -1
  7. package/dist/client.js +45 -1
  8. package/dist/index.d.ts +2 -2
  9. package/dist/index.js +46 -2
  10. package/dist/index.js.map +1 -1
  11. package/dist/schemas.d.ts +2933 -542
  12. package/dist/schemas.js +213 -1
  13. package/openapi.json +11646 -6855
  14. package/openapi.yaml +4939 -1675
  15. package/package.json +1 -1
  16. package/spec/components/errors.yaml +3 -0
  17. package/spec/components/schemas/alerts.yaml +138 -0
  18. package/spec/components/schemas/attributes.yaml +53 -3
  19. package/spec/components/schemas/common.yaml +10 -0
  20. package/spec/components/schemas/configs.yaml +58 -0
  21. package/spec/components/schemas/connectors.yaml +5 -1
  22. package/spec/components/schemas/errors-api.yaml +51 -4
  23. package/spec/components/schemas/experiments.yaml +347 -87
  24. package/spec/components/schemas/gates.yaml +341 -277
  25. package/spec/components/schemas/i18n.yaml +169 -40
  26. package/spec/components/schemas/killswitches.yaml +36 -0
  27. package/spec/components/schemas/metrics.yaml +183 -6
  28. package/spec/components/schemas/ops.yaml +817 -29
  29. package/spec/components/schemas/projects.yaml +129 -3
  30. package/spec/openapi.yaml +47 -0
  31. package/spec/paths/alerts.yaml +184 -0
  32. package/spec/paths/attributes.yaml +23 -5
  33. package/spec/paths/configs.yaml +70 -0
  34. package/spec/paths/errors.yaml +16 -0
  35. package/spec/paths/experiments.yaml +236 -16
  36. package/spec/paths/gates.yaml +137 -0
  37. package/spec/paths/i18n.yaml +290 -6
  38. package/spec/paths/killswitches.yaml +6 -0
  39. package/spec/paths/metrics.yaml +186 -0
  40. package/spec/paths/ops.yaml +299 -0
  41. package/spec/paths/projects.yaml +60 -0
  42. package/dist/chunk-LYNWK55D.js.map +0 -1
  43. package/dist/chunk-PRN4AEAM.js.map +0 -1
@@ -1,296 +1,327 @@
1
- ListGatesResponse:
1
+ # The single wire shape for a gate row, shared by `ListGatesResponse`
2
+ # (`data[]` items) and `GET /api/admin/gates/{id}`. The app projects every gate
3
+ # through one `toGateApiRow` allow-list at the HTTP boundary, so both endpoints
4
+ # return the SAME object — this schema is that allow-list.
5
+ GateApiRow:
2
6
  type: object
3
7
  properties:
4
- data:
8
+ id:
9
+ type: string
10
+ description: Stable opaque gate id (`gat_…`).
11
+ name:
12
+ type: string
13
+ maxLength: 128
14
+ pattern: ^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$
15
+ description: Stable gate key used by SDKs (`Shipeasy.checkGate(user, '<name>')`). Single segment or `folder.name`. Lowercase letters, digits, `_` or `-`; max 128 chars. Immutable after create — rename = delete + recreate.
16
+ enabled:
17
+ anyOf:
18
+ - type: boolean
19
+ - type: integer
20
+ minimum: 0
21
+ maximum: 1
22
+ description: Master switch. Returned as `1`/`0` from D1; treat truthy as enabled.
23
+ type:
24
+ type: string
25
+ enum:
26
+ - targeting
27
+ - holdout
28
+ description: Gate kind — `targeting` (normal flag) or `holdout` (restricted public % + whitelist).
29
+ rolloutPct:
30
+ type: integer
31
+ minimum: 0
32
+ maximum: 10000
33
+ description: Current rollout in basis points (0–10000).
34
+ rules:
5
35
  type: array
6
36
  items:
7
37
  type: object
8
38
  properties:
9
- id:
10
- type: string
11
- description: Stable opaque gate id (`gat_…`).
12
- name:
39
+ attr:
13
40
  type: string
14
- maxLength: 128
15
- pattern: ^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$
16
- description: Stable gate key used by SDKs (`Shipeasy.checkGate(user, '<name>')`). Single segment or `folder.name`. Lowercase letters, digits, `_` or `-`; max 128 chars. Immutable after create — rename = delete + recreate.
17
- enabled:
18
- anyOf:
19
- - type: boolean
20
- - type: integer
21
- minimum: 0
22
- maximum: 1
23
- description: Master switch. Returned as `1`/`0` from D1; treat truthy as enabled.
24
- type:
41
+ minLength: 1
42
+ description: Attribute key on the evaluation context (e.g. `country`, `plan`, `email`). Matched case-sensitively against `Shipeasy.checkGate(user, name)` input.
43
+ op:
25
44
  type: string
26
45
  enum:
27
- - targeting
28
- - holdout
29
- description: Gate kind — `targeting` (normal flag) or `holdout` (restricted public % + whitelist).
30
- rolloutPct:
31
- type: integer
32
- minimum: 0
33
- maximum: 10000
34
- description: Current rollout in basis points (0–10000).
35
- rules:
36
- type: array
37
- items:
38
- type: object
39
- properties:
40
- attr:
41
- type: string
42
- minLength: 1
43
- description: Attribute key on the evaluation context (e.g. `country`, `plan`, `email`). Matched case-sensitively against `Shipeasy.checkGate(user, name)` input.
44
- op:
45
- type: string
46
- enum:
47
- - eq
48
- - neq
49
- - in
50
- - not_in
51
- - gt
52
- - gte
53
- - lt
54
- - lte
55
- - contains
56
- - regex
57
- - semver_gt
58
- - semver_gte
59
- - semver_lt
60
- - semver_lte
61
- - gate_pass
62
- - exp_in
63
- description: "Comparison operator. Equality: `eq`/`neq`. Set membership: `in`/`not_in` (value is an array). Numeric order: `gt`/`gte`/`lt`/`lte`. Semver order: `semver_gt`/`semver_gte`/`semver_lt`/`semver_lte` (value is a dotted version like `4.2.0`). String: `contains` (substring), `regex` (JS-flavour pattern, value is the pattern string). Cross-resource references (evaluated only on the worker hot path, where both KV blobs load): `gate_pass` (`value` is another gate's name — true when that gate passes for the same caller); `exp_in` (`attr` is a running experiment's name, `value` is a group name, `\"$holdout\"`, or `\"$any\"` — true when the caller is in that variant / the universe holdout / any variant)."
64
- value:
65
- description: 'Operand. Shape depends on `op`: scalar for `eq/neq/gt/gte/lt/lte/contains/semver_*`; array of scalars for `in/not_in`; string pattern for `regex`; referenced gate name for `gate_pass`; group name / `"$holdout"` / `"$any"` for `exp_in`.'
66
- required:
67
- - attr
68
- - op
69
- - value
70
- additionalProperties: false
71
- description: Single targeting predicate. A gate's `rules` array is evaluated with AND semantics; use the gatekeeper `stack` for OR / fall-through logic.
72
- salt:
73
- description: Hash salt used for percentage bucketing.
74
- type: string
75
- title:
76
- anyOf:
77
- - type: string
78
- - type: "null"
79
- description:
80
- anyOf:
81
- - type: string
82
- - type: "null"
83
- folder:
84
- anyOf:
85
- - type: string
86
- - type: "null"
87
- groupName:
88
- description: "Group label (note: `groupName` in response, `group` in request)."
89
- anyOf:
90
- - type: string
91
- - type: "null"
92
- ownerEmail:
93
- description: "Owner email (note: `ownerEmail` in response, `owner_email` in request)."
94
- anyOf:
95
- - type: string
96
- - type: "null"
97
- stack:
98
- anyOf:
99
- - type: array
100
- items:
101
- oneOf:
102
- - type: object
46
+ - eq
47
+ - neq
48
+ - in
49
+ - not_in
50
+ - gt
51
+ - gte
52
+ - lt
53
+ - lte
54
+ - contains
55
+ - regex
56
+ - semver_gt
57
+ - semver_gte
58
+ - semver_lt
59
+ - semver_lte
60
+ - gate_pass
61
+ - exp_in
62
+ description: "Comparison operator. Equality: `eq`/`neq`. Set membership: `in`/`not_in` (value is an array). Numeric order: `gt`/`gte`/`lt`/`lte`. Semver order: `semver_gt`/`semver_gte`/`semver_lt`/`semver_lte` (value is a dotted version like `4.2.0`). String: `contains` (substring), `regex` (JS-flavour pattern, value is the pattern string). Cross-resource references (evaluated only on the worker hot path, where both KV blobs load): `gate_pass` (`value` is another gate's name — true when that gate passes for the same caller); `exp_in` (`attr` is a running experiment's name, `value` is a group name, `\"$holdout\"`, or `\"$any\"` — true when the caller is in that variant / the universe holdout / any variant)."
63
+ value:
64
+ description: 'Operand. Shape depends on `op`: scalar for `eq/neq/gt/gte/lt/lte/contains/semver_*`; array of scalars for `in/not_in`; string pattern for `regex`; referenced gate name for `gate_pass`; group name / `"$holdout"` / `"$any"` for `exp_in`.'
65
+ required:
66
+ - attr
67
+ - op
68
+ - value
69
+ additionalProperties: false
70
+ description: Single targeting predicate. A gate's `rules` array is evaluated with AND semantics; use the gatekeeper `stack` for OR / fall-through logic.
71
+ salt:
72
+ description: Hash salt used for percentage bucketing.
73
+ type: string
74
+ title:
75
+ anyOf:
76
+ - type: string
77
+ - type: "null"
78
+ description:
79
+ anyOf:
80
+ - type: string
81
+ - type: "null"
82
+ folder:
83
+ anyOf:
84
+ - type: string
85
+ - type: "null"
86
+ groupName:
87
+ description: "Group label (note: `groupName` in response, `group` in request)."
88
+ anyOf:
89
+ - type: string
90
+ - type: "null"
91
+ ownerEmail:
92
+ description: "Owner email (note: `ownerEmail` in response, `owner_email` in request)."
93
+ anyOf:
94
+ - type: string
95
+ - type: "null"
96
+ stack:
97
+ anyOf:
98
+ - type: array
99
+ items:
100
+ oneOf:
101
+ - type: object
102
+ properties:
103
+ id:
104
+ type: string
105
+ minLength: 1
106
+ description: Client-supplied stable id for the stack entry (used for React keys, audit diffs, and as the default per-condition rollout salt).
107
+ type:
108
+ type: string
109
+ const: condition
110
+ description: Discriminator. `condition` = rule-based predicate sub-gate.
111
+ name:
112
+ description: Human label shown in the dashboard.
113
+ type: string
114
+ fromTemplate:
115
+ description: Id of the project template this entry was seeded from, or `null` if hand-authored.
116
+ anyOf:
117
+ - type: string
118
+ - type: "null"
119
+ pass:
120
+ description: Combinator across `rules`. `all` = AND (default), `any` = OR.
121
+ type: string
122
+ enum:
123
+ - all
124
+ - any
125
+ rules:
126
+ default: []
127
+ description: Predicates evaluated under `pass`. Empty array = match nothing.
128
+ type: array
129
+ items:
130
+ type: object
103
131
  properties:
104
- id:
132
+ attr:
105
133
  type: string
106
134
  minLength: 1
107
- description: Client-supplied stable id for the stack entry (used for React keys, audit diffs, and as the default per-condition rollout salt).
108
- type:
109
- type: string
110
- const: condition
111
- description: Discriminator. `condition` = rule-based predicate sub-gate.
112
- name:
113
- description: Human label shown in the dashboard.
114
- type: string
115
- fromTemplate:
116
- description: Id of the project template this entry was seeded from, or `null` if hand-authored.
117
- anyOf:
118
- - type: string
119
- - type: "null"
120
- pass:
121
- description: Combinator across `rules`. `all` = AND (default), `any` = OR.
135
+ description: Attribute key on the evaluation context (e.g. `country`, `plan`, `email`). Matched case-sensitively against `Shipeasy.checkGate(user, name)` input.
136
+ op:
122
137
  type: string
123
138
  enum:
124
- - all
125
- - any
126
- rules:
127
- default: []
128
- description: Predicates evaluated under `pass`. Empty array = match nothing.
129
- type: array
130
- items:
131
- type: object
132
- properties:
133
- attr:
134
- type: string
135
- minLength: 1
136
- description: Attribute key on the evaluation context (e.g. `country`, `plan`, `email`). Matched case-sensitively against `Shipeasy.checkGate(user, name)` input.
137
- op:
138
- type: string
139
- enum:
140
- - eq
141
- - neq
142
- - in
143
- - not_in
144
- - gt
145
- - gte
146
- - lt
147
- - lte
148
- - contains
149
- - regex
150
- - semver_gt
151
- - semver_gte
152
- - semver_lt
153
- - semver_lte
154
- - gate_pass
155
- - exp_in
156
- description: "Comparison operator. Equality: `eq`/`neq`. Set membership: `in`/`not_in` (value is an array). Numeric order: `gt`/`gte`/`lt`/`lte`. Semver order: `semver_gt`/`semver_gte`/`semver_lt`/`semver_lte` (value is a dotted version like `4.2.0`). String: `contains` (substring), `regex` (JS-flavour pattern, value is the pattern string). Cross-resource references (evaluated only on the worker hot path, where both KV blobs load): `gate_pass` (`value` is another gate's name — true when that gate passes for the same caller); `exp_in` (`attr` is a running experiment's name, `value` is a group name, `\"$holdout\"`, or `\"$any\"` — true when the caller is in that variant / the universe holdout / any variant)."
157
- value:
158
- description: 'Operand. Shape depends on `op`: scalar for `eq/neq/gt/gte/lt/lte/contains/semver_*`; array of scalars for `in/not_in`; string pattern for `regex`; referenced gate name for `gate_pass`; group name / `"$holdout"` / `"$any"` for `exp_in`.'
159
- required:
160
- - attr
161
- - op
162
- - value
163
- additionalProperties: false
164
- description: Single targeting predicate. A gate's `rules` array is evaluated with AND semantics; use the gatekeeper `stack` for OR / fall-through logic.
165
- rolloutPct:
166
- description: Per-condition rollout in basis points. After the rules match, the caller is bucketed at this %; in-bucket → gate `true`, otherwise fall through to the next entry. Absent ⇒ 10000 (100%, every matching caller passes).
167
- type: integer
168
- minimum: 0
169
- maximum: 10000
170
- bucketBy:
171
- description: Attribute used to hash the caller into the per-condition bucket. Default `userID`.
172
- type: string
173
- salt:
174
- description: Per-condition hash salt. Defaults to the entry `id`, then the gate salt.
175
- type: string
176
- ramp:
177
- type: object
178
- properties:
179
- from:
180
- type: integer
181
- minimum: 0
182
- maximum: 10000
183
- description: Start of the ramp in basis points (0–10000).
184
- to:
185
- type: integer
186
- minimum: 0
187
- maximum: 10000
188
- description: End of the ramp in basis points (0–10000).
189
- startAt:
190
- type: integer
191
- minimum: 0
192
- maximum: 9007199254740991
193
- description: Ramp start, epoch milliseconds (UTC).
194
- durationMs:
195
- type: integer
196
- exclusiveMinimum: 0
197
- maximum: 9007199254740991
198
- description: Ramp length in milliseconds.
199
- required:
200
- - from
201
- - to
202
- - startAt
203
- - durationMs
204
- additionalProperties: false
205
- description: Linear rollout ramp. The effective rollout % interpolates `from`→`to` over `[startAt, startAt+durationMs]`, clamped outside that window, evaluated against the wall-clock at eval time. Overrides the entry's static `rolloutPct` while present.
206
- locked:
207
- description: If `true`, dashboard hides edit controls (e.g. the trailing public-floor entry).
208
- type: boolean
209
- required:
210
- - id
211
- - type
212
- additionalProperties: false
213
- description: Rule-based sub-gate. When the rules match and the caller falls in the per-condition rollout bucket, evaluation short-circuits and the gate returns `true`; otherwise it falls through to the next entry.
214
- - type: object
215
- properties:
216
- id:
217
- type: string
218
- minLength: 1
219
- description: Client-supplied stable id for the stack entry.
220
- type:
221
- type: string
222
- const: rollout
223
- description: Discriminator. `rollout` = percentage-bucket sub-gate.
224
- name:
225
- description: Human label shown in the dashboard.
226
- type: string
227
- fromTemplate:
228
- description: Source template id, or `null`.
229
- anyOf:
230
- - type: string
231
- - type: "null"
232
- rolloutPct:
233
- type: integer
234
- minimum: 0
235
- maximum: 10000
236
- description: Bucket size in basis points (0–10000 = 0%–100%). `5000` = 50%, `100` = 1%, allows sub-1% precision.
237
- bucketBy:
238
- description: Attribute used to hash the caller into a bucket. Defaults to `user.userID`. Use e.g. `accountID` to bucket whole accounts together.
239
- type: string
240
- salt:
241
- description: Per-entry hash salt. Defaults to the gate's salt. Set explicitly to keep two rollouts independent or correlated across gates.
242
- type: string
243
- ramp:
244
- type: object
245
- properties:
246
- from:
247
- type: integer
248
- minimum: 0
249
- maximum: 10000
250
- description: Start of the ramp in basis points (0–10000).
251
- to:
252
- type: integer
253
- minimum: 0
254
- maximum: 10000
255
- description: End of the ramp in basis points (0–10000).
256
- startAt:
257
- type: integer
258
- minimum: 0
259
- maximum: 9007199254740991
260
- description: Ramp start, epoch milliseconds (UTC).
261
- durationMs:
262
- type: integer
263
- exclusiveMinimum: 0
264
- maximum: 9007199254740991
265
- description: Ramp length in milliseconds.
266
- required:
267
- - from
268
- - to
269
- - startAt
270
- - durationMs
271
- additionalProperties: false
272
- description: Linear rollout ramp. The effective rollout % interpolates `from`→`to` over `[startAt, startAt+durationMs]`, clamped outside that window, evaluated against the wall-clock at eval time. Overrides the entry's static `rolloutPct` while present.
273
- locked:
274
- description: If `true`, dashboard hides edit controls.
275
- type: boolean
139
+ - eq
140
+ - neq
141
+ - in
142
+ - not_in
143
+ - gt
144
+ - gte
145
+ - lt
146
+ - lte
147
+ - contains
148
+ - regex
149
+ - semver_gt
150
+ - semver_gte
151
+ - semver_lt
152
+ - semver_lte
153
+ - gate_pass
154
+ - exp_in
155
+ description: "Comparison operator. Equality: `eq`/`neq`. Set membership: `in`/`not_in` (value is an array). Numeric order: `gt`/`gte`/`lt`/`lte`. Semver order: `semver_gt`/`semver_gte`/`semver_lt`/`semver_lte` (value is a dotted version like `4.2.0`). String: `contains` (substring), `regex` (JS-flavour pattern, value is the pattern string). Cross-resource references (evaluated only on the worker hot path, where both KV blobs load): `gate_pass` (`value` is another gate's name — true when that gate passes for the same caller); `exp_in` (`attr` is a running experiment's name, `value` is a group name, `\"$holdout\"`, or `\"$any\"` — true when the caller is in that variant / the universe holdout / any variant)."
156
+ value:
157
+ description: 'Operand. Shape depends on `op`: scalar for `eq/neq/gt/gte/lt/lte/contains/semver_*`; array of scalars for `in/not_in`; string pattern for `regex`; referenced gate name for `gate_pass`; group name / `"$holdout"` / `"$any"` for `exp_in`.'
276
158
  required:
277
- - id
278
- - type
279
- - rolloutPct
159
+ - attr
160
+ - op
161
+ - value
280
162
  additionalProperties: false
281
- description: Percentage-rollout sub-gate. Hashes `bucketBy` (default `userID`) with `salt` and returns `true` for `rolloutPct/10000` fraction of callers (or the ramp's effective % when `ramp` is set).
282
- description: One entry in the ordered gatekeeper stack. Evaluated top-to-bottom; first matching entry decides. Mix `condition` and `rollout` entries to express `internal-only` + `1% beta` + `50% public` in a single gate.
283
- - type: "null"
284
- updatedAt:
285
- type: string
286
- description: ISO-8601 timestamp of last mutation.
287
- required:
288
- - id
289
- - name
290
- - enabled
291
- - rolloutPct
292
- - updatedAt
293
- additionalProperties: false
163
+ description: Single targeting predicate. A gate's `rules` array is evaluated with AND semantics; use the gatekeeper `stack` for OR / fall-through logic.
164
+ rolloutPct:
165
+ description: Per-condition rollout in basis points. After the rules match, the caller is bucketed at this %; in-bucket → gate `true`, otherwise fall through to the next entry. Absent ⇒ 10000 (100%, every matching caller passes).
166
+ type: integer
167
+ minimum: 0
168
+ maximum: 10000
169
+ bucketBy:
170
+ description: Attribute used to hash the caller into the per-condition bucket. Default `userID`.
171
+ type: string
172
+ salt:
173
+ description: Per-condition hash salt. Defaults to the entry `id`, then the gate salt.
174
+ type: string
175
+ ramp:
176
+ type: object
177
+ properties:
178
+ from:
179
+ type: integer
180
+ minimum: 0
181
+ maximum: 10000
182
+ description: Start of the ramp in basis points (0–10000).
183
+ to:
184
+ type: integer
185
+ minimum: 0
186
+ maximum: 10000
187
+ description: End of the ramp in basis points (0–10000).
188
+ startAt:
189
+ type: integer
190
+ minimum: 0
191
+ maximum: 9007199254740991
192
+ description: Ramp start, epoch milliseconds (UTC).
193
+ durationMs:
194
+ type: integer
195
+ exclusiveMinimum: 0
196
+ maximum: 9007199254740991
197
+ description: Ramp length in milliseconds.
198
+ required:
199
+ - from
200
+ - to
201
+ - startAt
202
+ - durationMs
203
+ additionalProperties: false
204
+ description: Linear rollout ramp. The effective rollout % interpolates `from`→`to` over `[startAt, startAt+durationMs]`, clamped outside that window, evaluated against the wall-clock at eval time. Overrides the entry's static `rolloutPct` while present.
205
+ locked:
206
+ description: If `true`, dashboard hides edit controls (e.g. the trailing public-floor entry).
207
+ type: boolean
208
+ required:
209
+ - id
210
+ - type
211
+ additionalProperties: false
212
+ description: Rule-based sub-gate. When the rules match and the caller falls in the per-condition rollout bucket, evaluation short-circuits and the gate returns `true`; otherwise it falls through to the next entry.
213
+ - type: object
214
+ properties:
215
+ id:
216
+ type: string
217
+ minLength: 1
218
+ description: Client-supplied stable id for the stack entry.
219
+ type:
220
+ type: string
221
+ const: rollout
222
+ description: Discriminator. `rollout` = percentage-bucket sub-gate.
223
+ name:
224
+ description: Human label shown in the dashboard.
225
+ type: string
226
+ fromTemplate:
227
+ description: Source template id, or `null`.
228
+ anyOf:
229
+ - type: string
230
+ - type: "null"
231
+ rolloutPct:
232
+ type: integer
233
+ minimum: 0
234
+ maximum: 10000
235
+ description: Bucket size in basis points (0–10000 = 0%–100%). `5000` = 50%, `100` = 1%, allows sub-1% precision.
236
+ bucketBy:
237
+ description: Attribute used to hash the caller into a bucket. Defaults to `user.userID`. Use e.g. `accountID` to bucket whole accounts together.
238
+ type: string
239
+ salt:
240
+ description: Per-entry hash salt. Defaults to the gate's salt. Set explicitly to keep two rollouts independent or correlated across gates.
241
+ type: string
242
+ ramp:
243
+ type: object
244
+ properties:
245
+ from:
246
+ type: integer
247
+ minimum: 0
248
+ maximum: 10000
249
+ description: Start of the ramp in basis points (0–10000).
250
+ to:
251
+ type: integer
252
+ minimum: 0
253
+ maximum: 10000
254
+ description: End of the ramp in basis points (0–10000).
255
+ startAt:
256
+ type: integer
257
+ minimum: 0
258
+ maximum: 9007199254740991
259
+ description: Ramp start, epoch milliseconds (UTC).
260
+ durationMs:
261
+ type: integer
262
+ exclusiveMinimum: 0
263
+ maximum: 9007199254740991
264
+ description: Ramp length in milliseconds.
265
+ required:
266
+ - from
267
+ - to
268
+ - startAt
269
+ - durationMs
270
+ additionalProperties: false
271
+ description: Linear rollout ramp. The effective rollout % interpolates `from`→`to` over `[startAt, startAt+durationMs]`, clamped outside that window, evaluated against the wall-clock at eval time. Overrides the entry's static `rolloutPct` while present.
272
+ locked:
273
+ description: If `true`, dashboard hides edit controls.
274
+ type: boolean
275
+ required:
276
+ - id
277
+ - type
278
+ - rolloutPct
279
+ additionalProperties: false
280
+ description: Percentage-rollout sub-gate. Hashes `bucketBy` (default `userID`) with `salt` and returns `true` for `rolloutPct/10000` fraction of callers (or the ramp's effective % when `ramp` is set).
281
+ description: One entry in the ordered gatekeeper stack. Evaluated top-to-bottom; first matching entry decides. Mix `condition` and `rollout` entries to express `internal-only` + `1% beta` + `50% public` in a single gate.
282
+ - type: "null"
283
+ updatedAt:
284
+ type: string
285
+ description: ISO-8601 timestamp of last mutation.
286
+ creatorEmail:
287
+ description: Resolved email of the user who created the gate (`created_by` → `users.email`), or `null` when the creator is unknown.
288
+ anyOf:
289
+ - type: string
290
+ - type: "null"
291
+ updaterEmail:
292
+ description: Resolved email of the user who last edited the gate (`updated_by` → `users.email`), or `null` when the last editor is unknown.
293
+ anyOf:
294
+ - type: string
295
+ - type: "null"
296
+ version:
297
+ type: integer
298
+ minimum: 1
299
+ maximum: 9007199254740991
300
+ description: Monotonic edit counter — starts at 1 on create (D1 `NOT NULL DEFAULT 1`) and increments on every `PATCH /api/admin/gates/{id}`.
301
+ createdAt:
302
+ description: ISO-8601 creation timestamp, or `null` on legacy rows created before the column existed.
303
+ anyOf:
304
+ - type: string
305
+ - type: "null"
306
+ required:
307
+ - id
308
+ - name
309
+ - enabled
310
+ - rolloutPct
311
+ - updatedAt
312
+ - creatorEmail
313
+ - updaterEmail
314
+ - version
315
+ - createdAt
316
+ additionalProperties: false
317
+ description: The single wire shape for a gate row, shared by `ListGatesResponse` (`data[]` items) and `GET /api/admin/gates/{id}`.
318
+ ListGatesResponse:
319
+ type: object
320
+ properties:
321
+ data:
322
+ type: array
323
+ items:
324
+ $ref: "#/GateApiRow"
294
325
  next_cursor:
295
326
  anyOf:
296
327
  - type: string
@@ -907,3 +938,36 @@ DisableGateResponse:
907
938
  - id
908
939
  - enabled
909
940
  additionalProperties: false
941
+ GetGateResponse:
942
+ $ref: "#/GateApiRow"
943
+ ListGateActivityResponse:
944
+ type: array
945
+ items:
946
+ type: object
947
+ properties:
948
+ id:
949
+ type: string
950
+ action:
951
+ type: string
952
+ description: Audit action (e.g. `gate.create`, `gate.update`, `gate.enable`, `gate.disable`, `gate.delete`).
953
+ actorEmail:
954
+ type: string
955
+ actorType:
956
+ type: string
957
+ enum:
958
+ - user
959
+ - cli
960
+ - system
961
+ payload: {}
962
+ createdAt:
963
+ type: string
964
+ description: ISO-8601 timestamp.
965
+ required:
966
+ - id
967
+ - action
968
+ - actorEmail
969
+ - actorType
970
+ - payload
971
+ - createdAt
972
+ additionalProperties: false
973
+ description: Recent audit rows for one gate, newest first.