@nasebanal/cli 0.1.0 → 0.2.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.
@@ -1,87 +1,52 @@
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
 
49
-
50
- Publicly shared graphs can be embedded in external sites (blogs, portfolios, etc.) via iframe without
51
- authentication.
52
-
31
+ Publicly shared graphs can be embedded in external sites (blogs, portfolios, etc.) via iframe without authentication.
53
32
 
54
33
  **Endpoint:** `GET /shared/{lang}/{id}/embed`
55
34
 
56
-
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://recorder.nasebanal.com/shared/ja/{id}/embed\" width=\"100%\" height=\"500\" frameborder=\"0\"></iframe>
80
47
  ```
81
48
 
82
-
83
- **Note:** The embed displays a snapshot of the data at the time the SNS share was created. To update the data,
84
- recreate the SNS share.
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.
85
50
  version: 1.5.0
86
51
  license:
87
52
  name: MIT
@@ -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
- '200':
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
- '200':
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: '#/components/schemas/User'
150
- '401':
151
- $ref: '#/components/responses/Unauthorized'
152
- '500':
153
- $ref: '#/components/responses/InternalError'
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
@@ -178,7 +141,7 @@ paths:
178
141
  format: date-time
179
142
  - name: limit
180
143
  in: query
181
- 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.'
144
+ 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
145
  schema:
183
146
  type: integer
184
147
  default: 100
@@ -190,14 +153,14 @@ paths:
190
153
  type: integer
191
154
  default: 0
192
155
  responses:
193
- '200':
156
+ "200":
194
157
  description: List of records
195
158
  content:
196
159
  application/json:
197
160
  schema:
198
- $ref: '#/components/schemas/RecordListResponse'
199
- '500':
200
- $ref: '#/components/responses/InternalError'
161
+ $ref: "#/components/schemas/RecordListResponse"
162
+ "500":
163
+ $ref: "#/components/responses/InternalError"
201
164
  post:
202
165
  summary: Create a new record
203
166
  description: Create a new time-series record
@@ -209,18 +172,18 @@ paths:
209
172
  content:
210
173
  application/json:
211
174
  schema:
212
- $ref: '#/components/schemas/CreateRecordInput'
175
+ $ref: "#/components/schemas/CreateRecordInput"
213
176
  responses:
214
- '201':
177
+ "201":
215
178
  description: Record created successfully
216
179
  content:
217
180
  application/json:
218
181
  schema:
219
- $ref: '#/components/schemas/RecordResponse'
220
- '400':
221
- $ref: '#/components/responses/ValidationError'
222
- '500':
223
- $ref: '#/components/responses/InternalError'
182
+ $ref: "#/components/schemas/RecordResponse"
183
+ "400":
184
+ $ref: "#/components/responses/ValidationError"
185
+ "500":
186
+ $ref: "#/components/responses/InternalError"
224
187
  /records/{id}:
225
188
  get:
226
189
  summary: Get a single record
@@ -229,18 +192,18 @@ paths:
229
192
  tags:
230
193
  - Records
231
194
  parameters:
232
- - $ref: '#/components/parameters/RecordId'
195
+ - $ref: "#/components/parameters/RecordId"
233
196
  responses:
234
- '200':
197
+ "200":
235
198
  description: Record details
236
199
  content:
237
200
  application/json:
238
201
  schema:
239
- $ref: '#/components/schemas/RecordResponse'
240
- '404':
241
- $ref: '#/components/responses/NotFound'
242
- '500':
243
- $ref: '#/components/responses/InternalError'
202
+ $ref: "#/components/schemas/RecordResponse"
203
+ "404":
204
+ $ref: "#/components/responses/NotFound"
205
+ "500":
206
+ $ref: "#/components/responses/InternalError"
244
207
  put:
245
208
  summary: Update a record
246
209
  description: Update an existing record by ID
@@ -248,26 +211,26 @@ paths:
248
211
  tags:
249
212
  - Records
250
213
  parameters:
251
- - $ref: '#/components/parameters/RecordId'
214
+ - $ref: "#/components/parameters/RecordId"
252
215
  requestBody:
253
216
  required: true
254
217
  content:
255
218
  application/json:
256
219
  schema:
257
- $ref: '#/components/schemas/UpdateRecordInput'
220
+ $ref: "#/components/schemas/UpdateRecordInput"
258
221
  responses:
259
- '200':
222
+ "200":
260
223
  description: Record updated successfully
261
224
  content:
262
225
  application/json:
263
226
  schema:
264
- $ref: '#/components/schemas/RecordResponse'
265
- '400':
266
- $ref: '#/components/responses/ValidationError'
267
- '404':
268
- $ref: '#/components/responses/NotFound'
269
- '500':
270
- $ref: '#/components/responses/InternalError'
227
+ $ref: "#/components/schemas/RecordResponse"
228
+ "400":
229
+ $ref: "#/components/responses/ValidationError"
230
+ "404":
231
+ $ref: "#/components/responses/NotFound"
232
+ "500":
233
+ $ref: "#/components/responses/InternalError"
271
234
  delete:
272
235
  summary: Delete a record
273
236
  description: Delete a record by ID
@@ -275,9 +238,9 @@ paths:
275
238
  tags:
276
239
  - Records
277
240
  parameters:
278
- - $ref: '#/components/parameters/RecordId'
241
+ - $ref: "#/components/parameters/RecordId"
279
242
  responses:
280
- '200':
243
+ "200":
281
244
  description: Record deleted successfully
282
245
  content:
283
246
  application/json:
@@ -297,10 +260,10 @@ paths:
297
260
  enum:
298
261
  - true
299
262
  example: true
300
- '404':
301
- $ref: '#/components/responses/NotFound'
302
- '500':
303
- $ref: '#/components/responses/InternalError'
263
+ "404":
264
+ $ref: "#/components/responses/NotFound"
265
+ "500":
266
+ $ref: "#/components/responses/InternalError"
304
267
  /records/{id}/visibility:
305
268
  patch:
306
269
  summary: Toggle record visibility
@@ -309,7 +272,7 @@ paths:
309
272
  tags:
310
273
  - Records
311
274
  parameters:
312
- - $ref: '#/components/parameters/RecordId'
275
+ - $ref: "#/components/parameters/RecordId"
313
276
  requestBody:
314
277
  required: true
315
278
  content:
@@ -322,7 +285,7 @@ paths:
322
285
  required:
323
286
  - hide
324
287
  responses:
325
- '200':
288
+ "200":
326
289
  description: Visibility updated
327
290
  content:
328
291
  application/json:
@@ -342,10 +305,10 @@ paths:
342
305
  is_hidden:
343
306
  type: integer
344
307
  description: 0 = visible, 1 = hidden
345
- '404':
346
- $ref: '#/components/responses/NotFound'
347
- '500':
348
- $ref: '#/components/responses/InternalError'
308
+ "404":
309
+ $ref: "#/components/responses/NotFound"
310
+ "500":
311
+ $ref: "#/components/responses/InternalError"
349
312
  /records/bulk-delete:
350
313
  post:
351
314
  summary: Bulk delete records
@@ -372,7 +335,7 @@ paths:
372
335
  required:
373
336
  - ids
374
337
  responses:
375
- '200':
338
+ "200":
376
339
  description: Records deleted successfully
377
340
  content:
378
341
  application/json:
@@ -390,10 +353,10 @@ paths:
390
353
  deleted:
391
354
  type: integer
392
355
  description: Number of records deleted
393
- '400':
394
- $ref: '#/components/responses/ValidationError'
395
- '500':
396
- $ref: '#/components/responses/InternalError'
356
+ "400":
357
+ $ref: "#/components/responses/ValidationError"
358
+ "500":
359
+ $ref: "#/components/responses/InternalError"
397
360
  /tags:
398
361
  get:
399
362
  summary: Get all tags
@@ -402,7 +365,7 @@ paths:
402
365
  tags:
403
366
  - Tags
404
367
  responses:
405
- '200':
368
+ "200":
406
369
  description: List of tags
407
370
  content:
408
371
  application/json:
@@ -420,11 +383,11 @@ paths:
420
383
  data:
421
384
  type: array
422
385
  items:
423
- $ref: '#/components/schemas/Tag'
386
+ $ref: "#/components/schemas/Tag"
424
387
  total:
425
388
  type: integer
426
- '500':
427
- $ref: '#/components/responses/InternalError'
389
+ "500":
390
+ $ref: "#/components/responses/InternalError"
428
391
  /tags/{id}:
429
392
  put:
430
393
  summary: Update a tag
@@ -451,10 +414,7 @@ paths:
451
414
  unit:
452
415
  type: string
453
416
  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.
417
+ 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
418
  chart_type:
459
419
  type: string
460
420
  enum:
@@ -463,24 +423,14 @@ paths:
463
423
  - step
464
424
  data_type:
465
425
  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.
426
+ 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
427
  enum:
478
428
  - binary
479
429
  - decimal
480
430
  - integer
481
431
  - time
482
432
  responses:
483
- '200':
433
+ "200":
484
434
  description: Tag updated successfully
485
435
  content:
486
436
  application/json:
@@ -493,27 +443,22 @@ paths:
493
443
  - true
494
444
  example: true
495
445
  data:
496
- $ref: '#/components/schemas/Tag'
497
- '404':
498
- $ref: '#/components/responses/NotFound'
499
- '409':
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`.
446
+ $ref: "#/components/schemas/Tag"
447
+ "404":
448
+ $ref: "#/components/responses/NotFound"
449
+ "409":
450
+ 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
451
  content:
505
452
  application/json:
506
453
  schema:
507
- $ref: '#/components/schemas/ErrorResponse'
454
+ $ref: "#/components/schemas/ErrorResponse"
508
455
  example:
509
456
  success: false
510
457
  error:
511
458
  code: TAG_HAS_DATA
512
- message: >-
513
- Cannot change data_type: this tag already has records or
514
- goals written against its current scale.
515
- '500':
516
- $ref: '#/components/responses/InternalError'
459
+ message: "Cannot change data_type: this tag already has records or goals written against its current scale."
460
+ "500":
461
+ $ref: "#/components/responses/InternalError"
517
462
  delete:
518
463
  summary: Delete a tag
519
464
  description: Delete a tag and all associated records by ID
@@ -528,7 +473,7 @@ paths:
528
473
  type: integer
529
474
  minimum: 1
530
475
  responses:
531
- '200':
476
+ "200":
532
477
  description: Tag deleted successfully
533
478
  content:
534
479
  application/json:
@@ -548,10 +493,10 @@ paths:
548
493
  enum:
549
494
  - true
550
495
  example: true
551
- '404':
552
- $ref: '#/components/responses/NotFound'
553
- '500':
554
- $ref: '#/components/responses/InternalError'
496
+ "404":
497
+ $ref: "#/components/responses/NotFound"
498
+ "500":
499
+ $ref: "#/components/responses/InternalError"
555
500
  /tags/{id}/visibility:
556
501
  patch:
557
502
  summary: Toggle tag visibility
@@ -578,7 +523,7 @@ paths:
578
523
  required:
579
524
  - hide
580
525
  responses:
581
- '200':
526
+ "200":
582
527
  description: Visibility updated
583
528
  content:
584
529
  application/json:
@@ -591,11 +536,11 @@ paths:
591
536
  - true
592
537
  example: true
593
538
  data:
594
- $ref: '#/components/schemas/Tag'
595
- '404':
596
- $ref: '#/components/responses/NotFound'
597
- '500':
598
- $ref: '#/components/responses/InternalError'
539
+ $ref: "#/components/schemas/Tag"
540
+ "404":
541
+ $ref: "#/components/responses/NotFound"
542
+ "500":
543
+ $ref: "#/components/responses/InternalError"
599
544
  /tags/bulk-delete:
600
545
  post:
601
546
  summary: Bulk delete tags
@@ -622,7 +567,7 @@ paths:
622
567
  required:
623
568
  - ids
624
569
  responses:
625
- '200':
570
+ "200":
626
571
  description: Tags deleted successfully
627
572
  content:
628
573
  application/json:
@@ -640,10 +585,10 @@ paths:
640
585
  deleted:
641
586
  type: integer
642
587
  description: Number of tags deleted
643
- '400':
644
- $ref: '#/components/responses/ValidationError'
645
- '500':
646
- $ref: '#/components/responses/InternalError'
588
+ "400":
589
+ $ref: "#/components/responses/ValidationError"
590
+ "500":
591
+ $ref: "#/components/responses/InternalError"
647
592
  /shares:
648
593
  get:
649
594
  summary: Get my shares
@@ -652,7 +597,7 @@ paths:
652
597
  tags:
653
598
  - Shares
654
599
  responses:
655
- '200':
600
+ "200":
656
601
  description: List of shares
657
602
  content:
658
603
  application/json:
@@ -670,18 +615,14 @@ paths:
670
615
  data:
671
616
  type: array
672
617
  items:
673
- $ref: '#/components/schemas/Share'
618
+ $ref: "#/components/schemas/Share"
674
619
  total:
675
620
  type: integer
676
- '500':
677
- $ref: '#/components/responses/InternalError'
621
+ "500":
622
+ $ref: "#/components/responses/InternalError"
678
623
  post:
679
624
  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.
625
+ 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
626
  operationId: createShare
686
627
  tags:
687
628
  - Shares
@@ -707,7 +648,7 @@ paths:
707
648
  - shared_with_email
708
649
  - permission
709
650
  responses:
710
- '201':
651
+ "201":
711
652
  description: Share created successfully
712
653
  content:
713
654
  application/json:
@@ -720,18 +661,15 @@ paths:
720
661
  - true
721
662
  example: true
722
663
  data:
723
- $ref: '#/components/schemas/Share'
724
- '400':
725
- $ref: '#/components/responses/ValidationError'
726
- '500':
727
- $ref: '#/components/responses/InternalError'
664
+ $ref: "#/components/schemas/Share"
665
+ "400":
666
+ $ref: "#/components/responses/ValidationError"
667
+ "500":
668
+ $ref: "#/components/responses/InternalError"
728
669
  /shares/with-me:
729
670
  get:
730
671
  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.
672
+ 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
673
  operationId: getSharedWithMe
736
674
  tags:
737
675
  - Shares
@@ -749,7 +687,7 @@ paths:
749
687
  default: accepted
750
688
  description: Filter by approval status.
751
689
  responses:
752
- '200':
690
+ "200":
753
691
  description: List of shares shared with the user
754
692
  content:
755
693
  application/json:
@@ -767,11 +705,11 @@ paths:
767
705
  data:
768
706
  type: array
769
707
  items:
770
- $ref: '#/components/schemas/Share'
708
+ $ref: "#/components/schemas/Share"
771
709
  total:
772
710
  type: integer
773
- '500':
774
- $ref: '#/components/responses/InternalError'
711
+ "500":
712
+ $ref: "#/components/responses/InternalError"
775
713
  /shares/{id}:
776
714
  put:
777
715
  summary: Update a share
@@ -804,7 +742,7 @@ paths:
804
742
  - tag_id
805
743
  - permission
806
744
  responses:
807
- '200':
745
+ "200":
808
746
  description: Share updated
809
747
  content:
810
748
  application/json:
@@ -817,11 +755,11 @@ paths:
817
755
  - true
818
756
  example: true
819
757
  data:
820
- $ref: '#/components/schemas/Share'
821
- '404':
822
- $ref: '#/components/responses/NotFound'
823
- '500':
824
- $ref: '#/components/responses/InternalError'
758
+ $ref: "#/components/schemas/Share"
759
+ "404":
760
+ $ref: "#/components/responses/NotFound"
761
+ "500":
762
+ $ref: "#/components/responses/InternalError"
825
763
  delete:
826
764
  summary: Delete a share
827
765
  description: Delete a share by ID
@@ -836,7 +774,7 @@ paths:
836
774
  type: integer
837
775
  minimum: 1
838
776
  responses:
839
- '200':
777
+ "200":
840
778
  description: Share deleted
841
779
  content:
842
780
  application/json:
@@ -856,10 +794,10 @@ paths:
856
794
  enum:
857
795
  - true
858
796
  example: true
859
- '404':
860
- $ref: '#/components/responses/NotFound'
861
- '500':
862
- $ref: '#/components/responses/InternalError'
797
+ "404":
798
+ $ref: "#/components/responses/NotFound"
799
+ "500":
800
+ $ref: "#/components/responses/InternalError"
863
801
  /shares/{id}/visibility:
864
802
  patch:
865
803
  summary: Toggle share visibility
@@ -886,7 +824,7 @@ paths:
886
824
  required:
887
825
  - is_hidden
888
826
  responses:
889
- '200':
827
+ "200":
890
828
  description: Visibility updated
891
829
  content:
892
830
  application/json:
@@ -899,11 +837,11 @@ paths:
899
837
  - true
900
838
  example: true
901
839
  data:
902
- $ref: '#/components/schemas/Share'
903
- '404':
904
- $ref: '#/components/responses/NotFound'
905
- '500':
906
- $ref: '#/components/responses/InternalError'
840
+ $ref: "#/components/schemas/Share"
841
+ "404":
842
+ $ref: "#/components/responses/NotFound"
843
+ "500":
844
+ $ref: "#/components/responses/InternalError"
907
845
  /shares/{id}/pause:
908
846
  patch:
909
847
  summary: Toggle share paused status
@@ -930,7 +868,7 @@ paths:
930
868
  required:
931
869
  - is_paused
932
870
  responses:
933
- '200':
871
+ "200":
934
872
  description: Paused status updated
935
873
  content:
936
874
  application/json:
@@ -943,11 +881,11 @@ paths:
943
881
  - true
944
882
  example: true
945
883
  data:
946
- $ref: '#/components/schemas/Share'
947
- '404':
948
- $ref: '#/components/responses/NotFound'
949
- '500':
950
- $ref: '#/components/responses/InternalError'
884
+ $ref: "#/components/schemas/Share"
885
+ "404":
886
+ $ref: "#/components/responses/NotFound"
887
+ "500":
888
+ $ref: "#/components/responses/InternalError"
951
889
  /shares/{id}/transfer:
952
890
  post:
953
891
  summary: Transfer tag ownership
@@ -963,7 +901,7 @@ paths:
963
901
  type: integer
964
902
  minimum: 1
965
903
  responses:
966
- '200':
904
+ "200":
967
905
  description: Ownership transferred successfully
968
906
  content:
969
907
  application/json:
@@ -983,10 +921,10 @@ paths:
983
921
  enum:
984
922
  - true
985
923
  example: true
986
- '404':
987
- $ref: '#/components/responses/NotFound'
988
- '500':
989
- $ref: '#/components/responses/InternalError'
924
+ "404":
925
+ $ref: "#/components/responses/NotFound"
926
+ "500":
927
+ $ref: "#/components/responses/InternalError"
990
928
  /shares/bulk-delete:
991
929
  post:
992
930
  summary: Bulk delete shares
@@ -1013,7 +951,7 @@ paths:
1013
951
  required:
1014
952
  - ids
1015
953
  responses:
1016
- '200':
954
+ "200":
1017
955
  description: Shares deleted successfully
1018
956
  content:
1019
957
  application/json:
@@ -1030,17 +968,14 @@ paths:
1030
968
  properties:
1031
969
  deleted:
1032
970
  type: integer
1033
- '400':
1034
- $ref: '#/components/responses/ValidationError'
1035
- '500':
1036
- $ref: '#/components/responses/InternalError'
971
+ "400":
972
+ $ref: "#/components/responses/ValidationError"
973
+ "500":
974
+ $ref: "#/components/responses/InternalError"
1037
975
  /shares/accept:
1038
976
  post:
1039
977
  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.
978
+ 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
979
  operationId: acceptShare
1045
980
  tags:
1046
981
  - Shares
@@ -1057,7 +992,7 @@ paths:
1057
992
  required:
1058
993
  - token
1059
994
  responses:
1060
- '200':
995
+ "200":
1061
996
  description: Share accepted
1062
997
  content:
1063
998
  application/json:
@@ -1080,18 +1015,14 @@ paths:
1080
1015
  already:
1081
1016
  type: boolean
1082
1017
  description: True if the share was already accepted.
1083
- '400':
1084
- $ref: '#/components/responses/ValidationError'
1085
- '404':
1086
- $ref: '#/components/responses/NotFound'
1018
+ "400":
1019
+ $ref: "#/components/responses/ValidationError"
1020
+ "404":
1021
+ $ref: "#/components/responses/NotFound"
1087
1022
  /shares/reject:
1088
1023
  post:
1089
1024
  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}).
1025
+ 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
1026
  operationId: rejectShareByToken
1096
1027
  tags:
1097
1028
  - Shares
@@ -1108,7 +1039,7 @@ paths:
1108
1039
  required:
1109
1040
  - token
1110
1041
  responses:
1111
- '200':
1042
+ "200":
1112
1043
  description: Share rejected
1113
1044
  content:
1114
1045
  application/json:
@@ -1131,16 +1062,14 @@ paths:
1131
1062
  already:
1132
1063
  type: boolean
1133
1064
  description: True if the share was already rejected.
1134
- '400':
1135
- $ref: '#/components/responses/ValidationError'
1136
- '404':
1137
- $ref: '#/components/responses/NotFound'
1065
+ "400":
1066
+ $ref: "#/components/responses/ValidationError"
1067
+ "404":
1068
+ $ref: "#/components/responses/NotFound"
1138
1069
  /shares/{id}/reject:
1139
1070
  post:
1140
1071
  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).
1072
+ description: Called from the recipient's SharingManager UI. Marks the share as `rejected`; cannot be used on already-accepted shares (delete instead).
1144
1073
  operationId: rejectShare
1145
1074
  tags:
1146
1075
  - Shares
@@ -1151,7 +1080,7 @@ paths:
1151
1080
  schema:
1152
1081
  type: integer
1153
1082
  responses:
1154
- '200':
1083
+ "200":
1155
1084
  description: Share rejected
1156
1085
  content:
1157
1086
  application/json:
@@ -1171,10 +1100,10 @@ paths:
1171
1100
  type: string
1172
1101
  enum:
1173
1102
  - rejected
1174
- '400':
1175
- $ref: '#/components/responses/ValidationError'
1176
- '404':
1177
- $ref: '#/components/responses/NotFound'
1103
+ "400":
1104
+ $ref: "#/components/responses/ValidationError"
1105
+ "404":
1106
+ $ref: "#/components/responses/NotFound"
1178
1107
  /shared-graphs:
1179
1108
  get:
1180
1109
  summary: Get my shared graphs
@@ -1183,7 +1112,7 @@ paths:
1183
1112
  tags:
1184
1113
  - Shared Graphs
1185
1114
  responses:
1186
- '200':
1115
+ "200":
1187
1116
  description: List of shared graphs
1188
1117
  content:
1189
1118
  application/json:
@@ -1198,9 +1127,9 @@ paths:
1198
1127
  data:
1199
1128
  type: array
1200
1129
  items:
1201
- $ref: '#/components/schemas/SharedGraph'
1202
- '500':
1203
- $ref: '#/components/responses/InternalError'
1130
+ $ref: "#/components/schemas/SharedGraph"
1131
+ "500":
1132
+ $ref: "#/components/responses/InternalError"
1204
1133
  post:
1205
1134
  summary: Create a shared graph
1206
1135
  description: Create a publicly shareable graph snapshot for SNS sharing
@@ -1212,9 +1141,9 @@ paths:
1212
1141
  content:
1213
1142
  application/json:
1214
1143
  schema:
1215
- $ref: '#/components/schemas/CreateSharedGraphInput'
1144
+ $ref: "#/components/schemas/CreateSharedGraphInput"
1216
1145
  responses:
1217
- '201':
1146
+ "201":
1218
1147
  description: Shared graph created
1219
1148
  content:
1220
1149
  application/json:
@@ -1227,11 +1156,11 @@ paths:
1227
1156
  - true
1228
1157
  example: true
1229
1158
  data:
1230
- $ref: '#/components/schemas/SharedGraph'
1231
- '400':
1232
- $ref: '#/components/responses/ValidationError'
1233
- '500':
1234
- $ref: '#/components/responses/InternalError'
1159
+ $ref: "#/components/schemas/SharedGraph"
1160
+ "400":
1161
+ $ref: "#/components/responses/ValidationError"
1162
+ "500":
1163
+ $ref: "#/components/responses/InternalError"
1235
1164
  /shared-graphs/{id}:
1236
1165
  put:
1237
1166
  summary: Update a shared graph
@@ -1257,7 +1186,7 @@ paths:
1257
1186
  description:
1258
1187
  type: string
1259
1188
  responses:
1260
- '200':
1189
+ "200":
1261
1190
  description: Shared graph updated
1262
1191
  content:
1263
1192
  application/json:
@@ -1270,11 +1199,11 @@ paths:
1270
1199
  - true
1271
1200
  example: true
1272
1201
  data:
1273
- $ref: '#/components/schemas/SharedGraph'
1274
- '404':
1275
- $ref: '#/components/responses/NotFound'
1276
- '500':
1277
- $ref: '#/components/responses/InternalError'
1202
+ $ref: "#/components/schemas/SharedGraph"
1203
+ "404":
1204
+ $ref: "#/components/responses/NotFound"
1205
+ "500":
1206
+ $ref: "#/components/responses/InternalError"
1278
1207
  delete:
1279
1208
  summary: Delete a shared graph
1280
1209
  description: Delete a shared graph by ID
@@ -1288,7 +1217,7 @@ paths:
1288
1217
  schema:
1289
1218
  type: string
1290
1219
  responses:
1291
- '200':
1220
+ "200":
1292
1221
  description: Shared graph deleted
1293
1222
  content:
1294
1223
  application/json:
@@ -1308,10 +1237,10 @@ paths:
1308
1237
  enum:
1309
1238
  - true
1310
1239
  example: true
1311
- '404':
1312
- $ref: '#/components/responses/NotFound'
1313
- '500':
1314
- $ref: '#/components/responses/InternalError'
1240
+ "404":
1241
+ $ref: "#/components/responses/NotFound"
1242
+ "500":
1243
+ $ref: "#/components/responses/InternalError"
1315
1244
  /shared-graphs/{id}/toggle:
1316
1245
  patch:
1317
1246
  summary: Toggle shared graph active status
@@ -1326,7 +1255,7 @@ paths:
1326
1255
  schema:
1327
1256
  type: string
1328
1257
  responses:
1329
- '200':
1258
+ "200":
1330
1259
  description: Status toggled
1331
1260
  content:
1332
1261
  application/json:
@@ -1344,10 +1273,10 @@ paths:
1344
1273
  is_active:
1345
1274
  type: integer
1346
1275
  description: 1 for active, 0 for inactive
1347
- '404':
1348
- $ref: '#/components/responses/NotFound'
1349
- '500':
1350
- $ref: '#/components/responses/InternalError'
1276
+ "404":
1277
+ $ref: "#/components/responses/NotFound"
1278
+ "500":
1279
+ $ref: "#/components/responses/InternalError"
1351
1280
  /shared-graphs/bulk-delete:
1352
1281
  post:
1353
1282
  summary: Bulk delete shared graphs
@@ -1373,7 +1302,7 @@ paths:
1373
1302
  required:
1374
1303
  - ids
1375
1304
  responses:
1376
- '200':
1305
+ "200":
1377
1306
  description: Shared graphs deleted
1378
1307
  content:
1379
1308
  application/json:
@@ -1390,10 +1319,10 @@ paths:
1390
1319
  properties:
1391
1320
  deleted:
1392
1321
  type: integer
1393
- '400':
1394
- $ref: '#/components/responses/ValidationError'
1395
- '500':
1396
- $ref: '#/components/responses/InternalError'
1322
+ "400":
1323
+ $ref: "#/components/responses/ValidationError"
1324
+ "500":
1325
+ $ref: "#/components/responses/InternalError"
1397
1326
  /public/shared-graphs/{id}:
1398
1327
  get:
1399
1328
  summary: Get public shared graph
@@ -1409,7 +1338,7 @@ paths:
1409
1338
  schema:
1410
1339
  type: string
1411
1340
  responses:
1412
- '200':
1341
+ "200":
1413
1342
  description: Shared graph public data
1414
1343
  content:
1415
1344
  application/json:
@@ -1422,9 +1351,9 @@ paths:
1422
1351
  - true
1423
1352
  example: true
1424
1353
  data:
1425
- $ref: '#/components/schemas/SharedGraphPublic'
1426
- '404':
1427
- $ref: '#/components/responses/NotFound'
1354
+ $ref: "#/components/schemas/SharedGraphPublic"
1355
+ "404":
1356
+ $ref: "#/components/responses/NotFound"
1428
1357
  /public/shared-graphs/{id}/og-image:
1429
1358
  get:
1430
1359
  summary: Generate OG image for shared graph
@@ -1440,15 +1369,15 @@ paths:
1440
1369
  schema:
1441
1370
  type: string
1442
1371
  responses:
1443
- '200':
1372
+ "200":
1444
1373
  description: OG image
1445
1374
  content:
1446
1375
  image/png:
1447
1376
  schema:
1448
1377
  type: string
1449
1378
  format: binary
1450
- '404':
1451
- $ref: '#/components/responses/NotFound'
1379
+ "404":
1380
+ $ref: "#/components/responses/NotFound"
1452
1381
  /records/export:
1453
1382
  get:
1454
1383
  summary: Export records as CSV
@@ -1475,7 +1404,7 @@ paths:
1475
1404
  type: string
1476
1405
  format: date-time
1477
1406
  responses:
1478
- '200':
1407
+ "200":
1479
1408
  description: CSV file containing records
1480
1409
  content:
1481
1410
  text/csv:
@@ -1485,8 +1414,8 @@ paths:
1485
1414
  example: |-
1486
1415
  Tag,Value,Unit,Recorded At
1487
1416
  "temperature",25.5,"°C","2024-01-01T10:00:00Z"
1488
- '500':
1489
- $ref: '#/components/responses/InternalError'
1417
+ "500":
1418
+ $ref: "#/components/responses/InternalError"
1490
1419
  /records/import:
1491
1420
  post:
1492
1421
  summary: Import records from CSV
@@ -1504,20 +1433,20 @@ paths:
1504
1433
  file:
1505
1434
  type: string
1506
1435
  format: binary
1507
- description: 'CSV file to import (columns: Tag, Value, Unit, Recorded At)'
1436
+ description: "CSV file to import (columns: Tag, Value, Unit, Recorded At)"
1508
1437
  required:
1509
1438
  - file
1510
1439
  responses:
1511
- '200':
1440
+ "200":
1512
1441
  description: Import completed successfully
1513
1442
  content:
1514
1443
  application/json:
1515
1444
  schema:
1516
- $ref: '#/components/schemas/ImportResponse'
1517
- '400':
1518
- $ref: '#/components/responses/ValidationError'
1519
- '500':
1520
- $ref: '#/components/responses/InternalError'
1445
+ $ref: "#/components/schemas/ImportResponse"
1446
+ "400":
1447
+ $ref: "#/components/responses/ValidationError"
1448
+ "500":
1449
+ $ref: "#/components/responses/InternalError"
1521
1450
  /records/stats:
1522
1451
  get:
1523
1452
  summary: Get record statistics
@@ -1533,18 +1462,18 @@ paths:
1533
1462
  schema:
1534
1463
  type: string
1535
1464
  responses:
1536
- '200':
1465
+ "200":
1537
1466
  description: Statistics for the specified record name
1538
1467
  content:
1539
1468
  application/json:
1540
1469
  schema:
1541
- $ref: '#/components/schemas/StatsResponse'
1542
- '400':
1543
- $ref: '#/components/responses/ValidationError'
1544
- '404':
1545
- $ref: '#/components/responses/NotFound'
1546
- '500':
1547
- $ref: '#/components/responses/InternalError'
1470
+ $ref: "#/components/schemas/StatsResponse"
1471
+ "400":
1472
+ $ref: "#/components/responses/ValidationError"
1473
+ "404":
1474
+ $ref: "#/components/responses/NotFound"
1475
+ "500":
1476
+ $ref: "#/components/responses/InternalError"
1548
1477
  /media/upload:
1549
1478
  post:
1550
1479
  summary: Upload media file
@@ -1566,7 +1495,7 @@ paths:
1566
1495
  required:
1567
1496
  - file
1568
1497
  responses:
1569
- '200':
1498
+ "200":
1570
1499
  description: File uploaded successfully
1571
1500
  content:
1572
1501
  application/json:
@@ -1603,10 +1532,10 @@ paths:
1603
1532
  contentType:
1604
1533
  type: string
1605
1534
  description: MIME content type
1606
- '400':
1607
- $ref: '#/components/responses/ValidationError'
1608
- '500':
1609
- $ref: '#/components/responses/InternalError'
1535
+ "400":
1536
+ $ref: "#/components/responses/ValidationError"
1537
+ "500":
1538
+ $ref: "#/components/responses/InternalError"
1610
1539
  /media/upload-url:
1611
1540
  post:
1612
1541
  summary: Get upload URL info
@@ -1635,7 +1564,7 @@ paths:
1635
1564
  - contentType
1636
1565
  - size
1637
1566
  responses:
1638
- '200':
1567
+ "200":
1639
1568
  description: Upload URL info
1640
1569
  content:
1641
1570
  application/json:
@@ -1660,10 +1589,10 @@ paths:
1660
1589
  type: string
1661
1590
  example: direct
1662
1591
  description: Upload method
1663
- '400':
1664
- $ref: '#/components/responses/ValidationError'
1665
- '500':
1666
- $ref: '#/components/responses/InternalError'
1592
+ "400":
1593
+ $ref: "#/components/responses/ValidationError"
1594
+ "500":
1595
+ $ref: "#/components/responses/InternalError"
1667
1596
  /media/signed-url/{key}:
1668
1597
  get:
1669
1598
  summary: Get signed URL for media access
@@ -1679,7 +1608,7 @@ paths:
1679
1608
  schema:
1680
1609
  type: string
1681
1610
  responses:
1682
- '200':
1611
+ "200":
1683
1612
  description: Signed URL
1684
1613
  content:
1685
1614
  application/json:
@@ -1697,10 +1626,10 @@ paths:
1697
1626
  signedUrl:
1698
1627
  type: string
1699
1628
  description: Signed URL for accessing the media file
1700
- '404':
1701
- $ref: '#/components/responses/NotFound'
1702
- '500':
1703
- $ref: '#/components/responses/InternalError'
1629
+ "404":
1630
+ $ref: "#/components/responses/NotFound"
1631
+ "500":
1632
+ $ref: "#/components/responses/InternalError"
1704
1633
  /media/delete/{key}:
1705
1634
  delete:
1706
1635
  summary: Delete media file
@@ -1716,7 +1645,7 @@ paths:
1716
1645
  schema:
1717
1646
  type: string
1718
1647
  responses:
1719
- '200':
1648
+ "200":
1720
1649
  description: Media file deleted
1721
1650
  content:
1722
1651
  application/json:
@@ -1736,10 +1665,10 @@ paths:
1736
1665
  enum:
1737
1666
  - true
1738
1667
  example: true
1739
- '404':
1740
- $ref: '#/components/responses/NotFound'
1741
- '500':
1742
- $ref: '#/components/responses/InternalError'
1668
+ "404":
1669
+ $ref: "#/components/responses/NotFound"
1670
+ "500":
1671
+ $ref: "#/components/responses/InternalError"
1743
1672
  /goals:
1744
1673
  get:
1745
1674
  summary: List all goals
@@ -1748,7 +1677,7 @@ paths:
1748
1677
  tags:
1749
1678
  - Goals
1750
1679
  responses:
1751
- '200':
1680
+ "200":
1752
1681
  description: List of goals
1753
1682
  content:
1754
1683
  application/json:
@@ -1766,11 +1695,11 @@ paths:
1766
1695
  data:
1767
1696
  type: array
1768
1697
  items:
1769
- $ref: '#/components/schemas/Goal'
1698
+ $ref: "#/components/schemas/Goal"
1770
1699
  total:
1771
1700
  type: integer
1772
- '500':
1773
- $ref: '#/components/responses/InternalError'
1701
+ "500":
1702
+ $ref: "#/components/responses/InternalError"
1774
1703
  post:
1775
1704
  summary: Create a new goal
1776
1705
  description: Create a new goal for the authenticated user
@@ -1782,9 +1711,9 @@ paths:
1782
1711
  content:
1783
1712
  application/json:
1784
1713
  schema:
1785
- $ref: '#/components/schemas/CreateGoalInput'
1714
+ $ref: "#/components/schemas/CreateGoalInput"
1786
1715
  responses:
1787
- '201':
1716
+ "201":
1788
1717
  description: Goal created successfully
1789
1718
  content:
1790
1719
  application/json:
@@ -1797,11 +1726,11 @@ paths:
1797
1726
  - true
1798
1727
  example: true
1799
1728
  data:
1800
- $ref: '#/components/schemas/Goal'
1801
- '400':
1802
- $ref: '#/components/responses/ValidationError'
1803
- '500':
1804
- $ref: '#/components/responses/InternalError'
1729
+ $ref: "#/components/schemas/Goal"
1730
+ "400":
1731
+ $ref: "#/components/responses/ValidationError"
1732
+ "500":
1733
+ $ref: "#/components/responses/InternalError"
1805
1734
  /goals/{id}:
1806
1735
  put:
1807
1736
  summary: Update a goal
@@ -1821,9 +1750,9 @@ paths:
1821
1750
  content:
1822
1751
  application/json:
1823
1752
  schema:
1824
- $ref: '#/components/schemas/UpdateGoalInput'
1753
+ $ref: "#/components/schemas/UpdateGoalInput"
1825
1754
  responses:
1826
- '200':
1755
+ "200":
1827
1756
  description: Goal updated successfully
1828
1757
  content:
1829
1758
  application/json:
@@ -1836,13 +1765,13 @@ paths:
1836
1765
  - true
1837
1766
  example: true
1838
1767
  data:
1839
- $ref: '#/components/schemas/Goal'
1840
- '400':
1841
- $ref: '#/components/responses/ValidationError'
1842
- '404':
1843
- $ref: '#/components/responses/NotFound'
1844
- '500':
1845
- $ref: '#/components/responses/InternalError'
1768
+ $ref: "#/components/schemas/Goal"
1769
+ "400":
1770
+ $ref: "#/components/responses/ValidationError"
1771
+ "404":
1772
+ $ref: "#/components/responses/NotFound"
1773
+ "500":
1774
+ $ref: "#/components/responses/InternalError"
1846
1775
  delete:
1847
1776
  summary: Delete a goal
1848
1777
  description: Delete a goal by ID
@@ -1857,7 +1786,7 @@ paths:
1857
1786
  type: integer
1858
1787
  minimum: 1
1859
1788
  responses:
1860
- '200':
1789
+ "200":
1861
1790
  description: Goal deleted successfully
1862
1791
  content:
1863
1792
  application/json:
@@ -1877,10 +1806,10 @@ paths:
1877
1806
  enum:
1878
1807
  - true
1879
1808
  example: true
1880
- '404':
1881
- $ref: '#/components/responses/NotFound'
1882
- '500':
1883
- $ref: '#/components/responses/InternalError'
1809
+ "404":
1810
+ $ref: "#/components/responses/NotFound"
1811
+ "500":
1812
+ $ref: "#/components/responses/InternalError"
1884
1813
  /goals/bulk-delete:
1885
1814
  post:
1886
1815
  summary: Bulk delete goals
@@ -1907,7 +1836,7 @@ paths:
1907
1836
  required:
1908
1837
  - ids
1909
1838
  responses:
1910
- '200':
1839
+ "200":
1911
1840
  description: Goals deleted successfully
1912
1841
  content:
1913
1842
  application/json:
@@ -1925,21 +1854,19 @@ paths:
1925
1854
  deleted:
1926
1855
  type: integer
1927
1856
  description: Number of goals deleted
1928
- '400':
1929
- $ref: '#/components/responses/ValidationError'
1930
- '500':
1931
- $ref: '#/components/responses/InternalError'
1857
+ "400":
1858
+ $ref: "#/components/responses/ValidationError"
1859
+ "500":
1860
+ $ref: "#/components/responses/InternalError"
1932
1861
  /goals/progress:
1933
1862
  get:
1934
1863
  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.
1864
+ 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
1865
  operationId: getGoalProgress
1939
1866
  tags:
1940
1867
  - Goals
1941
1868
  responses:
1942
- '200':
1869
+ "200":
1943
1870
  description: Goal progress list
1944
1871
  content:
1945
1872
  application/json:
@@ -1957,9 +1884,9 @@ paths:
1957
1884
  data:
1958
1885
  type: array
1959
1886
  items:
1960
- $ref: '#/components/schemas/GoalProgress'
1961
- '500':
1962
- $ref: '#/components/responses/InternalError'
1887
+ $ref: "#/components/schemas/GoalProgress"
1888
+ "500":
1889
+ $ref: "#/components/responses/InternalError"
1963
1890
  /goals/{id}/visibility:
1964
1891
  patch:
1965
1892
  summary: Toggle goal visibility
@@ -1986,7 +1913,7 @@ paths:
1986
1913
  required:
1987
1914
  - hide
1988
1915
  responses:
1989
- '200':
1916
+ "200":
1990
1917
  description: Visibility updated
1991
1918
  content:
1992
1919
  application/json:
@@ -1999,11 +1926,11 @@ paths:
1999
1926
  - true
2000
1927
  example: true
2001
1928
  data:
2002
- $ref: '#/components/schemas/Goal'
2003
- '404':
2004
- $ref: '#/components/responses/NotFound'
2005
- '500':
2006
- $ref: '#/components/responses/InternalError'
1929
+ $ref: "#/components/schemas/Goal"
1930
+ "404":
1931
+ $ref: "#/components/responses/NotFound"
1932
+ "500":
1933
+ $ref: "#/components/responses/InternalError"
2007
1934
  components:
2008
1935
  securitySchemes:
2009
1936
  BearerAuth:
@@ -2075,10 +2002,7 @@ components:
2075
2002
  unit:
2076
2003
  type: string
2077
2004
  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.
2005
+ 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
2006
  recorded_at:
2083
2007
  type: string
2084
2008
  format: date-time
@@ -2093,15 +2017,10 @@ components:
2093
2017
  description: Timestamp when the record was last updated
2094
2018
  owner_email:
2095
2019
  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.
2020
+ 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
2021
  owner_name:
2101
2022
  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.
2023
+ 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
2024
  required:
2106
2025
  - id
2107
2026
  - name
@@ -2122,10 +2041,7 @@ components:
2122
2041
  example: 25.5
2123
2042
  unit:
2124
2043
  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.
2044
+ 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
2045
  example: °C
2130
2046
  recorded_at:
2131
2047
  type: string
@@ -2145,10 +2061,7 @@ components:
2145
2061
  description: Numeric value
2146
2062
  unit:
2147
2063
  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.
2064
+ 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
2065
  recorded_at:
2153
2066
  type: string
2154
2067
  format: date-time
@@ -2187,7 +2100,7 @@ components:
2187
2100
  latest:
2188
2101
  description: Latest record
2189
2102
  oneOf:
2190
- - $ref: '#/components/schemas/Record'
2103
+ - $ref: "#/components/schemas/Record"
2191
2104
  - type: object
2192
2105
  nullable: true
2193
2106
  required:
@@ -2209,7 +2122,7 @@ components:
2209
2122
  - true
2210
2123
  example: true
2211
2124
  data:
2212
- $ref: '#/components/schemas/Record'
2125
+ $ref: "#/components/schemas/Record"
2213
2126
  RecordListResponse:
2214
2127
  type: object
2215
2128
  properties:
@@ -2224,7 +2137,7 @@ components:
2224
2137
  data:
2225
2138
  type: array
2226
2139
  items:
2227
- $ref: '#/components/schemas/Record'
2140
+ $ref: "#/components/schemas/Record"
2228
2141
  total:
2229
2142
  type: integer
2230
2143
  description: Total number of records matching the filter
@@ -2243,7 +2156,7 @@ components:
2243
2156
  - true
2244
2157
  example: true
2245
2158
  data:
2246
- $ref: '#/components/schemas/RecordStats'
2159
+ $ref: "#/components/schemas/RecordStats"
2247
2160
  ImportResponse:
2248
2161
  type: object
2249
2162
  properties:
@@ -2283,10 +2196,7 @@ components:
2283
2196
  unit:
2284
2197
  type: string
2285
2198
  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.
2199
+ 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
2200
  data_type:
2291
2201
  type: string
2292
2202
  enum:
@@ -2305,14 +2215,7 @@ components:
2305
2215
  description: 0 = visible, 1 = hidden
2306
2216
  data_type_options:
2307
2217
  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.
2218
+ 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
2219
  items:
2317
2220
  type: object
2318
2221
  properties:
@@ -2327,14 +2230,7 @@ components:
2327
2230
  type: boolean
2328
2231
  reason:
2329
2232
  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.
2233
+ 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
2234
  enum:
2339
2235
  - SCALE_CHANGE
2340
2236
  - NON_INTEGER_VALUES
@@ -2350,15 +2246,10 @@ components:
2350
2246
  format: date-time
2351
2247
  owner_email:
2352
2248
  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.
2249
+ 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
2250
  owner_name:
2358
2251
  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.
2252
+ 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
2253
  required:
2363
2254
  - id
2364
2255
  - user_id
@@ -2392,9 +2283,7 @@ components:
2392
2283
  - pending
2393
2284
  - accepted
2394
2285
  - 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.
2286
+ 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
2287
  expires_at:
2399
2288
  type: string
2400
2289
  format: date-time
@@ -2411,18 +2300,13 @@ components:
2411
2300
  description: Email of the sharing owner. Set on shares addressed to the caller.
2412
2301
  owner_name:
2413
2302
  type: string
2414
- description: >-
2415
- Display name the sharing owner set in their profile. Absent when
2416
- they set none.
2303
+ description: Display name the sharing owner set in their profile. Absent when they set none.
2417
2304
  shared_with_email:
2418
2305
  type: string
2419
2306
  description: Email of the recipient. Set on shares the caller owns.
2420
2307
  shared_with_name:
2421
2308
  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.
2309
+ 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
2310
  required:
2427
2311
  - id
2428
2312
  - owner_user_id
@@ -2560,9 +2444,7 @@ components:
2560
2444
  description: Preferred language
2561
2445
  plan:
2562
2446
  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.
2447
+ description: Plan for this service, derived from the account's subscriptions. `free` when the account holds no active subscription for Recorder.
2566
2448
  subscription_status:
2567
2449
  type: string
2568
2450
  nullable: true
@@ -2714,7 +2596,7 @@ components:
2714
2596
  content:
2715
2597
  application/json:
2716
2598
  schema:
2717
- $ref: '#/components/schemas/ErrorResponse'
2599
+ $ref: "#/components/schemas/ErrorResponse"
2718
2600
  example:
2719
2601
  success: false
2720
2602
  error:
@@ -2725,7 +2607,7 @@ components:
2725
2607
  content:
2726
2608
  application/json:
2727
2609
  schema:
2728
- $ref: '#/components/schemas/ErrorResponse'
2610
+ $ref: "#/components/schemas/ErrorResponse"
2729
2611
  example:
2730
2612
  success: false
2731
2613
  error:
@@ -2736,7 +2618,7 @@ components:
2736
2618
  content:
2737
2619
  application/json:
2738
2620
  schema:
2739
- $ref: '#/components/schemas/ErrorResponse'
2621
+ $ref: "#/components/schemas/ErrorResponse"
2740
2622
  example:
2741
2623
  success: false
2742
2624
  error:
@@ -2747,7 +2629,7 @@ components:
2747
2629
  content:
2748
2630
  application/json:
2749
2631
  schema:
2750
- $ref: '#/components/schemas/ErrorResponse'
2632
+ $ref: "#/components/schemas/ErrorResponse"
2751
2633
  example:
2752
2634
  success: false
2753
2635
  error: