@nasebanal/cli 0.1.0 → 0.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.
- package/README.md +123 -4
- package/dist/apis.js +1 -0
- package/dist/index.js +9 -1
- package/dist/loginPage.js +112 -0
- package/dist/logo.js +7 -0
- package/dist/oauth.js +13 -5
- package/dist/reports/ci.js +59 -0
- package/dist/reports/csv.js +56 -0
- package/dist/reports/junit.js +119 -0
- package/dist/reports/locust.js +68 -0
- package/dist/reports/specmatic.js +69 -0
- package/dist/reports/upload.js +335 -0
- package/package.json +1 -1
- package/specs/account.yaml +484 -298
- package/specs/app-template.yaml +64 -62
- package/specs/assurance.yaml +1730 -0
- package/specs/recorder.yaml +375 -422
- package/specs/target.yaml +355 -363
package/specs/recorder.yaml
CHANGED
|
@@ -1,88 +1,53 @@
|
|
|
1
1
|
openapi: 3.0.3
|
|
2
2
|
info:
|
|
3
3
|
title: NASEBANAL Recorder API
|
|
4
|
-
description:
|
|
4
|
+
description: |-
|
|
5
5
|
Time-series data recorder API built with Cloudflare Workers and D1.
|
|
6
6
|
|
|
7
|
-
|
|
8
7
|
## Authentication
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
Create a Personal Access Token (PAT) in **Profile Settings > API Tokens** (requires Pro plan or above), then include
|
|
12
|
-
it in the `Authorization` header.
|
|
13
|
-
|
|
9
|
+
Create a Personal Access Token (PAT) in **Profile Settings > API Tokens** (requires Pro plan or above), then include it in the `Authorization` header.
|
|
14
10
|
|
|
15
11
|
Tokens use the format `nbpat_` followed by 40 random characters.
|
|
16
12
|
|
|
17
|
-
|
|
18
13
|
**Usage:**
|
|
19
|
-
|
|
20
14
|
```
|
|
21
|
-
|
|
22
15
|
Authorization: Bearer nbpat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
23
|
-
|
|
24
16
|
```
|
|
25
17
|
|
|
26
|
-
|
|
27
18
|
**curl example:**
|
|
28
|
-
|
|
29
19
|
```bash
|
|
30
|
-
|
|
31
20
|
curl -H "Authorization: Bearer nbpat_xxxxx..." https://api.example.com/api/v1/records
|
|
32
|
-
|
|
33
21
|
```
|
|
34
22
|
|
|
35
|
-
|
|
36
23
|
**Plan limits:**
|
|
37
|
-
|
|
38
24
|
- Free: API tokens not available
|
|
39
|
-
|
|
40
25
|
- Pro: up to 5 tokens
|
|
41
|
-
|
|
42
26
|
- Family: up to 20 tokens
|
|
43
|
-
|
|
44
27
|
- Enterprise: unlimited tokens
|
|
45
28
|
|
|
46
|
-
|
|
47
29
|
## SNS Shared Graph Embed
|
|
48
30
|
|
|
31
|
+
Publicly shared graphs can be embedded in external sites (blogs, portfolios, etc.) via iframe without authentication.
|
|
49
32
|
|
|
50
|
-
|
|
51
|
-
authentication.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
**Endpoint:** `GET /shared/{lang}/{id}/embed`
|
|
55
|
-
|
|
33
|
+
**Endpoint:** `GET https://growth.nasebanal.com/{lang}/recorder/shared/{id}/embed` (served by NASEBANAL Growth, not by this API)
|
|
56
34
|
|
|
57
35
|
| Parameter | Type | Required | Description |
|
|
58
|
-
|
|
59
36
|
|-----------|------|----------|-------------|
|
|
60
|
-
|
|
61
37
|
| `lang` | path | Yes | Language: `ja` or `en` |
|
|
62
|
-
|
|
63
38
|
| `id` | path | Yes | Shared graph ID |
|
|
64
39
|
|
|
65
|
-
|
|
66
|
-
**Features:** Line chart with auto-scale, goal lines, statistics. No navigation header or footer — designed for
|
|
67
|
-
iframe embedding.
|
|
68
|
-
|
|
40
|
+
**Features:** Line chart with auto-scale, goal lines, statistics. No navigation header or footer — designed for iframe embedding.
|
|
69
41
|
|
|
70
42
|
**Auth:** Not required (public access).
|
|
71
43
|
|
|
72
|
-
|
|
73
44
|
**iframe example:**
|
|
74
|
-
|
|
75
45
|
```html
|
|
76
|
-
|
|
77
|
-
<iframe src=\"https://recorder.nasebanal.com/shared/ja/{id}/embed\" width=\"100%\" height=\"500\"
|
|
78
|
-
frameborder=\"0\"></iframe>
|
|
79
|
-
|
|
46
|
+
<iframe src=\"https://growth.nasebanal.com/ja/recorder/shared/{id}/embed\" width=\"100%\" height=\"500\" frameborder=\"0\"></iframe>
|
|
80
47
|
```
|
|
81
48
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
recreate the SNS share.
|
|
85
|
-
version: 1.5.0
|
|
49
|
+
**Note:** The embed displays a snapshot of the data at the time the SNS share was created. To update the data, recreate the SNS share.
|
|
50
|
+
version: 1.7.0
|
|
86
51
|
license:
|
|
87
52
|
name: MIT
|
|
88
53
|
servers:
|
|
@@ -100,11 +65,9 @@ paths:
|
|
|
100
65
|
operationId: getHealth
|
|
101
66
|
tags:
|
|
102
67
|
- Health
|
|
103
|
-
# Public — the health check is unauthenticated in the implementation.
|
|
104
|
-
# Override the global BearerAuth requirement so it stays open.
|
|
105
68
|
security: []
|
|
106
69
|
responses:
|
|
107
|
-
|
|
70
|
+
"200":
|
|
108
71
|
description: API is healthy
|
|
109
72
|
content:
|
|
110
73
|
application/json:
|
|
@@ -133,7 +96,7 @@ paths:
|
|
|
133
96
|
tags:
|
|
134
97
|
- User
|
|
135
98
|
responses:
|
|
136
|
-
|
|
99
|
+
"200":
|
|
137
100
|
description: Current user profile
|
|
138
101
|
content:
|
|
139
102
|
application/json:
|
|
@@ -146,11 +109,11 @@ paths:
|
|
|
146
109
|
- true
|
|
147
110
|
example: true
|
|
148
111
|
data:
|
|
149
|
-
$ref:
|
|
150
|
-
|
|
151
|
-
$ref:
|
|
152
|
-
|
|
153
|
-
$ref:
|
|
112
|
+
$ref: "#/components/schemas/User"
|
|
113
|
+
"401":
|
|
114
|
+
$ref: "#/components/responses/Unauthorized"
|
|
115
|
+
"500":
|
|
116
|
+
$ref: "#/components/responses/InternalError"
|
|
154
117
|
/records:
|
|
155
118
|
get:
|
|
156
119
|
summary: Get all records
|
|
@@ -161,9 +124,19 @@ paths:
|
|
|
161
124
|
parameters:
|
|
162
125
|
- name: name
|
|
163
126
|
in: query
|
|
164
|
-
description: Filter by record name
|
|
127
|
+
description: "Filter by record name. A name is unique only per owner: a tag shared with you can have the same name as one of your own, and this then matches both. Use `tag_id` to pick exactly one tag."
|
|
165
128
|
schema:
|
|
166
129
|
type: string
|
|
130
|
+
- name: tag_id
|
|
131
|
+
in: query
|
|
132
|
+
description: Filter by tag id; repeat the parameter for several tags. An id names exactly one tag, so unlike `name` it cannot mix in a same-named tag of another owner. When `tag_id` is given, `name` is ignored. An id of a tag you cannot read (neither yours nor shared with you) matches nothing.
|
|
133
|
+
style: form
|
|
134
|
+
explode: true
|
|
135
|
+
schema:
|
|
136
|
+
type: array
|
|
137
|
+
items:
|
|
138
|
+
type: integer
|
|
139
|
+
minimum: 1
|
|
167
140
|
- name: start_date
|
|
168
141
|
in: query
|
|
169
142
|
description: Filter by start date (ISO 8601)
|
|
@@ -178,7 +151,7 @@ paths:
|
|
|
178
151
|
format: date-time
|
|
179
152
|
- name: limit
|
|
180
153
|
in: query
|
|
181
|
-
description:
|
|
154
|
+
description: "Maximum number of records to return for unbounded queries (max: 1000). When start_date or end_date is supplied, all records in the range are returned — the date filter itself bounds the payload."
|
|
182
155
|
schema:
|
|
183
156
|
type: integer
|
|
184
157
|
default: 100
|
|
@@ -190,14 +163,14 @@ paths:
|
|
|
190
163
|
type: integer
|
|
191
164
|
default: 0
|
|
192
165
|
responses:
|
|
193
|
-
|
|
166
|
+
"200":
|
|
194
167
|
description: List of records
|
|
195
168
|
content:
|
|
196
169
|
application/json:
|
|
197
170
|
schema:
|
|
198
|
-
$ref:
|
|
199
|
-
|
|
200
|
-
$ref:
|
|
171
|
+
$ref: "#/components/schemas/RecordListResponse"
|
|
172
|
+
"500":
|
|
173
|
+
$ref: "#/components/responses/InternalError"
|
|
201
174
|
post:
|
|
202
175
|
summary: Create a new record
|
|
203
176
|
description: Create a new time-series record
|
|
@@ -209,18 +182,18 @@ paths:
|
|
|
209
182
|
content:
|
|
210
183
|
application/json:
|
|
211
184
|
schema:
|
|
212
|
-
$ref:
|
|
185
|
+
$ref: "#/components/schemas/CreateRecordInput"
|
|
213
186
|
responses:
|
|
214
|
-
|
|
187
|
+
"201":
|
|
215
188
|
description: Record created successfully
|
|
216
189
|
content:
|
|
217
190
|
application/json:
|
|
218
191
|
schema:
|
|
219
|
-
$ref:
|
|
220
|
-
|
|
221
|
-
$ref:
|
|
222
|
-
|
|
223
|
-
$ref:
|
|
192
|
+
$ref: "#/components/schemas/RecordResponse"
|
|
193
|
+
"400":
|
|
194
|
+
$ref: "#/components/responses/ValidationError"
|
|
195
|
+
"500":
|
|
196
|
+
$ref: "#/components/responses/InternalError"
|
|
224
197
|
/records/{id}:
|
|
225
198
|
get:
|
|
226
199
|
summary: Get a single record
|
|
@@ -229,18 +202,18 @@ paths:
|
|
|
229
202
|
tags:
|
|
230
203
|
- Records
|
|
231
204
|
parameters:
|
|
232
|
-
- $ref:
|
|
205
|
+
- $ref: "#/components/parameters/RecordId"
|
|
233
206
|
responses:
|
|
234
|
-
|
|
207
|
+
"200":
|
|
235
208
|
description: Record details
|
|
236
209
|
content:
|
|
237
210
|
application/json:
|
|
238
211
|
schema:
|
|
239
|
-
$ref:
|
|
240
|
-
|
|
241
|
-
$ref:
|
|
242
|
-
|
|
243
|
-
$ref:
|
|
212
|
+
$ref: "#/components/schemas/RecordResponse"
|
|
213
|
+
"404":
|
|
214
|
+
$ref: "#/components/responses/NotFound"
|
|
215
|
+
"500":
|
|
216
|
+
$ref: "#/components/responses/InternalError"
|
|
244
217
|
put:
|
|
245
218
|
summary: Update a record
|
|
246
219
|
description: Update an existing record by ID
|
|
@@ -248,26 +221,26 @@ paths:
|
|
|
248
221
|
tags:
|
|
249
222
|
- Records
|
|
250
223
|
parameters:
|
|
251
|
-
- $ref:
|
|
224
|
+
- $ref: "#/components/parameters/RecordId"
|
|
252
225
|
requestBody:
|
|
253
226
|
required: true
|
|
254
227
|
content:
|
|
255
228
|
application/json:
|
|
256
229
|
schema:
|
|
257
|
-
$ref:
|
|
230
|
+
$ref: "#/components/schemas/UpdateRecordInput"
|
|
258
231
|
responses:
|
|
259
|
-
|
|
232
|
+
"200":
|
|
260
233
|
description: Record updated successfully
|
|
261
234
|
content:
|
|
262
235
|
application/json:
|
|
263
236
|
schema:
|
|
264
|
-
$ref:
|
|
265
|
-
|
|
266
|
-
$ref:
|
|
267
|
-
|
|
268
|
-
$ref:
|
|
269
|
-
|
|
270
|
-
$ref:
|
|
237
|
+
$ref: "#/components/schemas/RecordResponse"
|
|
238
|
+
"400":
|
|
239
|
+
$ref: "#/components/responses/ValidationError"
|
|
240
|
+
"404":
|
|
241
|
+
$ref: "#/components/responses/NotFound"
|
|
242
|
+
"500":
|
|
243
|
+
$ref: "#/components/responses/InternalError"
|
|
271
244
|
delete:
|
|
272
245
|
summary: Delete a record
|
|
273
246
|
description: Delete a record by ID
|
|
@@ -275,9 +248,9 @@ paths:
|
|
|
275
248
|
tags:
|
|
276
249
|
- Records
|
|
277
250
|
parameters:
|
|
278
|
-
- $ref:
|
|
251
|
+
- $ref: "#/components/parameters/RecordId"
|
|
279
252
|
responses:
|
|
280
|
-
|
|
253
|
+
"200":
|
|
281
254
|
description: Record deleted successfully
|
|
282
255
|
content:
|
|
283
256
|
application/json:
|
|
@@ -297,10 +270,10 @@ paths:
|
|
|
297
270
|
enum:
|
|
298
271
|
- true
|
|
299
272
|
example: true
|
|
300
|
-
|
|
301
|
-
$ref:
|
|
302
|
-
|
|
303
|
-
$ref:
|
|
273
|
+
"404":
|
|
274
|
+
$ref: "#/components/responses/NotFound"
|
|
275
|
+
"500":
|
|
276
|
+
$ref: "#/components/responses/InternalError"
|
|
304
277
|
/records/{id}/visibility:
|
|
305
278
|
patch:
|
|
306
279
|
summary: Toggle record visibility
|
|
@@ -309,7 +282,7 @@ paths:
|
|
|
309
282
|
tags:
|
|
310
283
|
- Records
|
|
311
284
|
parameters:
|
|
312
|
-
- $ref:
|
|
285
|
+
- $ref: "#/components/parameters/RecordId"
|
|
313
286
|
requestBody:
|
|
314
287
|
required: true
|
|
315
288
|
content:
|
|
@@ -322,7 +295,7 @@ paths:
|
|
|
322
295
|
required:
|
|
323
296
|
- hide
|
|
324
297
|
responses:
|
|
325
|
-
|
|
298
|
+
"200":
|
|
326
299
|
description: Visibility updated
|
|
327
300
|
content:
|
|
328
301
|
application/json:
|
|
@@ -342,10 +315,10 @@ paths:
|
|
|
342
315
|
is_hidden:
|
|
343
316
|
type: integer
|
|
344
317
|
description: 0 = visible, 1 = hidden
|
|
345
|
-
|
|
346
|
-
$ref:
|
|
347
|
-
|
|
348
|
-
$ref:
|
|
318
|
+
"404":
|
|
319
|
+
$ref: "#/components/responses/NotFound"
|
|
320
|
+
"500":
|
|
321
|
+
$ref: "#/components/responses/InternalError"
|
|
349
322
|
/records/bulk-delete:
|
|
350
323
|
post:
|
|
351
324
|
summary: Bulk delete records
|
|
@@ -372,7 +345,7 @@ paths:
|
|
|
372
345
|
required:
|
|
373
346
|
- ids
|
|
374
347
|
responses:
|
|
375
|
-
|
|
348
|
+
"200":
|
|
376
349
|
description: Records deleted successfully
|
|
377
350
|
content:
|
|
378
351
|
application/json:
|
|
@@ -390,10 +363,10 @@ paths:
|
|
|
390
363
|
deleted:
|
|
391
364
|
type: integer
|
|
392
365
|
description: Number of records deleted
|
|
393
|
-
|
|
394
|
-
$ref:
|
|
395
|
-
|
|
396
|
-
$ref:
|
|
366
|
+
"400":
|
|
367
|
+
$ref: "#/components/responses/ValidationError"
|
|
368
|
+
"500":
|
|
369
|
+
$ref: "#/components/responses/InternalError"
|
|
397
370
|
/tags:
|
|
398
371
|
get:
|
|
399
372
|
summary: Get all tags
|
|
@@ -402,7 +375,7 @@ paths:
|
|
|
402
375
|
tags:
|
|
403
376
|
- Tags
|
|
404
377
|
responses:
|
|
405
|
-
|
|
378
|
+
"200":
|
|
406
379
|
description: List of tags
|
|
407
380
|
content:
|
|
408
381
|
application/json:
|
|
@@ -420,11 +393,11 @@ paths:
|
|
|
420
393
|
data:
|
|
421
394
|
type: array
|
|
422
395
|
items:
|
|
423
|
-
$ref:
|
|
396
|
+
$ref: "#/components/schemas/Tag"
|
|
424
397
|
total:
|
|
425
398
|
type: integer
|
|
426
|
-
|
|
427
|
-
$ref:
|
|
399
|
+
"500":
|
|
400
|
+
$ref: "#/components/responses/InternalError"
|
|
428
401
|
/tags/{id}:
|
|
429
402
|
put:
|
|
430
403
|
summary: Update a tag
|
|
@@ -451,10 +424,7 @@ paths:
|
|
|
451
424
|
unit:
|
|
452
425
|
type: string
|
|
453
426
|
nullable: true
|
|
454
|
-
description:
|
|
455
|
-
Unit of measurement. For a `time`-typed tag, must be
|
|
456
|
-
`hour`, `minute`, or `second`, controlling whether the
|
|
457
|
-
value formats as H:MM:SS, MM:SS, or decimal seconds.
|
|
427
|
+
description: Unit of measurement. For a `time`-typed tag, must be `hour`, `minute`, or `second`, controlling whether the value formats as H:MM:SS, MM:SS, or decimal seconds.
|
|
458
428
|
chart_type:
|
|
459
429
|
type: string
|
|
460
430
|
enum:
|
|
@@ -463,24 +433,14 @@ paths:
|
|
|
463
433
|
- step
|
|
464
434
|
data_type:
|
|
465
435
|
type: string
|
|
466
|
-
description:
|
|
467
|
-
The scale every stored value is written against (a `time` tag's 90 means 90
|
|
468
|
-
minutes). Changing it does NOT convert existing values, so it is
|
|
469
|
-
accepted only when no stored value would change meaning: widening
|
|
470
|
-
(`integer` → `decimal`) is always allowed, narrowing only while every
|
|
471
|
-
stored value is representable in the new type, and moving into or out of
|
|
472
|
-
`time` never is once the tag holds data. Otherwise the request is refused
|
|
473
|
-
with 409 `TAG_HAS_DATA`, whose `error.details.reason` carries the same
|
|
474
|
-
code as `Tag.data_type_options[].reason`. Read `data_type_options` off
|
|
475
|
-
`GET /tags` rather than re-deriving this. Sending the tag's current value
|
|
476
|
-
is not a change and is always accepted.
|
|
436
|
+
description: "The scale every stored value is written against (a `time` tag's 90 means 90 minutes). Changing it does NOT convert existing values, so it is accepted only when no stored value would change meaning: widening (`integer` → `decimal`) is always allowed, narrowing only while every stored value is representable in the new type, and moving into or out of `time` never is once the tag holds data. Otherwise the request is refused with 409 `TAG_HAS_DATA`, whose `error.details.reason` carries the same code as `Tag.data_type_options[].reason`. Read `data_type_options` off `GET /tags` rather than re-deriving this. Sending the tag's current value is not a change and is always accepted."
|
|
477
437
|
enum:
|
|
478
438
|
- binary
|
|
479
439
|
- decimal
|
|
480
440
|
- integer
|
|
481
441
|
- time
|
|
482
442
|
responses:
|
|
483
|
-
|
|
443
|
+
"200":
|
|
484
444
|
description: Tag updated successfully
|
|
485
445
|
content:
|
|
486
446
|
application/json:
|
|
@@ -493,27 +453,22 @@ paths:
|
|
|
493
453
|
- true
|
|
494
454
|
example: true
|
|
495
455
|
data:
|
|
496
|
-
$ref:
|
|
497
|
-
|
|
498
|
-
$ref:
|
|
499
|
-
|
|
500
|
-
description:
|
|
501
|
-
Refused: the requested `data_type` would change the meaning of values
|
|
502
|
-
already stored. `error.details.reason` is one of `SCALE_CHANGE`,
|
|
503
|
-
`NON_INTEGER_VALUES`, `NON_BINARY_VALUES`.
|
|
456
|
+
$ref: "#/components/schemas/Tag"
|
|
457
|
+
"404":
|
|
458
|
+
$ref: "#/components/responses/NotFound"
|
|
459
|
+
"409":
|
|
460
|
+
description: "Refused: the requested `data_type` would change the meaning of values already stored. `error.details.reason` is one of `SCALE_CHANGE`, `NON_INTEGER_VALUES`, `NON_BINARY_VALUES`."
|
|
504
461
|
content:
|
|
505
462
|
application/json:
|
|
506
463
|
schema:
|
|
507
|
-
$ref:
|
|
464
|
+
$ref: "#/components/schemas/ErrorResponse"
|
|
508
465
|
example:
|
|
509
466
|
success: false
|
|
510
467
|
error:
|
|
511
468
|
code: TAG_HAS_DATA
|
|
512
|
-
message:
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
'500':
|
|
516
|
-
$ref: '#/components/responses/InternalError'
|
|
469
|
+
message: "Cannot change data_type: this tag already has records or goals written against its current scale."
|
|
470
|
+
"500":
|
|
471
|
+
$ref: "#/components/responses/InternalError"
|
|
517
472
|
delete:
|
|
518
473
|
summary: Delete a tag
|
|
519
474
|
description: Delete a tag and all associated records by ID
|
|
@@ -528,7 +483,7 @@ paths:
|
|
|
528
483
|
type: integer
|
|
529
484
|
minimum: 1
|
|
530
485
|
responses:
|
|
531
|
-
|
|
486
|
+
"200":
|
|
532
487
|
description: Tag deleted successfully
|
|
533
488
|
content:
|
|
534
489
|
application/json:
|
|
@@ -548,10 +503,10 @@ paths:
|
|
|
548
503
|
enum:
|
|
549
504
|
- true
|
|
550
505
|
example: true
|
|
551
|
-
|
|
552
|
-
$ref:
|
|
553
|
-
|
|
554
|
-
$ref:
|
|
506
|
+
"404":
|
|
507
|
+
$ref: "#/components/responses/NotFound"
|
|
508
|
+
"500":
|
|
509
|
+
$ref: "#/components/responses/InternalError"
|
|
555
510
|
/tags/{id}/visibility:
|
|
556
511
|
patch:
|
|
557
512
|
summary: Toggle tag visibility
|
|
@@ -578,7 +533,7 @@ paths:
|
|
|
578
533
|
required:
|
|
579
534
|
- hide
|
|
580
535
|
responses:
|
|
581
|
-
|
|
536
|
+
"200":
|
|
582
537
|
description: Visibility updated
|
|
583
538
|
content:
|
|
584
539
|
application/json:
|
|
@@ -591,11 +546,11 @@ paths:
|
|
|
591
546
|
- true
|
|
592
547
|
example: true
|
|
593
548
|
data:
|
|
594
|
-
$ref:
|
|
595
|
-
|
|
596
|
-
$ref:
|
|
597
|
-
|
|
598
|
-
$ref:
|
|
549
|
+
$ref: "#/components/schemas/Tag"
|
|
550
|
+
"404":
|
|
551
|
+
$ref: "#/components/responses/NotFound"
|
|
552
|
+
"500":
|
|
553
|
+
$ref: "#/components/responses/InternalError"
|
|
599
554
|
/tags/bulk-delete:
|
|
600
555
|
post:
|
|
601
556
|
summary: Bulk delete tags
|
|
@@ -622,7 +577,7 @@ paths:
|
|
|
622
577
|
required:
|
|
623
578
|
- ids
|
|
624
579
|
responses:
|
|
625
|
-
|
|
580
|
+
"200":
|
|
626
581
|
description: Tags deleted successfully
|
|
627
582
|
content:
|
|
628
583
|
application/json:
|
|
@@ -640,10 +595,10 @@ paths:
|
|
|
640
595
|
deleted:
|
|
641
596
|
type: integer
|
|
642
597
|
description: Number of tags deleted
|
|
643
|
-
|
|
644
|
-
$ref:
|
|
645
|
-
|
|
646
|
-
$ref:
|
|
598
|
+
"400":
|
|
599
|
+
$ref: "#/components/responses/ValidationError"
|
|
600
|
+
"500":
|
|
601
|
+
$ref: "#/components/responses/InternalError"
|
|
647
602
|
/shares:
|
|
648
603
|
get:
|
|
649
604
|
summary: Get my shares
|
|
@@ -652,7 +607,7 @@ paths:
|
|
|
652
607
|
tags:
|
|
653
608
|
- Shares
|
|
654
609
|
responses:
|
|
655
|
-
|
|
610
|
+
"200":
|
|
656
611
|
description: List of shares
|
|
657
612
|
content:
|
|
658
613
|
application/json:
|
|
@@ -670,18 +625,14 @@ paths:
|
|
|
670
625
|
data:
|
|
671
626
|
type: array
|
|
672
627
|
items:
|
|
673
|
-
$ref:
|
|
628
|
+
$ref: "#/components/schemas/Share"
|
|
674
629
|
total:
|
|
675
630
|
type: integer
|
|
676
|
-
|
|
677
|
-
$ref:
|
|
631
|
+
"500":
|
|
632
|
+
$ref: "#/components/responses/InternalError"
|
|
678
633
|
post:
|
|
679
634
|
summary: Create a share (sends approval email)
|
|
680
|
-
description:
|
|
681
|
-
Create a tag share addressed to another user by email. The share is created in status `pending` and does NOT
|
|
682
|
-
grant data access until the recipient clicks the approval link in the invitation email delivered via the Account
|
|
683
|
-
API (Resend). Invitations expire after 7 days; after expiry the recipient must be re-invited. The raw invitation
|
|
684
|
-
token is never stored — only a SHA-256 hash — so even database access does not expose reusable accept links.
|
|
635
|
+
description: Create a tag share addressed to another user by email. The share is created in status `pending` and does NOT grant data access until the recipient clicks the approval link in the invitation email delivered via the Account API (Resend). Invitations expire after 7 days; after expiry the recipient must be re-invited. The raw invitation token is never stored — only a SHA-256 hash — so even database access does not expose reusable accept links.
|
|
685
636
|
operationId: createShare
|
|
686
637
|
tags:
|
|
687
638
|
- Shares
|
|
@@ -707,7 +658,7 @@ paths:
|
|
|
707
658
|
- shared_with_email
|
|
708
659
|
- permission
|
|
709
660
|
responses:
|
|
710
|
-
|
|
661
|
+
"201":
|
|
711
662
|
description: Share created successfully
|
|
712
663
|
content:
|
|
713
664
|
application/json:
|
|
@@ -720,18 +671,15 @@ paths:
|
|
|
720
671
|
- true
|
|
721
672
|
example: true
|
|
722
673
|
data:
|
|
723
|
-
$ref:
|
|
724
|
-
|
|
725
|
-
$ref:
|
|
726
|
-
|
|
727
|
-
$ref:
|
|
674
|
+
$ref: "#/components/schemas/Share"
|
|
675
|
+
"400":
|
|
676
|
+
$ref: "#/components/responses/ValidationError"
|
|
677
|
+
"500":
|
|
678
|
+
$ref: "#/components/responses/InternalError"
|
|
728
679
|
/shares/with-me:
|
|
729
680
|
get:
|
|
730
681
|
summary: Get shares shared with me
|
|
731
|
-
description:
|
|
732
|
-
Retrieve shares that other users have shared with the authenticated user. Returns only `accepted` shares by
|
|
733
|
-
default. Pass `?status=pending` to list invitations awaiting approval, `?status=rejected` for declined
|
|
734
|
-
invitations, or `?status=all` for every row.
|
|
682
|
+
description: Retrieve shares that other users have shared with the authenticated user. Returns only `accepted` shares by default. Pass `?status=pending` to list invitations awaiting approval, `?status=rejected` for declined invitations, or `?status=all` for every row.
|
|
735
683
|
operationId: getSharedWithMe
|
|
736
684
|
tags:
|
|
737
685
|
- Shares
|
|
@@ -749,7 +697,7 @@ paths:
|
|
|
749
697
|
default: accepted
|
|
750
698
|
description: Filter by approval status.
|
|
751
699
|
responses:
|
|
752
|
-
|
|
700
|
+
"200":
|
|
753
701
|
description: List of shares shared with the user
|
|
754
702
|
content:
|
|
755
703
|
application/json:
|
|
@@ -767,11 +715,11 @@ paths:
|
|
|
767
715
|
data:
|
|
768
716
|
type: array
|
|
769
717
|
items:
|
|
770
|
-
$ref:
|
|
718
|
+
$ref: "#/components/schemas/Share"
|
|
771
719
|
total:
|
|
772
720
|
type: integer
|
|
773
|
-
|
|
774
|
-
$ref:
|
|
721
|
+
"500":
|
|
722
|
+
$ref: "#/components/responses/InternalError"
|
|
775
723
|
/shares/{id}:
|
|
776
724
|
put:
|
|
777
725
|
summary: Update a share
|
|
@@ -804,7 +752,7 @@ paths:
|
|
|
804
752
|
- tag_id
|
|
805
753
|
- permission
|
|
806
754
|
responses:
|
|
807
|
-
|
|
755
|
+
"200":
|
|
808
756
|
description: Share updated
|
|
809
757
|
content:
|
|
810
758
|
application/json:
|
|
@@ -817,11 +765,11 @@ paths:
|
|
|
817
765
|
- true
|
|
818
766
|
example: true
|
|
819
767
|
data:
|
|
820
|
-
$ref:
|
|
821
|
-
|
|
822
|
-
$ref:
|
|
823
|
-
|
|
824
|
-
$ref:
|
|
768
|
+
$ref: "#/components/schemas/Share"
|
|
769
|
+
"404":
|
|
770
|
+
$ref: "#/components/responses/NotFound"
|
|
771
|
+
"500":
|
|
772
|
+
$ref: "#/components/responses/InternalError"
|
|
825
773
|
delete:
|
|
826
774
|
summary: Delete a share
|
|
827
775
|
description: Delete a share by ID
|
|
@@ -836,7 +784,7 @@ paths:
|
|
|
836
784
|
type: integer
|
|
837
785
|
minimum: 1
|
|
838
786
|
responses:
|
|
839
|
-
|
|
787
|
+
"200":
|
|
840
788
|
description: Share deleted
|
|
841
789
|
content:
|
|
842
790
|
application/json:
|
|
@@ -856,10 +804,10 @@ paths:
|
|
|
856
804
|
enum:
|
|
857
805
|
- true
|
|
858
806
|
example: true
|
|
859
|
-
|
|
860
|
-
$ref:
|
|
861
|
-
|
|
862
|
-
$ref:
|
|
807
|
+
"404":
|
|
808
|
+
$ref: "#/components/responses/NotFound"
|
|
809
|
+
"500":
|
|
810
|
+
$ref: "#/components/responses/InternalError"
|
|
863
811
|
/shares/{id}/visibility:
|
|
864
812
|
patch:
|
|
865
813
|
summary: Toggle share visibility
|
|
@@ -886,7 +834,7 @@ paths:
|
|
|
886
834
|
required:
|
|
887
835
|
- is_hidden
|
|
888
836
|
responses:
|
|
889
|
-
|
|
837
|
+
"200":
|
|
890
838
|
description: Visibility updated
|
|
891
839
|
content:
|
|
892
840
|
application/json:
|
|
@@ -899,11 +847,11 @@ paths:
|
|
|
899
847
|
- true
|
|
900
848
|
example: true
|
|
901
849
|
data:
|
|
902
|
-
$ref:
|
|
903
|
-
|
|
904
|
-
$ref:
|
|
905
|
-
|
|
906
|
-
$ref:
|
|
850
|
+
$ref: "#/components/schemas/Share"
|
|
851
|
+
"404":
|
|
852
|
+
$ref: "#/components/responses/NotFound"
|
|
853
|
+
"500":
|
|
854
|
+
$ref: "#/components/responses/InternalError"
|
|
907
855
|
/shares/{id}/pause:
|
|
908
856
|
patch:
|
|
909
857
|
summary: Toggle share paused status
|
|
@@ -930,7 +878,7 @@ paths:
|
|
|
930
878
|
required:
|
|
931
879
|
- is_paused
|
|
932
880
|
responses:
|
|
933
|
-
|
|
881
|
+
"200":
|
|
934
882
|
description: Paused status updated
|
|
935
883
|
content:
|
|
936
884
|
application/json:
|
|
@@ -943,11 +891,11 @@ paths:
|
|
|
943
891
|
- true
|
|
944
892
|
example: true
|
|
945
893
|
data:
|
|
946
|
-
$ref:
|
|
947
|
-
|
|
948
|
-
$ref:
|
|
949
|
-
|
|
950
|
-
$ref:
|
|
894
|
+
$ref: "#/components/schemas/Share"
|
|
895
|
+
"404":
|
|
896
|
+
$ref: "#/components/responses/NotFound"
|
|
897
|
+
"500":
|
|
898
|
+
$ref: "#/components/responses/InternalError"
|
|
951
899
|
/shares/{id}/transfer:
|
|
952
900
|
post:
|
|
953
901
|
summary: Transfer tag ownership
|
|
@@ -963,7 +911,7 @@ paths:
|
|
|
963
911
|
type: integer
|
|
964
912
|
minimum: 1
|
|
965
913
|
responses:
|
|
966
|
-
|
|
914
|
+
"200":
|
|
967
915
|
description: Ownership transferred successfully
|
|
968
916
|
content:
|
|
969
917
|
application/json:
|
|
@@ -983,10 +931,10 @@ paths:
|
|
|
983
931
|
enum:
|
|
984
932
|
- true
|
|
985
933
|
example: true
|
|
986
|
-
|
|
987
|
-
$ref:
|
|
988
|
-
|
|
989
|
-
$ref:
|
|
934
|
+
"404":
|
|
935
|
+
$ref: "#/components/responses/NotFound"
|
|
936
|
+
"500":
|
|
937
|
+
$ref: "#/components/responses/InternalError"
|
|
990
938
|
/shares/bulk-delete:
|
|
991
939
|
post:
|
|
992
940
|
summary: Bulk delete shares
|
|
@@ -1013,7 +961,7 @@ paths:
|
|
|
1013
961
|
required:
|
|
1014
962
|
- ids
|
|
1015
963
|
responses:
|
|
1016
|
-
|
|
964
|
+
"200":
|
|
1017
965
|
description: Shares deleted successfully
|
|
1018
966
|
content:
|
|
1019
967
|
application/json:
|
|
@@ -1030,17 +978,14 @@ paths:
|
|
|
1030
978
|
properties:
|
|
1031
979
|
deleted:
|
|
1032
980
|
type: integer
|
|
1033
|
-
|
|
1034
|
-
$ref:
|
|
1035
|
-
|
|
1036
|
-
$ref:
|
|
981
|
+
"400":
|
|
982
|
+
$ref: "#/components/responses/ValidationError"
|
|
983
|
+
"500":
|
|
984
|
+
$ref: "#/components/responses/InternalError"
|
|
1037
985
|
/shares/accept:
|
|
1038
986
|
post:
|
|
1039
987
|
summary: Accept a pending share invitation
|
|
1040
|
-
description:
|
|
1041
|
-
Called from the /share/accept frontend page after the recipient clicks the link in their invitation email.
|
|
1042
|
-
Requires the authenticated user to be the invited recipient (`shared_with_user_id`). On success the share
|
|
1043
|
-
transitions from `pending` to `accepted` and data access is enabled.
|
|
988
|
+
description: Called from the /share/accept frontend page after the recipient clicks the link in their invitation email. Requires the authenticated user to be the invited recipient (`shared_with_user_id`). On success the share transitions from `pending` to `accepted` and data access is enabled.
|
|
1044
989
|
operationId: acceptShare
|
|
1045
990
|
tags:
|
|
1046
991
|
- Shares
|
|
@@ -1057,7 +1002,7 @@ paths:
|
|
|
1057
1002
|
required:
|
|
1058
1003
|
- token
|
|
1059
1004
|
responses:
|
|
1060
|
-
|
|
1005
|
+
"200":
|
|
1061
1006
|
description: Share accepted
|
|
1062
1007
|
content:
|
|
1063
1008
|
application/json:
|
|
@@ -1080,18 +1025,14 @@ paths:
|
|
|
1080
1025
|
already:
|
|
1081
1026
|
type: boolean
|
|
1082
1027
|
description: True if the share was already accepted.
|
|
1083
|
-
|
|
1084
|
-
$ref:
|
|
1085
|
-
|
|
1086
|
-
$ref:
|
|
1028
|
+
"400":
|
|
1029
|
+
$ref: "#/components/responses/ValidationError"
|
|
1030
|
+
"404":
|
|
1031
|
+
$ref: "#/components/responses/NotFound"
|
|
1087
1032
|
/shares/reject:
|
|
1088
1033
|
post:
|
|
1089
1034
|
summary: Decline a pending share invitation via emailed token
|
|
1090
|
-
description:
|
|
1091
|
-
Called from the /share/reject frontend page after the recipient clicks the decline link in their invitation
|
|
1092
|
-
email. Same token and auth model as /shares/accept (requires the authenticated user to be the invited
|
|
1093
|
-
recipient); on success the share transitions from `pending` to `rejected`. Cannot be used on already-accepted
|
|
1094
|
-
shares (delete instead, via DELETE /shares/{id}).
|
|
1035
|
+
description: Called from the /share/reject frontend page after the recipient clicks the decline link in their invitation email. Same token and auth model as /shares/accept (requires the authenticated user to be the invited recipient); on success the share transitions from `pending` to `rejected`. Cannot be used on already-accepted shares (delete instead, via DELETE /shares/{id}).
|
|
1095
1036
|
operationId: rejectShareByToken
|
|
1096
1037
|
tags:
|
|
1097
1038
|
- Shares
|
|
@@ -1108,7 +1049,7 @@ paths:
|
|
|
1108
1049
|
required:
|
|
1109
1050
|
- token
|
|
1110
1051
|
responses:
|
|
1111
|
-
|
|
1052
|
+
"200":
|
|
1112
1053
|
description: Share rejected
|
|
1113
1054
|
content:
|
|
1114
1055
|
application/json:
|
|
@@ -1131,16 +1072,14 @@ paths:
|
|
|
1131
1072
|
already:
|
|
1132
1073
|
type: boolean
|
|
1133
1074
|
description: True if the share was already rejected.
|
|
1134
|
-
|
|
1135
|
-
$ref:
|
|
1136
|
-
|
|
1137
|
-
$ref:
|
|
1075
|
+
"400":
|
|
1076
|
+
$ref: "#/components/responses/ValidationError"
|
|
1077
|
+
"404":
|
|
1078
|
+
$ref: "#/components/responses/NotFound"
|
|
1138
1079
|
/shares/{id}/reject:
|
|
1139
1080
|
post:
|
|
1140
1081
|
summary: Reject a pending share invitation
|
|
1141
|
-
description:
|
|
1142
|
-
Called from the recipient's SharingManager UI. Marks the share as `rejected`; cannot be used on already-accepted
|
|
1143
|
-
shares (delete instead).
|
|
1082
|
+
description: Called from the recipient's SharingManager UI. Marks the share as `rejected`; cannot be used on already-accepted shares (delete instead).
|
|
1144
1083
|
operationId: rejectShare
|
|
1145
1084
|
tags:
|
|
1146
1085
|
- Shares
|
|
@@ -1151,7 +1090,7 @@ paths:
|
|
|
1151
1090
|
schema:
|
|
1152
1091
|
type: integer
|
|
1153
1092
|
responses:
|
|
1154
|
-
|
|
1093
|
+
"200":
|
|
1155
1094
|
description: Share rejected
|
|
1156
1095
|
content:
|
|
1157
1096
|
application/json:
|
|
@@ -1171,10 +1110,10 @@ paths:
|
|
|
1171
1110
|
type: string
|
|
1172
1111
|
enum:
|
|
1173
1112
|
- rejected
|
|
1174
|
-
|
|
1175
|
-
$ref:
|
|
1176
|
-
|
|
1177
|
-
$ref:
|
|
1113
|
+
"400":
|
|
1114
|
+
$ref: "#/components/responses/ValidationError"
|
|
1115
|
+
"404":
|
|
1116
|
+
$ref: "#/components/responses/NotFound"
|
|
1178
1117
|
/shared-graphs:
|
|
1179
1118
|
get:
|
|
1180
1119
|
summary: Get my shared graphs
|
|
@@ -1183,7 +1122,7 @@ paths:
|
|
|
1183
1122
|
tags:
|
|
1184
1123
|
- Shared Graphs
|
|
1185
1124
|
responses:
|
|
1186
|
-
|
|
1125
|
+
"200":
|
|
1187
1126
|
description: List of shared graphs
|
|
1188
1127
|
content:
|
|
1189
1128
|
application/json:
|
|
@@ -1198,9 +1137,9 @@ paths:
|
|
|
1198
1137
|
data:
|
|
1199
1138
|
type: array
|
|
1200
1139
|
items:
|
|
1201
|
-
$ref:
|
|
1202
|
-
|
|
1203
|
-
$ref:
|
|
1140
|
+
$ref: "#/components/schemas/SharedGraph"
|
|
1141
|
+
"500":
|
|
1142
|
+
$ref: "#/components/responses/InternalError"
|
|
1204
1143
|
post:
|
|
1205
1144
|
summary: Create a shared graph
|
|
1206
1145
|
description: Create a publicly shareable graph snapshot for SNS sharing
|
|
@@ -1212,9 +1151,9 @@ paths:
|
|
|
1212
1151
|
content:
|
|
1213
1152
|
application/json:
|
|
1214
1153
|
schema:
|
|
1215
|
-
$ref:
|
|
1154
|
+
$ref: "#/components/schemas/CreateSharedGraphInput"
|
|
1216
1155
|
responses:
|
|
1217
|
-
|
|
1156
|
+
"201":
|
|
1218
1157
|
description: Shared graph created
|
|
1219
1158
|
content:
|
|
1220
1159
|
application/json:
|
|
@@ -1227,11 +1166,11 @@ paths:
|
|
|
1227
1166
|
- true
|
|
1228
1167
|
example: true
|
|
1229
1168
|
data:
|
|
1230
|
-
$ref:
|
|
1231
|
-
|
|
1232
|
-
$ref:
|
|
1233
|
-
|
|
1234
|
-
$ref:
|
|
1169
|
+
$ref: "#/components/schemas/SharedGraph"
|
|
1170
|
+
"400":
|
|
1171
|
+
$ref: "#/components/responses/ValidationError"
|
|
1172
|
+
"500":
|
|
1173
|
+
$ref: "#/components/responses/InternalError"
|
|
1235
1174
|
/shared-graphs/{id}:
|
|
1236
1175
|
put:
|
|
1237
1176
|
summary: Update a shared graph
|
|
@@ -1257,7 +1196,7 @@ paths:
|
|
|
1257
1196
|
description:
|
|
1258
1197
|
type: string
|
|
1259
1198
|
responses:
|
|
1260
|
-
|
|
1199
|
+
"200":
|
|
1261
1200
|
description: Shared graph updated
|
|
1262
1201
|
content:
|
|
1263
1202
|
application/json:
|
|
@@ -1270,11 +1209,11 @@ paths:
|
|
|
1270
1209
|
- true
|
|
1271
1210
|
example: true
|
|
1272
1211
|
data:
|
|
1273
|
-
$ref:
|
|
1274
|
-
|
|
1275
|
-
$ref:
|
|
1276
|
-
|
|
1277
|
-
$ref:
|
|
1212
|
+
$ref: "#/components/schemas/SharedGraph"
|
|
1213
|
+
"404":
|
|
1214
|
+
$ref: "#/components/responses/NotFound"
|
|
1215
|
+
"500":
|
|
1216
|
+
$ref: "#/components/responses/InternalError"
|
|
1278
1217
|
delete:
|
|
1279
1218
|
summary: Delete a shared graph
|
|
1280
1219
|
description: Delete a shared graph by ID
|
|
@@ -1288,7 +1227,7 @@ paths:
|
|
|
1288
1227
|
schema:
|
|
1289
1228
|
type: string
|
|
1290
1229
|
responses:
|
|
1291
|
-
|
|
1230
|
+
"200":
|
|
1292
1231
|
description: Shared graph deleted
|
|
1293
1232
|
content:
|
|
1294
1233
|
application/json:
|
|
@@ -1308,10 +1247,10 @@ paths:
|
|
|
1308
1247
|
enum:
|
|
1309
1248
|
- true
|
|
1310
1249
|
example: true
|
|
1311
|
-
|
|
1312
|
-
$ref:
|
|
1313
|
-
|
|
1314
|
-
$ref:
|
|
1250
|
+
"404":
|
|
1251
|
+
$ref: "#/components/responses/NotFound"
|
|
1252
|
+
"500":
|
|
1253
|
+
$ref: "#/components/responses/InternalError"
|
|
1315
1254
|
/shared-graphs/{id}/toggle:
|
|
1316
1255
|
patch:
|
|
1317
1256
|
summary: Toggle shared graph active status
|
|
@@ -1326,7 +1265,7 @@ paths:
|
|
|
1326
1265
|
schema:
|
|
1327
1266
|
type: string
|
|
1328
1267
|
responses:
|
|
1329
|
-
|
|
1268
|
+
"200":
|
|
1330
1269
|
description: Status toggled
|
|
1331
1270
|
content:
|
|
1332
1271
|
application/json:
|
|
@@ -1344,10 +1283,10 @@ paths:
|
|
|
1344
1283
|
is_active:
|
|
1345
1284
|
type: integer
|
|
1346
1285
|
description: 1 for active, 0 for inactive
|
|
1347
|
-
|
|
1348
|
-
$ref:
|
|
1349
|
-
|
|
1350
|
-
$ref:
|
|
1286
|
+
"404":
|
|
1287
|
+
$ref: "#/components/responses/NotFound"
|
|
1288
|
+
"500":
|
|
1289
|
+
$ref: "#/components/responses/InternalError"
|
|
1351
1290
|
/shared-graphs/bulk-delete:
|
|
1352
1291
|
post:
|
|
1353
1292
|
summary: Bulk delete shared graphs
|
|
@@ -1373,7 +1312,7 @@ paths:
|
|
|
1373
1312
|
required:
|
|
1374
1313
|
- ids
|
|
1375
1314
|
responses:
|
|
1376
|
-
|
|
1315
|
+
"200":
|
|
1377
1316
|
description: Shared graphs deleted
|
|
1378
1317
|
content:
|
|
1379
1318
|
application/json:
|
|
@@ -1390,10 +1329,10 @@ paths:
|
|
|
1390
1329
|
properties:
|
|
1391
1330
|
deleted:
|
|
1392
1331
|
type: integer
|
|
1393
|
-
|
|
1394
|
-
$ref:
|
|
1395
|
-
|
|
1396
|
-
$ref:
|
|
1332
|
+
"400":
|
|
1333
|
+
$ref: "#/components/responses/ValidationError"
|
|
1334
|
+
"500":
|
|
1335
|
+
$ref: "#/components/responses/InternalError"
|
|
1397
1336
|
/public/shared-graphs/{id}:
|
|
1398
1337
|
get:
|
|
1399
1338
|
summary: Get public shared graph
|
|
@@ -1409,7 +1348,7 @@ paths:
|
|
|
1409
1348
|
schema:
|
|
1410
1349
|
type: string
|
|
1411
1350
|
responses:
|
|
1412
|
-
|
|
1351
|
+
"200":
|
|
1413
1352
|
description: Shared graph public data
|
|
1414
1353
|
content:
|
|
1415
1354
|
application/json:
|
|
@@ -1422,9 +1361,9 @@ paths:
|
|
|
1422
1361
|
- true
|
|
1423
1362
|
example: true
|
|
1424
1363
|
data:
|
|
1425
|
-
$ref:
|
|
1426
|
-
|
|
1427
|
-
$ref:
|
|
1364
|
+
$ref: "#/components/schemas/SharedGraphPublic"
|
|
1365
|
+
"404":
|
|
1366
|
+
$ref: "#/components/responses/NotFound"
|
|
1428
1367
|
/public/shared-graphs/{id}/og-image:
|
|
1429
1368
|
get:
|
|
1430
1369
|
summary: Generate OG image for shared graph
|
|
@@ -1440,15 +1379,15 @@ paths:
|
|
|
1440
1379
|
schema:
|
|
1441
1380
|
type: string
|
|
1442
1381
|
responses:
|
|
1443
|
-
|
|
1382
|
+
"200":
|
|
1444
1383
|
description: OG image
|
|
1445
1384
|
content:
|
|
1446
1385
|
image/png:
|
|
1447
1386
|
schema:
|
|
1448
1387
|
type: string
|
|
1449
1388
|
format: binary
|
|
1450
|
-
|
|
1451
|
-
$ref:
|
|
1389
|
+
"404":
|
|
1390
|
+
$ref: "#/components/responses/NotFound"
|
|
1452
1391
|
/records/export:
|
|
1453
1392
|
get:
|
|
1454
1393
|
summary: Export records as CSV
|
|
@@ -1475,7 +1414,7 @@ paths:
|
|
|
1475
1414
|
type: string
|
|
1476
1415
|
format: date-time
|
|
1477
1416
|
responses:
|
|
1478
|
-
|
|
1417
|
+
"200":
|
|
1479
1418
|
description: CSV file containing records
|
|
1480
1419
|
content:
|
|
1481
1420
|
text/csv:
|
|
@@ -1485,8 +1424,8 @@ paths:
|
|
|
1485
1424
|
example: |-
|
|
1486
1425
|
Tag,Value,Unit,Recorded At
|
|
1487
1426
|
"temperature",25.5,"°C","2024-01-01T10:00:00Z"
|
|
1488
|
-
|
|
1489
|
-
$ref:
|
|
1427
|
+
"500":
|
|
1428
|
+
$ref: "#/components/responses/InternalError"
|
|
1490
1429
|
/records/import:
|
|
1491
1430
|
post:
|
|
1492
1431
|
summary: Import records from CSV
|
|
@@ -1504,47 +1443,52 @@ paths:
|
|
|
1504
1443
|
file:
|
|
1505
1444
|
type: string
|
|
1506
1445
|
format: binary
|
|
1507
|
-
description:
|
|
1446
|
+
description: "CSV file to import (columns: Tag, Value, Unit, Recorded At)"
|
|
1508
1447
|
required:
|
|
1509
1448
|
- file
|
|
1510
1449
|
responses:
|
|
1511
|
-
|
|
1450
|
+
"200":
|
|
1512
1451
|
description: Import completed successfully
|
|
1513
1452
|
content:
|
|
1514
1453
|
application/json:
|
|
1515
1454
|
schema:
|
|
1516
|
-
$ref:
|
|
1517
|
-
|
|
1518
|
-
$ref:
|
|
1519
|
-
|
|
1520
|
-
$ref:
|
|
1455
|
+
$ref: "#/components/schemas/ImportResponse"
|
|
1456
|
+
"400":
|
|
1457
|
+
$ref: "#/components/responses/ValidationError"
|
|
1458
|
+
"500":
|
|
1459
|
+
$ref: "#/components/responses/InternalError"
|
|
1521
1460
|
/records/stats:
|
|
1522
1461
|
get:
|
|
1523
1462
|
summary: Get record statistics
|
|
1524
|
-
description: Get aggregated statistics for records
|
|
1463
|
+
description: Get aggregated statistics for the records of one tag, picked by `name` or, unambiguously, by `tag_id`. Send one of the two.
|
|
1525
1464
|
operationId: getRecordStats
|
|
1526
1465
|
tags:
|
|
1527
1466
|
- Statistics
|
|
1528
1467
|
parameters:
|
|
1529
1468
|
- name: name
|
|
1530
1469
|
in: query
|
|
1531
|
-
|
|
1532
|
-
description: Record name to get statistics for
|
|
1470
|
+
description: Record name to get statistics for. A name is unique only per owner, so a tag shared with you can share it with one of your own; prefer `tag_id`.
|
|
1533
1471
|
schema:
|
|
1534
1472
|
type: string
|
|
1473
|
+
- name: tag_id
|
|
1474
|
+
in: query
|
|
1475
|
+
description: Id of the tag to get statistics for. When given, `name` is ignored. An id of a tag you cannot read matches nothing.
|
|
1476
|
+
schema:
|
|
1477
|
+
type: integer
|
|
1478
|
+
minimum: 1
|
|
1535
1479
|
responses:
|
|
1536
|
-
|
|
1480
|
+
"200":
|
|
1537
1481
|
description: Statistics for the specified record name
|
|
1538
1482
|
content:
|
|
1539
1483
|
application/json:
|
|
1540
1484
|
schema:
|
|
1541
|
-
$ref:
|
|
1542
|
-
|
|
1543
|
-
$ref:
|
|
1544
|
-
|
|
1545
|
-
$ref:
|
|
1546
|
-
|
|
1547
|
-
$ref:
|
|
1485
|
+
$ref: "#/components/schemas/StatsResponse"
|
|
1486
|
+
"400":
|
|
1487
|
+
$ref: "#/components/responses/ValidationError"
|
|
1488
|
+
"404":
|
|
1489
|
+
$ref: "#/components/responses/NotFound"
|
|
1490
|
+
"500":
|
|
1491
|
+
$ref: "#/components/responses/InternalError"
|
|
1548
1492
|
/media/upload:
|
|
1549
1493
|
post:
|
|
1550
1494
|
summary: Upload media file
|
|
@@ -1566,7 +1510,7 @@ paths:
|
|
|
1566
1510
|
required:
|
|
1567
1511
|
- file
|
|
1568
1512
|
responses:
|
|
1569
|
-
|
|
1513
|
+
"200":
|
|
1570
1514
|
description: File uploaded successfully
|
|
1571
1515
|
content:
|
|
1572
1516
|
application/json:
|
|
@@ -1603,10 +1547,10 @@ paths:
|
|
|
1603
1547
|
contentType:
|
|
1604
1548
|
type: string
|
|
1605
1549
|
description: MIME content type
|
|
1606
|
-
|
|
1607
|
-
$ref:
|
|
1608
|
-
|
|
1609
|
-
$ref:
|
|
1550
|
+
"400":
|
|
1551
|
+
$ref: "#/components/responses/ValidationError"
|
|
1552
|
+
"500":
|
|
1553
|
+
$ref: "#/components/responses/InternalError"
|
|
1610
1554
|
/media/upload-url:
|
|
1611
1555
|
post:
|
|
1612
1556
|
summary: Get upload URL info
|
|
@@ -1635,7 +1579,7 @@ paths:
|
|
|
1635
1579
|
- contentType
|
|
1636
1580
|
- size
|
|
1637
1581
|
responses:
|
|
1638
|
-
|
|
1582
|
+
"200":
|
|
1639
1583
|
description: Upload URL info
|
|
1640
1584
|
content:
|
|
1641
1585
|
application/json:
|
|
@@ -1660,10 +1604,10 @@ paths:
|
|
|
1660
1604
|
type: string
|
|
1661
1605
|
example: direct
|
|
1662
1606
|
description: Upload method
|
|
1663
|
-
|
|
1664
|
-
$ref:
|
|
1665
|
-
|
|
1666
|
-
$ref:
|
|
1607
|
+
"400":
|
|
1608
|
+
$ref: "#/components/responses/ValidationError"
|
|
1609
|
+
"500":
|
|
1610
|
+
$ref: "#/components/responses/InternalError"
|
|
1667
1611
|
/media/signed-url/{key}:
|
|
1668
1612
|
get:
|
|
1669
1613
|
summary: Get signed URL for media access
|
|
@@ -1679,7 +1623,7 @@ paths:
|
|
|
1679
1623
|
schema:
|
|
1680
1624
|
type: string
|
|
1681
1625
|
responses:
|
|
1682
|
-
|
|
1626
|
+
"200":
|
|
1683
1627
|
description: Signed URL
|
|
1684
1628
|
content:
|
|
1685
1629
|
application/json:
|
|
@@ -1697,10 +1641,10 @@ paths:
|
|
|
1697
1641
|
signedUrl:
|
|
1698
1642
|
type: string
|
|
1699
1643
|
description: Signed URL for accessing the media file
|
|
1700
|
-
|
|
1701
|
-
$ref:
|
|
1702
|
-
|
|
1703
|
-
$ref:
|
|
1644
|
+
"404":
|
|
1645
|
+
$ref: "#/components/responses/NotFound"
|
|
1646
|
+
"500":
|
|
1647
|
+
$ref: "#/components/responses/InternalError"
|
|
1704
1648
|
/media/delete/{key}:
|
|
1705
1649
|
delete:
|
|
1706
1650
|
summary: Delete media file
|
|
@@ -1716,7 +1660,7 @@ paths:
|
|
|
1716
1660
|
schema:
|
|
1717
1661
|
type: string
|
|
1718
1662
|
responses:
|
|
1719
|
-
|
|
1663
|
+
"200":
|
|
1720
1664
|
description: Media file deleted
|
|
1721
1665
|
content:
|
|
1722
1666
|
application/json:
|
|
@@ -1736,10 +1680,10 @@ paths:
|
|
|
1736
1680
|
enum:
|
|
1737
1681
|
- true
|
|
1738
1682
|
example: true
|
|
1739
|
-
|
|
1740
|
-
$ref:
|
|
1741
|
-
|
|
1742
|
-
$ref:
|
|
1683
|
+
"404":
|
|
1684
|
+
$ref: "#/components/responses/NotFound"
|
|
1685
|
+
"500":
|
|
1686
|
+
$ref: "#/components/responses/InternalError"
|
|
1743
1687
|
/goals:
|
|
1744
1688
|
get:
|
|
1745
1689
|
summary: List all goals
|
|
@@ -1748,7 +1692,7 @@ paths:
|
|
|
1748
1692
|
tags:
|
|
1749
1693
|
- Goals
|
|
1750
1694
|
responses:
|
|
1751
|
-
|
|
1695
|
+
"200":
|
|
1752
1696
|
description: List of goals
|
|
1753
1697
|
content:
|
|
1754
1698
|
application/json:
|
|
@@ -1766,11 +1710,11 @@ paths:
|
|
|
1766
1710
|
data:
|
|
1767
1711
|
type: array
|
|
1768
1712
|
items:
|
|
1769
|
-
$ref:
|
|
1713
|
+
$ref: "#/components/schemas/Goal"
|
|
1770
1714
|
total:
|
|
1771
1715
|
type: integer
|
|
1772
|
-
|
|
1773
|
-
$ref:
|
|
1716
|
+
"500":
|
|
1717
|
+
$ref: "#/components/responses/InternalError"
|
|
1774
1718
|
post:
|
|
1775
1719
|
summary: Create a new goal
|
|
1776
1720
|
description: Create a new goal for the authenticated user
|
|
@@ -1782,9 +1726,9 @@ paths:
|
|
|
1782
1726
|
content:
|
|
1783
1727
|
application/json:
|
|
1784
1728
|
schema:
|
|
1785
|
-
$ref:
|
|
1729
|
+
$ref: "#/components/schemas/CreateGoalInput"
|
|
1786
1730
|
responses:
|
|
1787
|
-
|
|
1731
|
+
"201":
|
|
1788
1732
|
description: Goal created successfully
|
|
1789
1733
|
content:
|
|
1790
1734
|
application/json:
|
|
@@ -1797,11 +1741,11 @@ paths:
|
|
|
1797
1741
|
- true
|
|
1798
1742
|
example: true
|
|
1799
1743
|
data:
|
|
1800
|
-
$ref:
|
|
1801
|
-
|
|
1802
|
-
$ref:
|
|
1803
|
-
|
|
1804
|
-
$ref:
|
|
1744
|
+
$ref: "#/components/schemas/Goal"
|
|
1745
|
+
"400":
|
|
1746
|
+
$ref: "#/components/responses/ValidationError"
|
|
1747
|
+
"500":
|
|
1748
|
+
$ref: "#/components/responses/InternalError"
|
|
1805
1749
|
/goals/{id}:
|
|
1806
1750
|
put:
|
|
1807
1751
|
summary: Update a goal
|
|
@@ -1821,9 +1765,9 @@ paths:
|
|
|
1821
1765
|
content:
|
|
1822
1766
|
application/json:
|
|
1823
1767
|
schema:
|
|
1824
|
-
$ref:
|
|
1768
|
+
$ref: "#/components/schemas/UpdateGoalInput"
|
|
1825
1769
|
responses:
|
|
1826
|
-
|
|
1770
|
+
"200":
|
|
1827
1771
|
description: Goal updated successfully
|
|
1828
1772
|
content:
|
|
1829
1773
|
application/json:
|
|
@@ -1836,13 +1780,13 @@ paths:
|
|
|
1836
1780
|
- true
|
|
1837
1781
|
example: true
|
|
1838
1782
|
data:
|
|
1839
|
-
$ref:
|
|
1840
|
-
|
|
1841
|
-
$ref:
|
|
1842
|
-
|
|
1843
|
-
$ref:
|
|
1844
|
-
|
|
1845
|
-
$ref:
|
|
1783
|
+
$ref: "#/components/schemas/Goal"
|
|
1784
|
+
"400":
|
|
1785
|
+
$ref: "#/components/responses/ValidationError"
|
|
1786
|
+
"404":
|
|
1787
|
+
$ref: "#/components/responses/NotFound"
|
|
1788
|
+
"500":
|
|
1789
|
+
$ref: "#/components/responses/InternalError"
|
|
1846
1790
|
delete:
|
|
1847
1791
|
summary: Delete a goal
|
|
1848
1792
|
description: Delete a goal by ID
|
|
@@ -1857,7 +1801,7 @@ paths:
|
|
|
1857
1801
|
type: integer
|
|
1858
1802
|
minimum: 1
|
|
1859
1803
|
responses:
|
|
1860
|
-
|
|
1804
|
+
"200":
|
|
1861
1805
|
description: Goal deleted successfully
|
|
1862
1806
|
content:
|
|
1863
1807
|
application/json:
|
|
@@ -1877,10 +1821,10 @@ paths:
|
|
|
1877
1821
|
enum:
|
|
1878
1822
|
- true
|
|
1879
1823
|
example: true
|
|
1880
|
-
|
|
1881
|
-
$ref:
|
|
1882
|
-
|
|
1883
|
-
$ref:
|
|
1824
|
+
"404":
|
|
1825
|
+
$ref: "#/components/responses/NotFound"
|
|
1826
|
+
"500":
|
|
1827
|
+
$ref: "#/components/responses/InternalError"
|
|
1884
1828
|
/goals/bulk-delete:
|
|
1885
1829
|
post:
|
|
1886
1830
|
summary: Bulk delete goals
|
|
@@ -1907,7 +1851,7 @@ paths:
|
|
|
1907
1851
|
required:
|
|
1908
1852
|
- ids
|
|
1909
1853
|
responses:
|
|
1910
|
-
|
|
1854
|
+
"200":
|
|
1911
1855
|
description: Goals deleted successfully
|
|
1912
1856
|
content:
|
|
1913
1857
|
application/json:
|
|
@@ -1925,21 +1869,19 @@ paths:
|
|
|
1925
1869
|
deleted:
|
|
1926
1870
|
type: integer
|
|
1927
1871
|
description: Number of goals deleted
|
|
1928
|
-
|
|
1929
|
-
$ref:
|
|
1930
|
-
|
|
1931
|
-
$ref:
|
|
1872
|
+
"400":
|
|
1873
|
+
$ref: "#/components/responses/ValidationError"
|
|
1874
|
+
"500":
|
|
1875
|
+
$ref: "#/components/responses/InternalError"
|
|
1932
1876
|
/goals/progress:
|
|
1933
1877
|
get:
|
|
1934
1878
|
summary: Get goal progress
|
|
1935
|
-
description:
|
|
1936
|
-
Retrieve progress for all visible goals of the authenticated user. Computes current values from latest records,
|
|
1937
|
-
including virtual tags (e.g. BMI). Used by NASEBANAL Target for cross-app goal tracking.
|
|
1879
|
+
description: Retrieve progress for all visible goals of the authenticated user. Computes current values from latest records, including virtual tags (e.g. BMI). Used by NASEBANAL Target for cross-app goal tracking.
|
|
1938
1880
|
operationId: getGoalProgress
|
|
1939
1881
|
tags:
|
|
1940
1882
|
- Goals
|
|
1941
1883
|
responses:
|
|
1942
|
-
|
|
1884
|
+
"200":
|
|
1943
1885
|
description: Goal progress list
|
|
1944
1886
|
content:
|
|
1945
1887
|
application/json:
|
|
@@ -1957,9 +1899,9 @@ paths:
|
|
|
1957
1899
|
data:
|
|
1958
1900
|
type: array
|
|
1959
1901
|
items:
|
|
1960
|
-
$ref:
|
|
1961
|
-
|
|
1962
|
-
$ref:
|
|
1902
|
+
$ref: "#/components/schemas/GoalProgress"
|
|
1903
|
+
"500":
|
|
1904
|
+
$ref: "#/components/responses/InternalError"
|
|
1963
1905
|
/goals/{id}/visibility:
|
|
1964
1906
|
patch:
|
|
1965
1907
|
summary: Toggle goal visibility
|
|
@@ -1986,7 +1928,7 @@ paths:
|
|
|
1986
1928
|
required:
|
|
1987
1929
|
- hide
|
|
1988
1930
|
responses:
|
|
1989
|
-
|
|
1931
|
+
"200":
|
|
1990
1932
|
description: Visibility updated
|
|
1991
1933
|
content:
|
|
1992
1934
|
application/json:
|
|
@@ -1999,11 +1941,11 @@ paths:
|
|
|
1999
1941
|
- true
|
|
2000
1942
|
example: true
|
|
2001
1943
|
data:
|
|
2002
|
-
$ref:
|
|
2003
|
-
|
|
2004
|
-
$ref:
|
|
2005
|
-
|
|
2006
|
-
$ref:
|
|
1944
|
+
$ref: "#/components/schemas/Goal"
|
|
1945
|
+
"404":
|
|
1946
|
+
$ref: "#/components/responses/NotFound"
|
|
1947
|
+
"500":
|
|
1948
|
+
$ref: "#/components/responses/InternalError"
|
|
2007
1949
|
components:
|
|
2008
1950
|
securitySchemes:
|
|
2009
1951
|
BearerAuth:
|
|
@@ -2075,10 +2017,7 @@ components:
|
|
|
2075
2017
|
unit:
|
|
2076
2018
|
type: string
|
|
2077
2019
|
nullable: true
|
|
2078
|
-
description:
|
|
2079
|
-
Unit of measurement. For a `time`-typed tag, `hour`, `minute`, or
|
|
2080
|
-
`second`, controlling whether the value formats as H:MM:SS,
|
|
2081
|
-
MM:SS, or decimal seconds.
|
|
2020
|
+
description: Unit of measurement. For a `time`-typed tag, `hour`, `minute`, or `second`, controlling whether the value formats as H:MM:SS, MM:SS, or decimal seconds.
|
|
2082
2021
|
recorded_at:
|
|
2083
2022
|
type: string
|
|
2084
2023
|
format: date-time
|
|
@@ -2093,15 +2032,10 @@ components:
|
|
|
2093
2032
|
description: Timestamp when the record was last updated
|
|
2094
2033
|
owner_email:
|
|
2095
2034
|
type: string
|
|
2096
|
-
description:
|
|
2097
|
-
Email of the tag's owner. Set on the caller's own rows too (it then
|
|
2098
|
-
holds the caller's own address), so compare it with the caller's to
|
|
2099
|
-
tell shared-in data apart.
|
|
2035
|
+
description: Email of the tag's owner. Set on the caller's own rows too (it then holds the caller's own address), so compare it with the caller's to tell shared-in data apart.
|
|
2100
2036
|
owner_name:
|
|
2101
2037
|
type: string
|
|
2102
|
-
description:
|
|
2103
|
-
Display name the owner set in their profile. Absent when they set
|
|
2104
|
-
none. Clients name the owner by this, falling back to a masked email.
|
|
2038
|
+
description: Display name the owner set in their profile. Absent when they set none. Clients name the owner by this, falling back to a masked email.
|
|
2105
2039
|
required:
|
|
2106
2040
|
- id
|
|
2107
2041
|
- name
|
|
@@ -2122,10 +2056,7 @@ components:
|
|
|
2122
2056
|
example: 25.5
|
|
2123
2057
|
unit:
|
|
2124
2058
|
type: string
|
|
2125
|
-
description:
|
|
2126
|
-
Unit of measurement. For a `time`-typed tag, must be `hour`,
|
|
2127
|
-
`minute`, or `second`, controlling whether the value formats as
|
|
2128
|
-
H:MM:SS, MM:SS, or decimal seconds.
|
|
2059
|
+
description: Unit of measurement. For a `time`-typed tag, must be `hour`, `minute`, or `second`, controlling whether the value formats as H:MM:SS, MM:SS, or decimal seconds.
|
|
2129
2060
|
example: °C
|
|
2130
2061
|
recorded_at:
|
|
2131
2062
|
type: string
|
|
@@ -2145,10 +2076,7 @@ components:
|
|
|
2145
2076
|
description: Numeric value
|
|
2146
2077
|
unit:
|
|
2147
2078
|
type: string
|
|
2148
|
-
description:
|
|
2149
|
-
Unit of measurement. For a `time`-typed tag, must be `hour`,
|
|
2150
|
-
`minute`, or `second`, controlling whether the value formats as
|
|
2151
|
-
H:MM:SS, MM:SS, or decimal seconds.
|
|
2079
|
+
description: Unit of measurement. For a `time`-typed tag, must be `hour`, `minute`, or `second`, controlling whether the value formats as H:MM:SS, MM:SS, or decimal seconds.
|
|
2152
2080
|
recorded_at:
|
|
2153
2081
|
type: string
|
|
2154
2082
|
format: date-time
|
|
@@ -2187,7 +2115,7 @@ components:
|
|
|
2187
2115
|
latest:
|
|
2188
2116
|
description: Latest record
|
|
2189
2117
|
oneOf:
|
|
2190
|
-
- $ref:
|
|
2118
|
+
- $ref: "#/components/schemas/Record"
|
|
2191
2119
|
- type: object
|
|
2192
2120
|
nullable: true
|
|
2193
2121
|
required:
|
|
@@ -2209,7 +2137,7 @@ components:
|
|
|
2209
2137
|
- true
|
|
2210
2138
|
example: true
|
|
2211
2139
|
data:
|
|
2212
|
-
$ref:
|
|
2140
|
+
$ref: "#/components/schemas/Record"
|
|
2213
2141
|
RecordListResponse:
|
|
2214
2142
|
type: object
|
|
2215
2143
|
properties:
|
|
@@ -2224,7 +2152,7 @@ components:
|
|
|
2224
2152
|
data:
|
|
2225
2153
|
type: array
|
|
2226
2154
|
items:
|
|
2227
|
-
$ref:
|
|
2155
|
+
$ref: "#/components/schemas/Record"
|
|
2228
2156
|
total:
|
|
2229
2157
|
type: integer
|
|
2230
2158
|
description: Total number of records matching the filter
|
|
@@ -2243,7 +2171,7 @@ components:
|
|
|
2243
2171
|
- true
|
|
2244
2172
|
example: true
|
|
2245
2173
|
data:
|
|
2246
|
-
$ref:
|
|
2174
|
+
$ref: "#/components/schemas/RecordStats"
|
|
2247
2175
|
ImportResponse:
|
|
2248
2176
|
type: object
|
|
2249
2177
|
properties:
|
|
@@ -2271,6 +2199,45 @@ components:
|
|
|
2271
2199
|
- imported
|
|
2272
2200
|
- created
|
|
2273
2201
|
- updated
|
|
2202
|
+
SeriesKind:
|
|
2203
|
+
type: string
|
|
2204
|
+
enum:
|
|
2205
|
+
- raw
|
|
2206
|
+
- diff
|
|
2207
|
+
- diff_pct
|
|
2208
|
+
- sum
|
|
2209
|
+
- bmi
|
|
2210
|
+
- annual_income
|
|
2211
|
+
description: "Stable code of a derived series — not the display suffix (`/Diff` etc.). `diff` difference from the previous record, `diff_pct` percent change from the previous record, `sum` running total, `bmi` BMI (body-weight category), `annual_income` annual income (currency category). The raw tag is `raw`: it is the default on the referencing side and never appears in a `derived_series` list."
|
|
2212
|
+
DerivedSeries:
|
|
2213
|
+
type: object
|
|
2214
|
+
description: "A series derived from a tag. No row of its own: it is derived from the tag's settings (`derived_config`, `category`). Identified by the source tag's `id` plus `kind` — no name in it, so a rename cannot break a reference."
|
|
2215
|
+
properties:
|
|
2216
|
+
kind:
|
|
2217
|
+
$ref: "#/components/schemas/SeriesKind"
|
|
2218
|
+
label:
|
|
2219
|
+
type: string
|
|
2220
|
+
description: Display name (e.g. `Body Weight/BMI`). Not an identifier.
|
|
2221
|
+
unit:
|
|
2222
|
+
type: string
|
|
2223
|
+
nullable: true
|
|
2224
|
+
data_type:
|
|
2225
|
+
type: string
|
|
2226
|
+
enum:
|
|
2227
|
+
- decimal
|
|
2228
|
+
- integer
|
|
2229
|
+
- time
|
|
2230
|
+
chart_type:
|
|
2231
|
+
type: string
|
|
2232
|
+
enum:
|
|
2233
|
+
- line
|
|
2234
|
+
- smooth
|
|
2235
|
+
- step
|
|
2236
|
+
required:
|
|
2237
|
+
- kind
|
|
2238
|
+
- label
|
|
2239
|
+
- data_type
|
|
2240
|
+
- chart_type
|
|
2274
2241
|
Tag:
|
|
2275
2242
|
type: object
|
|
2276
2243
|
properties:
|
|
@@ -2283,10 +2250,7 @@ components:
|
|
|
2283
2250
|
unit:
|
|
2284
2251
|
type: string
|
|
2285
2252
|
nullable: true
|
|
2286
|
-
description:
|
|
2287
|
-
Unit of measurement. For a `time`-typed tag, must be `hour`,
|
|
2288
|
-
`minute`, or `second`, controlling whether the value formats as
|
|
2289
|
-
H:MM:SS, MM:SS, or decimal seconds.
|
|
2253
|
+
description: Unit of measurement. For a `time`-typed tag, must be `hour`, `minute`, or `second`, controlling whether the value formats as H:MM:SS, MM:SS, or decimal seconds.
|
|
2290
2254
|
data_type:
|
|
2291
2255
|
type: string
|
|
2292
2256
|
enum:
|
|
@@ -2303,16 +2267,14 @@ components:
|
|
|
2303
2267
|
is_hidden:
|
|
2304
2268
|
type: integer
|
|
2305
2269
|
description: 0 = visible, 1 = hidden
|
|
2270
|
+
derived_series:
|
|
2271
|
+
type: array
|
|
2272
|
+
description: Derived series this tag can produce. Excludes the raw series (`raw`).
|
|
2273
|
+
items:
|
|
2274
|
+
$ref: "#/components/schemas/DerivedSeries"
|
|
2306
2275
|
data_type_options:
|
|
2307
2276
|
type: array
|
|
2308
|
-
description:
|
|
2309
|
-
Which `data_type` this tag may be changed to, and why not for the
|
|
2310
|
-
rest. A change is safe exactly when no stored value changes meaning,
|
|
2311
|
-
which depends on the direction and on what is already stored — so
|
|
2312
|
-
this is server-computed rather than re-derived per client, and it
|
|
2313
|
-
carries a reason per option because the reason differs per option.
|
|
2314
|
-
A tag shared in from another user lists only its current type, not
|
|
2315
|
-
selectable: the recipient does not own the master data.
|
|
2277
|
+
description: "Which `data_type` this tag may be changed to, and why not for the rest. A change is safe exactly when no stored value changes meaning, which depends on the direction and on what is already stored — so this is server-computed rather than re-derived per client, and it carries a reason per option because the reason differs per option. A tag shared in from another user lists only its current type, not selectable: the recipient does not own the master data."
|
|
2316
2278
|
items:
|
|
2317
2279
|
type: object
|
|
2318
2280
|
properties:
|
|
@@ -2327,14 +2289,7 @@ components:
|
|
|
2327
2289
|
type: boolean
|
|
2328
2290
|
reason:
|
|
2329
2291
|
type: string
|
|
2330
|
-
description:
|
|
2331
|
-
Why this type is unavailable; absent when selectable.
|
|
2332
|
-
`SCALE_CHANGE` — into or out of `time`, whose stored minutes
|
|
2333
|
-
would be re-read rather than converted (90 becomes 1:30).
|
|
2334
|
-
`NON_INTEGER_VALUES` — a stored value is not a whole number,
|
|
2335
|
-
so it would display rounded while the stored value stays
|
|
2336
|
-
fractional. `NON_BINARY_VALUES` — a stored value is neither 0
|
|
2337
|
-
nor 1.
|
|
2292
|
+
description: Why this type is unavailable; absent when selectable. `SCALE_CHANGE` — into or out of `time`, whose stored minutes would be re-read rather than converted (90 becomes 1:30). `NON_INTEGER_VALUES` — a stored value is not a whole number, so it would display rounded while the stored value stays fractional. `NON_BINARY_VALUES` — a stored value is neither 0 nor 1.
|
|
2338
2293
|
enum:
|
|
2339
2294
|
- SCALE_CHANGE
|
|
2340
2295
|
- NON_INTEGER_VALUES
|
|
@@ -2350,15 +2305,10 @@ components:
|
|
|
2350
2305
|
format: date-time
|
|
2351
2306
|
owner_email:
|
|
2352
2307
|
type: string
|
|
2353
|
-
description:
|
|
2354
|
-
Email of the tag's owner. Set on the caller's own tags too (it then
|
|
2355
|
-
holds the caller's own address), so compare it with the caller's to
|
|
2356
|
-
tell shared-in tags apart.
|
|
2308
|
+
description: Email of the tag's owner. Set on the caller's own tags too (it then holds the caller's own address), so compare it with the caller's to tell shared-in tags apart.
|
|
2357
2309
|
owner_name:
|
|
2358
2310
|
type: string
|
|
2359
|
-
description:
|
|
2360
|
-
Display name the owner set in their profile. Absent when they set
|
|
2361
|
-
none. Clients name the owner by this, falling back to a masked email.
|
|
2311
|
+
description: Display name the owner set in their profile. Absent when they set none. Clients name the owner by this, falling back to a masked email.
|
|
2362
2312
|
required:
|
|
2363
2313
|
- id
|
|
2364
2314
|
- user_id
|
|
@@ -2392,9 +2342,7 @@ components:
|
|
|
2392
2342
|
- pending
|
|
2393
2343
|
- accepted
|
|
2394
2344
|
- rejected
|
|
2395
|
-
description:
|
|
2396
|
-
Approval status. New shares are created in 'pending' and require the recipient to click the accept link
|
|
2397
|
-
delivered via email. Only 'accepted' shares grant data access.
|
|
2345
|
+
description: Approval status. New shares are created in 'pending' and require the recipient to click the accept link delivered via email. Only 'accepted' shares grant data access.
|
|
2398
2346
|
expires_at:
|
|
2399
2347
|
type: string
|
|
2400
2348
|
format: date-time
|
|
@@ -2411,18 +2359,13 @@ components:
|
|
|
2411
2359
|
description: Email of the sharing owner. Set on shares addressed to the caller.
|
|
2412
2360
|
owner_name:
|
|
2413
2361
|
type: string
|
|
2414
|
-
description:
|
|
2415
|
-
Display name the sharing owner set in their profile. Absent when
|
|
2416
|
-
they set none.
|
|
2362
|
+
description: Display name the sharing owner set in their profile. Absent when they set none.
|
|
2417
2363
|
shared_with_email:
|
|
2418
2364
|
type: string
|
|
2419
2365
|
description: Email of the recipient. Set on shares the caller owns.
|
|
2420
2366
|
shared_with_name:
|
|
2421
2367
|
type: string
|
|
2422
|
-
description:
|
|
2423
|
-
Display name the recipient set in their profile. Set on shares the
|
|
2424
|
-
caller owns, and only once the share is `accepted`, so an invitation
|
|
2425
|
-
does not reveal the profile of someone who has not accepted it.
|
|
2368
|
+
description: Display name the recipient set in their profile. Set on shares the caller owns, and only once the share is `accepted`, so an invitation does not reveal the profile of someone who has not accepted it.
|
|
2426
2369
|
required:
|
|
2427
2370
|
- id
|
|
2428
2371
|
- owner_user_id
|
|
@@ -2560,9 +2503,7 @@ components:
|
|
|
2560
2503
|
description: Preferred language
|
|
2561
2504
|
plan:
|
|
2562
2505
|
type: string
|
|
2563
|
-
description:
|
|
2564
|
-
Plan for this service, derived from the account's subscriptions.
|
|
2565
|
-
`free` when the account holds no active subscription for Recorder.
|
|
2506
|
+
description: Plan for this service, derived from the account's subscriptions. `free` when the account holds no active subscription for Recorder.
|
|
2566
2507
|
subscription_status:
|
|
2567
2508
|
type: string
|
|
2568
2509
|
nullable: true
|
|
@@ -2605,6 +2546,10 @@ components:
|
|
|
2605
2546
|
virtual_tag_key:
|
|
2606
2547
|
type: string
|
|
2607
2548
|
nullable: true
|
|
2549
|
+
tag_kind:
|
|
2550
|
+
allOf:
|
|
2551
|
+
- $ref: "#/components/schemas/SeriesKind"
|
|
2552
|
+
description: Which series of the `tag_id` tag the goal targets. Absent or `raw` means the raw tag. Successor to `virtual_tag_key`, with no name in it.
|
|
2608
2553
|
is_hidden:
|
|
2609
2554
|
type: integer
|
|
2610
2555
|
description: 0 = visible, 1 = hidden
|
|
@@ -2660,6 +2605,10 @@ components:
|
|
|
2660
2605
|
virtual_tag_key:
|
|
2661
2606
|
type: string
|
|
2662
2607
|
description: Virtual tag key
|
|
2608
|
+
tag_kind:
|
|
2609
|
+
allOf:
|
|
2610
|
+
- $ref: "#/components/schemas/SeriesKind"
|
|
2611
|
+
description: Which series of the `tag_id` tag the goal targets. Absent or `raw` means the raw tag. Successor to `virtual_tag_key`, with no name in it.
|
|
2663
2612
|
required:
|
|
2664
2613
|
- tag_id
|
|
2665
2614
|
- goal_type
|
|
@@ -2687,6 +2636,10 @@ components:
|
|
|
2687
2636
|
type: string
|
|
2688
2637
|
virtual_tag_key:
|
|
2689
2638
|
type: string
|
|
2639
|
+
tag_kind:
|
|
2640
|
+
allOf:
|
|
2641
|
+
- $ref: "#/components/schemas/SeriesKind"
|
|
2642
|
+
description: Which series of the `tag_id` tag the goal targets. Absent or `raw` means the raw tag. Successor to `virtual_tag_key`, with no name in it.
|
|
2690
2643
|
ErrorResponse:
|
|
2691
2644
|
type: object
|
|
2692
2645
|
properties:
|
|
@@ -2714,7 +2667,7 @@ components:
|
|
|
2714
2667
|
content:
|
|
2715
2668
|
application/json:
|
|
2716
2669
|
schema:
|
|
2717
|
-
$ref:
|
|
2670
|
+
$ref: "#/components/schemas/ErrorResponse"
|
|
2718
2671
|
example:
|
|
2719
2672
|
success: false
|
|
2720
2673
|
error:
|
|
@@ -2725,7 +2678,7 @@ components:
|
|
|
2725
2678
|
content:
|
|
2726
2679
|
application/json:
|
|
2727
2680
|
schema:
|
|
2728
|
-
$ref:
|
|
2681
|
+
$ref: "#/components/schemas/ErrorResponse"
|
|
2729
2682
|
example:
|
|
2730
2683
|
success: false
|
|
2731
2684
|
error:
|
|
@@ -2736,7 +2689,7 @@ components:
|
|
|
2736
2689
|
content:
|
|
2737
2690
|
application/json:
|
|
2738
2691
|
schema:
|
|
2739
|
-
$ref:
|
|
2692
|
+
$ref: "#/components/schemas/ErrorResponse"
|
|
2740
2693
|
example:
|
|
2741
2694
|
success: false
|
|
2742
2695
|
error:
|
|
@@ -2747,7 +2700,7 @@ components:
|
|
|
2747
2700
|
content:
|
|
2748
2701
|
application/json:
|
|
2749
2702
|
schema:
|
|
2750
|
-
$ref:
|
|
2703
|
+
$ref: "#/components/schemas/ErrorResponse"
|
|
2751
2704
|
example:
|
|
2752
2705
|
success: false
|
|
2753
2706
|
error:
|