RemoteAPI.openapi.yaml 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059
  1. openapi: 3.1.0
  2. info:
  3. title: Celestia Trace iOS Remote API
  4. version: 2026-07-24
  5. description: |
  6. iOS 客户端实际调用的远程接口契约。
  7. 维护规则:
  8. 1. backend 路由、请求字段或响应字段变化时,先更新本文件,再更新 Swift 模型。
  9. 2. 所有 JSON 接口使用统一响应 `{code, message, data}`。
  10. 3. 除登录、注册和刷新令牌外,接口均使用 Bearer access token。
  11. 4. 公网网关保留 `/celestia-trace/v1`;后端 Gin 路由本身使用 `/v1`。
  12. 5. 服务端时间使用 RFC 3339 / ISO 8601,客户端同时兼容带或不带小数秒。
  13. x-client-sources:
  14. - CelestiaTrace/Services/Network/APIClient.swift
  15. - CelestiaTrace/Services/Network/RemoteNetworkService.swift
  16. - CelestiaTrace/Services/Auth/RemoteAuthService.swift
  17. servers:
  18. - url: https://api.ccdw.life/celestia-trace/v1
  19. description: Production
  20. tags:
  21. - name: Health
  22. - name: Auth
  23. - name: User
  24. - name: Devices
  25. - name: Sessions
  26. - name: Assets
  27. - name: Sync
  28. paths:
  29. /health:
  30. get:
  31. tags: [Health]
  32. operationId: getHealth
  33. security: []
  34. responses:
  35. "200":
  36. description: API and database are healthy
  37. content:
  38. application/json:
  39. schema:
  40. $ref: "#/components/schemas/HealthEnvelope"
  41. "503":
  42. $ref: "#/components/responses/Error"
  43. /auth/register:
  44. post:
  45. tags: [Auth]
  46. operationId: register
  47. security: []
  48. requestBody:
  49. required: true
  50. content:
  51. application/json:
  52. schema:
  53. $ref: "#/components/schemas/RegisterRequest"
  54. responses:
  55. "200":
  56. description: Account and login session created
  57. content:
  58. application/json:
  59. schema:
  60. $ref: "#/components/schemas/AuthEnvelope"
  61. "400":
  62. $ref: "#/components/responses/Error"
  63. "409":
  64. $ref: "#/components/responses/Error"
  65. /auth/login:
  66. post:
  67. tags: [Auth]
  68. operationId: login
  69. security: []
  70. requestBody:
  71. required: true
  72. content:
  73. application/json:
  74. schema:
  75. $ref: "#/components/schemas/LoginRequest"
  76. responses:
  77. "200":
  78. description: Login session created
  79. content:
  80. application/json:
  81. schema:
  82. $ref: "#/components/schemas/AuthEnvelope"
  83. "400":
  84. $ref: "#/components/responses/Error"
  85. "401":
  86. $ref: "#/components/responses/Error"
  87. /auth/refresh:
  88. post:
  89. tags: [Auth]
  90. operationId: refreshAccessToken
  91. security: []
  92. requestBody:
  93. required: true
  94. content:
  95. application/json:
  96. schema:
  97. type: object
  98. required: [refreshToken]
  99. properties:
  100. refreshToken:
  101. type: string
  102. responses:
  103. "200":
  104. description: Tokens rotated; the old refresh token is no longer valid
  105. content:
  106. application/json:
  107. schema:
  108. $ref: "#/components/schemas/AuthEnvelope"
  109. "401":
  110. $ref: "#/components/responses/Error"
  111. /auth/logout:
  112. post:
  113. tags: [Auth]
  114. operationId: logout
  115. responses:
  116. "200":
  117. $ref: "#/components/responses/EmptySuccess"
  118. "401":
  119. $ref: "#/components/responses/Error"
  120. /user/profile:
  121. get:
  122. tags: [User]
  123. operationId: getProfile
  124. responses:
  125. "200":
  126. description: Current user
  127. content:
  128. application/json:
  129. schema:
  130. $ref: "#/components/schemas/UserEnvelope"
  131. "401":
  132. $ref: "#/components/responses/Error"
  133. put:
  134. tags: [User]
  135. operationId: updateProfile
  136. requestBody:
  137. required: true
  138. content:
  139. application/json:
  140. schema:
  141. $ref: "#/components/schemas/UpdateProfileRequest"
  142. responses:
  143. "200":
  144. description: Updated user
  145. content:
  146. application/json:
  147. schema:
  148. $ref: "#/components/schemas/UserEnvelope"
  149. "400":
  150. $ref: "#/components/responses/Error"
  151. "401":
  152. $ref: "#/components/responses/Error"
  153. "409":
  154. $ref: "#/components/responses/Error"
  155. /user/change-password:
  156. post:
  157. tags: [User]
  158. operationId: changePassword
  159. requestBody:
  160. required: true
  161. content:
  162. application/json:
  163. schema:
  164. type: object
  165. required: [oldPassword, newPassword]
  166. properties:
  167. oldPassword:
  168. type: string
  169. newPassword:
  170. type: string
  171. minLength: 6
  172. responses:
  173. "200":
  174. $ref: "#/components/responses/EmptySuccess"
  175. "400":
  176. $ref: "#/components/responses/Error"
  177. "401":
  178. $ref: "#/components/responses/Error"
  179. /devices:
  180. post:
  181. tags: [Devices]
  182. operationId: bindDevice
  183. requestBody:
  184. required: true
  185. content:
  186. application/json:
  187. schema:
  188. $ref: "#/components/schemas/BindDeviceRequest"
  189. responses:
  190. "200":
  191. description: Bound or updated cloud device
  192. content:
  193. application/json:
  194. schema:
  195. $ref: "#/components/schemas/DeviceEnvelope"
  196. "400":
  197. $ref: "#/components/responses/Error"
  198. "401":
  199. $ref: "#/components/responses/Error"
  200. /devices/{deviceId}:
  201. parameters:
  202. - $ref: "#/components/parameters/DeviceId"
  203. put:
  204. tags: [Devices]
  205. operationId: updateDevice
  206. requestBody:
  207. required: true
  208. content:
  209. application/json:
  210. schema:
  211. $ref: "#/components/schemas/UpdateDeviceRequest"
  212. responses:
  213. "200":
  214. description: Updated cloud device
  215. content:
  216. application/json:
  217. schema:
  218. $ref: "#/components/schemas/DeviceEnvelope"
  219. "401":
  220. $ref: "#/components/responses/Error"
  221. "404":
  222. $ref: "#/components/responses/Error"
  223. delete:
  224. tags: [Devices]
  225. operationId: unbindDevice
  226. responses:
  227. "200":
  228. description: Device unbound
  229. content:
  230. application/json:
  231. schema:
  232. $ref: "#/components/schemas/DeleteEnvelope"
  233. "401":
  234. $ref: "#/components/responses/Error"
  235. "404":
  236. $ref: "#/components/responses/Error"
  237. /sessions:
  238. get:
  239. tags: [Sessions]
  240. operationId: listSessions
  241. parameters:
  242. - name: includeDeleted
  243. in: query
  244. schema:
  245. type: boolean
  246. default: true
  247. description: iOS uses true to receive deletion tombstones.
  248. responses:
  249. "200":
  250. description: All sessions visible to the current user
  251. content:
  252. application/json:
  253. schema:
  254. $ref: "#/components/schemas/SessionListEnvelope"
  255. "401":
  256. $ref: "#/components/responses/Error"
  257. post:
  258. tags: [Sessions]
  259. operationId: upsertSession
  260. description: |
  261. Idempotent upsert by `(userId, clientId)`.
  262. Existing sessions must send `baseRevision`; a mismatch returns HTTP/code 409.
  263. `deletedEventClientIds` removes events deleted locally since the last pull.
  264. requestBody:
  265. required: true
  266. content:
  267. application/json:
  268. schema:
  269. $ref: "#/components/schemas/SessionUpsertRequest"
  270. responses:
  271. "200":
  272. description: Created or updated session
  273. content:
  274. application/json:
  275. schema:
  276. $ref: "#/components/schemas/SessionEnvelope"
  277. "400":
  278. $ref: "#/components/responses/Error"
  279. "401":
  280. $ref: "#/components/responses/Error"
  281. "409":
  282. description: Optimistic-lock conflict
  283. content:
  284. application/json:
  285. schema:
  286. $ref: "#/components/schemas/ConflictEnvelope"
  287. /sessions/{sessionId}:
  288. parameters:
  289. - $ref: "#/components/parameters/SessionId"
  290. delete:
  291. tags: [Sessions]
  292. operationId: deleteSession
  293. description: Soft-deletes the session and its assets for the current user.
  294. responses:
  295. "200":
  296. description: Session deleted
  297. content:
  298. application/json:
  299. schema:
  300. $ref: "#/components/schemas/DeleteEnvelope"
  301. "401":
  302. $ref: "#/components/responses/Error"
  303. "404":
  304. $ref: "#/components/responses/Error"
  305. /sessions/{sessionId}/assets:
  306. parameters:
  307. - $ref: "#/components/parameters/SessionId"
  308. post:
  309. tags: [Assets]
  310. operationId: uploadAsset
  311. description: |
  312. Used for files smaller than 16 MiB. `clientId` makes retries idempotent.
  313. A new upload returns `{asset, sessionRevision}`. An idempotent replay may
  314. return the asset directly; the iOS decoder intentionally accepts both.
  315. requestBody:
  316. required: true
  317. content:
  318. multipart/form-data:
  319. schema:
  320. type: object
  321. required: [clientId, kind, file]
  322. properties:
  323. clientId:
  324. type: string
  325. kind:
  326. $ref: "#/components/schemas/AssetKind"
  327. file:
  328. type: string
  329. format: binary
  330. responses:
  331. "200":
  332. description: Uploaded asset or idempotent existing asset
  333. content:
  334. application/json:
  335. schema:
  336. $ref: "#/components/schemas/AssetUploadEnvelope"
  337. "401":
  338. $ref: "#/components/responses/Error"
  339. "404":
  340. $ref: "#/components/responses/Error"
  341. "413":
  342. $ref: "#/components/responses/QuotaError"
  343. /sessions/{sessionId}/assets/init:
  344. parameters:
  345. - $ref: "#/components/parameters/SessionId"
  346. post:
  347. tags: [Assets]
  348. operationId: initializeChunkedUpload
  349. description: iOS uses this flow for files at least 16 MiB, with 8 MiB chunks.
  350. requestBody:
  351. required: true
  352. content:
  353. application/json:
  354. schema:
  355. $ref: "#/components/schemas/ChunkUploadInitRequest"
  356. responses:
  357. "200":
  358. description: Chunked upload initialized
  359. content:
  360. application/json:
  361. schema:
  362. $ref: "#/components/schemas/ChunkUploadInitEnvelope"
  363. "401":
  364. $ref: "#/components/responses/Error"
  365. "404":
  366. $ref: "#/components/responses/Error"
  367. "413":
  368. $ref: "#/components/responses/QuotaError"
  369. /sessions/{sessionId}/assets/chunk:
  370. parameters:
  371. - $ref: "#/components/parameters/SessionId"
  372. post:
  373. tags: [Assets]
  374. operationId: uploadChunk
  375. requestBody:
  376. required: true
  377. content:
  378. multipart/form-data:
  379. schema:
  380. type: object
  381. required: [uploadId, chunkIndex, file]
  382. properties:
  383. uploadId:
  384. type: string
  385. format: uuid
  386. chunkIndex:
  387. type: integer
  388. minimum: 0
  389. file:
  390. type: string
  391. format: binary
  392. responses:
  393. "200":
  394. description: Chunk accepted
  395. content:
  396. application/json:
  397. schema:
  398. $ref: "#/components/schemas/ChunkProgressEnvelope"
  399. "400":
  400. $ref: "#/components/responses/Error"
  401. "401":
  402. $ref: "#/components/responses/Error"
  403. "404":
  404. $ref: "#/components/responses/Error"
  405. "410":
  406. $ref: "#/components/responses/Error"
  407. /sessions/{sessionId}/assets/complete:
  408. parameters:
  409. - $ref: "#/components/parameters/SessionId"
  410. post:
  411. tags: [Assets]
  412. operationId: completeChunkedUpload
  413. requestBody:
  414. required: true
  415. content:
  416. application/json:
  417. schema:
  418. type: object
  419. required: [uploadId, totalChunks]
  420. properties:
  421. uploadId:
  422. type: string
  423. format: uuid
  424. totalChunks:
  425. type: integer
  426. minimum: 1
  427. responses:
  428. "200":
  429. description: Chunks merged and asset created
  430. content:
  431. application/json:
  432. schema:
  433. $ref: "#/components/schemas/AssetUploadEnvelope"
  434. "400":
  435. $ref: "#/components/responses/Error"
  436. "401":
  437. $ref: "#/components/responses/Error"
  438. "404":
  439. $ref: "#/components/responses/Error"
  440. "410":
  441. $ref: "#/components/responses/Error"
  442. /sessions/{sessionId}/assets/{assetId}:
  443. parameters:
  444. - $ref: "#/components/parameters/SessionId"
  445. - $ref: "#/components/parameters/AssetId"
  446. get:
  447. tags: [Assets]
  448. operationId: downloadAsset
  449. responses:
  450. "200":
  451. description: Attachment bytes; Content-Disposition contains the original filename
  452. content:
  453. application/octet-stream:
  454. schema:
  455. type: string
  456. format: binary
  457. "401":
  458. $ref: "#/components/responses/Error"
  459. "404":
  460. $ref: "#/components/responses/Error"
  461. /storage/quota:
  462. get:
  463. tags: [Sync]
  464. operationId: getStorageQuota
  465. description: Called before uploading the pending assets for a session.
  466. responses:
  467. "200":
  468. description: Current storage quota in bytes
  469. content:
  470. application/json:
  471. schema:
  472. $ref: "#/components/schemas/StorageQuotaEnvelope"
  473. "401":
  474. $ref: "#/components/responses/Error"
  475. /sync/trigger:
  476. post:
  477. tags: [Sync]
  478. operationId: recordSyncCheckpoint
  479. description: Called only after all session metadata and assets finish syncing.
  480. responses:
  481. "200":
  482. description: Client sync checkpoint recorded
  483. content:
  484. application/json:
  485. schema:
  486. $ref: "#/components/schemas/SyncCheckpointEnvelope"
  487. "401":
  488. $ref: "#/components/responses/Error"
  489. components:
  490. securitySchemes:
  491. bearerAuth:
  492. type: http
  493. scheme: bearer
  494. bearerFormat: JWT
  495. parameters:
  496. DeviceId:
  497. name: deviceId
  498. in: path
  499. required: true
  500. schema:
  501. type: string
  502. format: uuid
  503. SessionId:
  504. name: sessionId
  505. in: path
  506. required: true
  507. schema:
  508. type: string
  509. format: uuid
  510. AssetId:
  511. name: assetId
  512. in: path
  513. required: true
  514. schema:
  515. type: string
  516. format: uuid
  517. responses:
  518. EmptySuccess:
  519. description: Success without a data payload
  520. content:
  521. application/json:
  522. schema:
  523. $ref: "#/components/schemas/EmptyEnvelope"
  524. Error:
  525. description: Request failed
  526. content:
  527. application/json:
  528. schema:
  529. $ref: "#/components/schemas/ErrorEnvelope"
  530. QuotaError:
  531. description: Storage quota exceeded
  532. content:
  533. application/json:
  534. schema:
  535. $ref: "#/components/schemas/QuotaErrorEnvelope"
  536. schemas:
  537. EnvelopeBase:
  538. type: object
  539. required: [code, message]
  540. properties:
  541. code:
  542. type: integer
  543. message:
  544. type: string
  545. EmptyEnvelope:
  546. allOf:
  547. - $ref: "#/components/schemas/EnvelopeBase"
  548. - type: object
  549. properties:
  550. data:
  551. type: "null"
  552. ErrorEnvelope:
  553. allOf:
  554. - $ref: "#/components/schemas/EnvelopeBase"
  555. - type: object
  556. properties:
  557. data: {}
  558. HealthEnvelope:
  559. allOf:
  560. - $ref: "#/components/schemas/EnvelopeBase"
  561. - type: object
  562. required: [data]
  563. properties:
  564. data:
  565. type: string
  566. const: healthy
  567. RegisterRequest:
  568. type: object
  569. required: [username, identifier, password]
  570. properties:
  571. username:
  572. type: string
  573. minLength: 2
  574. identifier:
  575. type: string
  576. description: Email address or phone number.
  577. password:
  578. type: string
  579. minLength: 6
  580. LoginRequest:
  581. type: object
  582. required: [identifier, password]
  583. properties:
  584. identifier:
  585. type: string
  586. description: Username, email address, or phone number.
  587. password:
  588. type: string
  589. UpdateProfileRequest:
  590. type: object
  591. properties:
  592. username:
  593. type: [string, "null"]
  594. email:
  595. type: [string, "null"]
  596. phoneNumber:
  597. type: [string, "null"]
  598. avatarURL:
  599. type: [string, "null"]
  600. User:
  601. type: object
  602. required: [id, username, registeredAt]
  603. properties:
  604. id:
  605. type: string
  606. format: uuid
  607. username:
  608. type: string
  609. email:
  610. type: string
  611. phoneNumber:
  612. type: string
  613. avatarURL:
  614. type: string
  615. format: uri
  616. registeredAt:
  617. type: string
  618. format: date-time
  619. updatedAt:
  620. type: string
  621. format: date-time
  622. AuthData:
  623. type: object
  624. required: [user, token, refreshToken, expiresAt]
  625. properties:
  626. user:
  627. $ref: "#/components/schemas/User"
  628. token:
  629. type: string
  630. description: Short-lived access JWT.
  631. refreshToken:
  632. type: string
  633. description: Rotated on every refresh.
  634. expiresAt:
  635. type: string
  636. format: date-time
  637. AuthEnvelope:
  638. allOf:
  639. - $ref: "#/components/schemas/EnvelopeBase"
  640. - type: object
  641. required: [data]
  642. properties:
  643. data:
  644. $ref: "#/components/schemas/AuthData"
  645. UserEnvelope:
  646. allOf:
  647. - $ref: "#/components/schemas/EnvelopeBase"
  648. - type: object
  649. required: [data]
  650. properties:
  651. data:
  652. $ref: "#/components/schemas/User"
  653. BindDeviceRequest:
  654. type: object
  655. required: [name]
  656. properties:
  657. name:
  658. type: string
  659. peripheralUUID:
  660. type: string
  661. hardwareMAC:
  662. type: [string, "null"]
  663. firmwareVersion:
  664. type: [string, "null"]
  665. batteryLevel:
  666. type: [integer, "null"]
  667. minimum: 0
  668. maximum: 100
  669. freeStorageMB:
  670. type: [integer, "null"]
  671. totalStorageMB:
  672. type: [integer, "null"]
  673. UpdateDeviceRequest:
  674. type: object
  675. properties:
  676. name:
  677. type: [string, "null"]
  678. batteryLevel:
  679. type: [integer, "null"]
  680. minimum: 0
  681. maximum: 100
  682. isConnected:
  683. type: [boolean, "null"]
  684. firmwareVersion:
  685. type: [string, "null"]
  686. freeStorageMB:
  687. type: [integer, "null"]
  688. totalStorageMB:
  689. type: [integer, "null"]
  690. Device:
  691. type: object
  692. required: [id, name, peripheralUUID]
  693. properties:
  694. id:
  695. type: string
  696. format: uuid
  697. userId:
  698. type: string
  699. format: uuid
  700. name:
  701. type: string
  702. peripheralUUID:
  703. type: string
  704. hardwareMAC:
  705. type: string
  706. batteryLevel:
  707. type: integer
  708. firmwareVersion:
  709. type: string
  710. freeStorageMB:
  711. type: integer
  712. totalStorageMB:
  713. type: integer
  714. isConnected:
  715. type: boolean
  716. boundAt:
  717. type: string
  718. format: date-time
  719. updatedAt:
  720. type: string
  721. format: date-time
  722. DeviceEnvelope:
  723. allOf:
  724. - $ref: "#/components/schemas/EnvelopeBase"
  725. - type: object
  726. required: [data]
  727. properties:
  728. data:
  729. $ref: "#/components/schemas/Device"
  730. EventUpsert:
  731. type: object
  732. required: [clientId, relativeTimeMs, eventType]
  733. properties:
  734. clientId:
  735. type: string
  736. relativeTimeMs:
  737. type: integer
  738. format: int64
  739. eventType:
  740. type: string
  741. enum: [PHOTO, NOTE, MARKER, VOICE, CONTINUATION]
  742. textContent:
  743. type: [string, "null"]
  744. voiceStartOffsetMs:
  745. type: [integer, "null"]
  746. format: int64
  747. voiceEndOffsetMs:
  748. type: [integer, "null"]
  749. format: int64
  750. locationName:
  751. type: [string, "null"]
  752. locationAddress:
  753. type: [string, "null"]
  754. latitude:
  755. type: [number, "null"]
  756. format: double
  757. minimum: -90
  758. maximum: 90
  759. longitude:
  760. type: [number, "null"]
  761. format: double
  762. minimum: -180
  763. maximum: 180
  764. SessionUpsertRequest:
  765. type: object
  766. required: [clientId, title, startTime, durationMs, events, deletedEventClientIds]
  767. properties:
  768. clientId:
  769. type: string
  770. title:
  771. type: string
  772. startTime:
  773. type: string
  774. format: date-time
  775. endTime:
  776. type: [string, "null"]
  777. format: date-time
  778. durationMs:
  779. type: integer
  780. format: int64
  781. events:
  782. type: array
  783. items:
  784. $ref: "#/components/schemas/EventUpsert"
  785. baseRevision:
  786. type: [integer, "null"]
  787. format: int64
  788. deletedEventClientIds:
  789. type: array
  790. items:
  791. type: string
  792. RemoteEvent:
  793. allOf:
  794. - $ref: "#/components/schemas/EventUpsert"
  795. - type: object
  796. required: [id]
  797. properties:
  798. id:
  799. type: string
  800. format: uuid
  801. clientId:
  802. type: [string, "null"]
  803. createdAt:
  804. type: string
  805. format: date-time
  806. RemoteSession:
  807. type: object
  808. required: [id, title, startTime, durationMs, revision]
  809. properties:
  810. id:
  811. type: string
  812. format: uuid
  813. clientId:
  814. type: [string, "null"]
  815. title:
  816. type: string
  817. startTime:
  818. type: string
  819. format: date-time
  820. endTime:
  821. type: [string, "null"]
  822. format: date-time
  823. durationMs:
  824. type: integer
  825. format: int64
  826. revision:
  827. type: integer
  828. format: int64
  829. deletedAt:
  830. type: [string, "null"]
  831. format: date-time
  832. events:
  833. type: array
  834. items:
  835. $ref: "#/components/schemas/RemoteEvent"
  836. assets:
  837. type: array
  838. items:
  839. $ref: "#/components/schemas/Asset"
  840. SessionEnvelope:
  841. allOf:
  842. - $ref: "#/components/schemas/EnvelopeBase"
  843. - type: object
  844. required: [data]
  845. properties:
  846. data:
  847. $ref: "#/components/schemas/RemoteSession"
  848. SessionListEnvelope:
  849. allOf:
  850. - $ref: "#/components/schemas/EnvelopeBase"
  851. - type: object
  852. required: [data]
  853. properties:
  854. data:
  855. type: array
  856. items:
  857. $ref: "#/components/schemas/RemoteSession"
  858. ConflictEnvelope:
  859. allOf:
  860. - $ref: "#/components/schemas/EnvelopeBase"
  861. - type: object
  862. required: [data]
  863. properties:
  864. data:
  865. type: object
  866. required: [serverRevision]
  867. properties:
  868. serverRevision:
  869. type: integer
  870. format: int64
  871. AssetKind:
  872. type: string
  873. enum: [AUDIO, PHOTO]
  874. Asset:
  875. type: object
  876. required: [id, clientId, kind, fileName, mimeType, sizeBytes, sha256]
  877. properties:
  878. id:
  879. type: string
  880. format: uuid
  881. clientId:
  882. type: string
  883. kind:
  884. $ref: "#/components/schemas/AssetKind"
  885. fileName:
  886. type: string
  887. mimeType:
  888. type: string
  889. sizeBytes:
  890. type: integer
  891. format: int64
  892. sha256:
  893. type: string
  894. pattern: "^[a-fA-F0-9]{64}$"
  895. createdAt:
  896. type: string
  897. format: date-time
  898. AssetUploadData:
  899. type: object
  900. required: [asset, sessionRevision]
  901. properties:
  902. asset:
  903. $ref: "#/components/schemas/Asset"
  904. sessionRevision:
  905. type: integer
  906. format: int64
  907. AssetUploadEnvelope:
  908. allOf:
  909. - $ref: "#/components/schemas/EnvelopeBase"
  910. - type: object
  911. required: [data]
  912. properties:
  913. data:
  914. oneOf:
  915. - $ref: "#/components/schemas/AssetUploadData"
  916. - $ref: "#/components/schemas/Asset"
  917. ChunkUploadInitRequest:
  918. type: object
  919. required: [clientId, kind, fileName, mimeType, fileSize, chunkSize]
  920. properties:
  921. clientId:
  922. type: string
  923. kind:
  924. $ref: "#/components/schemas/AssetKind"
  925. fileName:
  926. type: string
  927. mimeType:
  928. type: string
  929. fileSize:
  930. type: integer
  931. format: int64
  932. minimum: 1
  933. chunkSize:
  934. type: integer
  935. minimum: 1
  936. ChunkUploadInitEnvelope:
  937. allOf:
  938. - $ref: "#/components/schemas/EnvelopeBase"
  939. - type: object
  940. required: [data]
  941. properties:
  942. data:
  943. type: object
  944. required: [uploadId, totalChunks, chunkSize, expiresAt]
  945. properties:
  946. uploadId:
  947. type: string
  948. format: uuid
  949. totalChunks:
  950. type: integer
  951. chunkSize:
  952. type: integer
  953. expiresAt:
  954. type: string
  955. format: date-time
  956. ChunkProgressEnvelope:
  957. allOf:
  958. - $ref: "#/components/schemas/EnvelopeBase"
  959. - type: object
  960. required: [data]
  961. properties:
  962. data:
  963. type: object
  964. required: [uploadId, chunkIndex, uploadedChunks, totalChunks]
  965. properties:
  966. uploadId:
  967. type: string
  968. format: uuid
  969. chunkIndex:
  970. type: integer
  971. uploadedChunks:
  972. type: integer
  973. totalChunks:
  974. type: integer
  975. StorageQuota:
  976. type: object
  977. required: [totalBytes, usedBytes, remainingBytes]
  978. properties:
  979. totalBytes:
  980. type: integer
  981. format: int64
  982. usedBytes:
  983. type: integer
  984. format: int64
  985. remainingBytes:
  986. type: integer
  987. format: int64
  988. StorageQuotaEnvelope:
  989. allOf:
  990. - $ref: "#/components/schemas/EnvelopeBase"
  991. - type: object
  992. required: [data]
  993. properties:
  994. data:
  995. $ref: "#/components/schemas/StorageQuota"
  996. QuotaErrorEnvelope:
  997. allOf:
  998. - $ref: "#/components/schemas/EnvelopeBase"
  999. - type: object
  1000. required: [data]
  1001. properties:
  1002. data:
  1003. allOf:
  1004. - $ref: "#/components/schemas/StorageQuota"
  1005. - type: object
  1006. required: [requiredBytes]
  1007. properties:
  1008. requiredBytes:
  1009. type: integer
  1010. format: int64
  1011. SyncCheckpointEnvelope:
  1012. allOf:
  1013. - $ref: "#/components/schemas/EnvelopeBase"
  1014. - type: object
  1015. required: [data]
  1016. properties:
  1017. data:
  1018. type: object
  1019. required: [syncedAt, message]
  1020. properties:
  1021. syncedAt:
  1022. type: string
  1023. format: date-time
  1024. message:
  1025. type: string
  1026. DeleteEnvelope:
  1027. allOf:
  1028. - $ref: "#/components/schemas/EnvelopeBase"
  1029. - type: object
  1030. required: [data]
  1031. properties:
  1032. data:
  1033. type: object
  1034. required: [deletedId]
  1035. properties:
  1036. deletedId:
  1037. type: string
  1038. security:
  1039. - bearerAuth: []