You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

918 rivejä
24 KiB

  1. openapi: 3.0.3
  2. info:
  3. title: Presence API
  4. description: API for gateways, zones, trackers, parser configs, settings, alerts, and tracks.
  5. version: 1.0.0
  6. servers:
  7. - url: /
  8. description: Default server
  9. paths:
  10. # --- Health ---
  11. /health:
  12. get:
  13. summary: Liveness check
  14. operationId: health
  15. tags: [Health]
  16. responses:
  17. '200':
  18. description: Service is alive
  19. content:
  20. application/json:
  21. schema:
  22. type: object
  23. properties:
  24. status:
  25. type: string
  26. example: ok
  27. /ready:
  28. get:
  29. summary: Readiness check (DB connectivity)
  30. operationId: ready
  31. tags: [Health]
  32. responses:
  33. '200':
  34. description: Service is ready
  35. content:
  36. application/json:
  37. schema:
  38. type: object
  39. properties:
  40. status:
  41. type: string
  42. example: ready
  43. '503':
  44. $ref: '#/components/responses/ServiceUnavailable'
  45. # --- Gateways ---
  46. /reslevis/getGateways:
  47. get:
  48. summary: List all gateways
  49. operationId: getGateways
  50. tags: [Gateways]
  51. responses:
  52. '200':
  53. description: List of gateways
  54. content:
  55. application/json:
  56. schema:
  57. type: array
  58. items:
  59. $ref: '#/components/schemas/Gateway'
  60. '500':
  61. $ref: '#/components/responses/InternalError'
  62. /reslevis/postGateway:
  63. post:
  64. summary: Create a gateway
  65. operationId: postGateway
  66. tags: [Gateways]
  67. requestBody:
  68. required: true
  69. content:
  70. application/json:
  71. schema:
  72. $ref: '#/components/schemas/Gateway'
  73. responses:
  74. '201':
  75. description: Gateway created
  76. content:
  77. application/json:
  78. schema:
  79. $ref: '#/components/schemas/StatusCreated'
  80. '400':
  81. $ref: '#/components/responses/BadRequest'
  82. '500':
  83. $ref: '#/components/responses/InternalError'
  84. /reslevis/removeGateway/{id}:
  85. delete:
  86. summary: Delete a gateway by ID
  87. operationId: removeGateway
  88. tags: [Gateways]
  89. parameters:
  90. - $ref: '#/components/parameters/PathId'
  91. responses:
  92. '200':
  93. description: Gateway deleted
  94. content:
  95. application/json:
  96. schema:
  97. $ref: '#/components/schemas/StatusDeleted'
  98. '404':
  99. $ref: '#/components/responses/NotFound'
  100. '500':
  101. $ref: '#/components/responses/InternalError'
  102. /reslevis/updateGateway/{id}:
  103. put:
  104. summary: Update a gateway by ID
  105. operationId: updateGateway
  106. tags: [Gateways]
  107. parameters:
  108. - $ref: '#/components/parameters/PathId'
  109. requestBody:
  110. required: true
  111. content:
  112. application/json:
  113. schema:
  114. $ref: '#/components/schemas/Gateway'
  115. responses:
  116. '200':
  117. description: Gateway updated
  118. content:
  119. application/json:
  120. schema:
  121. $ref: '#/components/schemas/StatusUpdated'
  122. '400':
  123. $ref: '#/components/responses/BadRequest'
  124. '404':
  125. $ref: '#/components/responses/NotFound'
  126. '500':
  127. $ref: '#/components/responses/InternalError'
  128. # --- Zones ---
  129. /reslevis/getZones:
  130. get:
  131. summary: List all zones
  132. operationId: getZones
  133. tags: [Zones]
  134. responses:
  135. '200':
  136. description: List of zones
  137. content:
  138. application/json:
  139. schema:
  140. type: array
  141. items:
  142. $ref: '#/components/schemas/Zone'
  143. '500':
  144. $ref: '#/components/responses/InternalError'
  145. /reslevis/postZone:
  146. post:
  147. summary: Create a zone
  148. operationId: postZone
  149. tags: [Zones]
  150. requestBody:
  151. required: true
  152. content:
  153. application/json:
  154. schema:
  155. $ref: '#/components/schemas/Zone'
  156. responses:
  157. '201':
  158. description: Zone created
  159. content:
  160. application/json:
  161. schema:
  162. $ref: '#/components/schemas/StatusCreated'
  163. '400':
  164. $ref: '#/components/responses/BadRequest'
  165. '500':
  166. $ref: '#/components/responses/InternalError'
  167. /reslevis/removeZone/{id}:
  168. delete:
  169. summary: Delete a zone by ID
  170. operationId: removeZone
  171. tags: [Zones]
  172. parameters:
  173. - $ref: '#/components/parameters/PathId'
  174. responses:
  175. '200':
  176. description: Zone deleted
  177. content:
  178. application/json:
  179. schema:
  180. $ref: '#/components/schemas/StatusDeleted'
  181. '404':
  182. $ref: '#/components/responses/NotFound'
  183. '500':
  184. $ref: '#/components/responses/InternalError'
  185. /reslevis/updateZone:
  186. put:
  187. summary: Update a zone
  188. operationId: updateZone
  189. tags: [Zones]
  190. requestBody:
  191. required: true
  192. content:
  193. application/json:
  194. schema:
  195. $ref: '#/components/schemas/Zone'
  196. responses:
  197. '200':
  198. description: Zone updated
  199. content:
  200. application/json:
  201. schema:
  202. $ref: '#/components/schemas/StatusUpdated'
  203. '400':
  204. $ref: '#/components/responses/BadRequest'
  205. '404':
  206. $ref: '#/components/responses/NotFound'
  207. '500':
  208. $ref: '#/components/responses/InternalError'
  209. # --- Tracker zones ---
  210. /reslevis/getTrackerZones:
  211. get:
  212. summary: List all tracker zones
  213. operationId: getTrackerZones
  214. tags: [TrackerZones]
  215. responses:
  216. '200':
  217. description: List of tracker zones
  218. content:
  219. application/json:
  220. schema:
  221. type: array
  222. items:
  223. $ref: '#/components/schemas/TrackerZone'
  224. '500':
  225. $ref: '#/components/responses/InternalError'
  226. /reslevis/postTrackerZone:
  227. post:
  228. summary: Create a tracker zone
  229. operationId: postTrackerZone
  230. tags: [TrackerZones]
  231. requestBody:
  232. required: true
  233. content:
  234. application/json:
  235. schema:
  236. $ref: '#/components/schemas/TrackerZone'
  237. responses:
  238. '201':
  239. description: Tracker zone created
  240. content:
  241. application/json:
  242. schema:
  243. $ref: '#/components/schemas/StatusCreated'
  244. '400':
  245. $ref: '#/components/responses/BadRequest'
  246. '500':
  247. $ref: '#/components/responses/InternalError'
  248. /reslevis/removeTrackerZone/{id}:
  249. delete:
  250. summary: Delete a tracker zone by ID
  251. operationId: removeTrackerZone
  252. tags: [TrackerZones]
  253. parameters:
  254. - $ref: '#/components/parameters/PathId'
  255. responses:
  256. '200':
  257. description: Tracker zone deleted
  258. content:
  259. application/json:
  260. schema:
  261. $ref: '#/components/schemas/StatusDeleted'
  262. '404':
  263. $ref: '#/components/responses/NotFound'
  264. '500':
  265. $ref: '#/components/responses/InternalError'
  266. /reslevis/updateTrackerZone:
  267. put:
  268. summary: Update a tracker zone
  269. operationId: updateTrackerZone
  270. tags: [TrackerZones]
  271. requestBody:
  272. required: true
  273. content:
  274. application/json:
  275. schema:
  276. $ref: '#/components/schemas/TrackerZone'
  277. responses:
  278. '200':
  279. description: Tracker zone updated
  280. content:
  281. application/json:
  282. schema:
  283. $ref: '#/components/schemas/StatusUpdated'
  284. '400':
  285. $ref: '#/components/responses/BadRequest'
  286. '404':
  287. $ref: '#/components/responses/NotFound'
  288. '500':
  289. $ref: '#/components/responses/InternalError'
  290. # --- Trackers ---
  291. /reslevis/getTrackers:
  292. get:
  293. summary: List all trackers
  294. operationId: getTrackers
  295. tags: [Trackers]
  296. responses:
  297. '200':
  298. description: List of trackers
  299. content:
  300. application/json:
  301. schema:
  302. type: array
  303. items:
  304. $ref: '#/components/schemas/Tracker'
  305. '500':
  306. $ref: '#/components/responses/InternalError'
  307. /reslevis/postTracker:
  308. post:
  309. summary: Create a tracker
  310. operationId: postTracker
  311. tags: [Trackers]
  312. requestBody:
  313. required: true
  314. content:
  315. application/json:
  316. schema:
  317. $ref: '#/components/schemas/Tracker'
  318. responses:
  319. '201':
  320. description: Tracker created
  321. content:
  322. application/json:
  323. schema:
  324. $ref: '#/components/schemas/StatusCreated'
  325. '400':
  326. $ref: '#/components/responses/BadRequest'
  327. '500':
  328. $ref: '#/components/responses/InternalError'
  329. /reslevis/removeTracker/{id}:
  330. delete:
  331. summary: Delete a tracker by ID
  332. operationId: removeTracker
  333. tags: [Trackers]
  334. parameters:
  335. - $ref: '#/components/parameters/PathId'
  336. responses:
  337. '200':
  338. description: Tracker deleted
  339. content:
  340. application/json:
  341. schema:
  342. $ref: '#/components/schemas/StatusDeleted'
  343. '404':
  344. $ref: '#/components/responses/NotFound'
  345. '500':
  346. $ref: '#/components/responses/InternalError'
  347. /reslevis/updateTracker:
  348. put:
  349. summary: Update a tracker
  350. operationId: updateTracker
  351. tags: [Trackers]
  352. requestBody:
  353. required: true
  354. content:
  355. application/json:
  356. schema:
  357. $ref: '#/components/schemas/Tracker'
  358. responses:
  359. '200':
  360. description: Tracker updated
  361. content:
  362. application/json:
  363. schema:
  364. $ref: '#/components/schemas/StatusUpdated'
  365. '400':
  366. $ref: '#/components/responses/BadRequest'
  367. '404':
  368. $ref: '#/components/responses/NotFound'
  369. '500':
  370. $ref: '#/components/responses/InternalError'
  371. # --- Parser configs (beacons) ---
  372. /configs/beacons:
  373. get:
  374. summary: List all beacon parser configs
  375. operationId: listParserConfigs
  376. tags: [ParserConfigs]
  377. responses:
  378. '200':
  379. description: List of parser configs
  380. content:
  381. application/json:
  382. schema:
  383. type: array
  384. items:
  385. $ref: '#/components/schemas/ParserConfig'
  386. '500':
  387. $ref: '#/components/responses/InternalError'
  388. post:
  389. summary: Create a beacon parser config
  390. operationId: addParserConfig
  391. tags: [ParserConfigs]
  392. requestBody:
  393. required: true
  394. content:
  395. application/json:
  396. schema:
  397. $ref: '#/components/schemas/ParserConfig'
  398. responses:
  399. '201':
  400. description: Parser config created
  401. content:
  402. application/json:
  403. schema:
  404. $ref: '#/components/schemas/StatusCreated'
  405. '400':
  406. $ref: '#/components/responses/BadRequest'
  407. '500':
  408. $ref: '#/components/responses/InternalError'
  409. /configs/beacons/{id}:
  410. put:
  411. summary: Update a beacon parser config by name (id)
  412. operationId: updateParserConfig
  413. tags: [ParserConfigs]
  414. parameters:
  415. - name: id
  416. in: path
  417. required: true
  418. description: Config name (identifier)
  419. schema:
  420. type: string
  421. requestBody:
  422. required: true
  423. content:
  424. application/json:
  425. schema:
  426. $ref: '#/components/schemas/ParserConfig'
  427. responses:
  428. '200':
  429. description: Parser config updated
  430. content:
  431. application/json:
  432. schema:
  433. $ref: '#/components/schemas/StatusUpdated'
  434. '400':
  435. $ref: '#/components/responses/BadRequest'
  436. '404':
  437. $ref: '#/components/responses/NotFound'
  438. '500':
  439. $ref: '#/components/responses/InternalError'
  440. delete:
  441. summary: Delete a beacon parser config by name (id)
  442. operationId: deleteParserConfig
  443. tags: [ParserConfigs]
  444. parameters:
  445. - name: id
  446. in: path
  447. required: true
  448. description: Config name (identifier)
  449. schema:
  450. type: string
  451. responses:
  452. '200':
  453. description: Parser config deleted
  454. content:
  455. application/json:
  456. schema:
  457. $ref: '#/components/schemas/StatusDeleted'
  458. '404':
  459. $ref: '#/components/responses/NotFound'
  460. '500':
  461. $ref: '#/components/responses/InternalError'
  462. # --- Settings ---
  463. /reslevis/settings:
  464. get:
  465. summary: List settings
  466. operationId: getSettings
  467. tags: [Settings]
  468. responses:
  469. '200':
  470. description: List of settings (typically one row)
  471. content:
  472. application/json:
  473. schema:
  474. type: array
  475. items:
  476. $ref: '#/components/schemas/Settings'
  477. '500':
  478. $ref: '#/components/responses/InternalError'
  479. patch:
  480. summary: Partially update settings
  481. operationId: updateSettings
  482. tags: [Settings]
  483. requestBody:
  484. required: true
  485. content:
  486. application/json:
  487. schema:
  488. $ref: '#/components/schemas/SettingsUpdate'
  489. responses:
  490. '200':
  491. description: Settings updated
  492. content:
  493. application/json:
  494. schema:
  495. $ref: '#/components/schemas/StatusUpdated'
  496. '400':
  497. $ref: '#/components/responses/BadRequest'
  498. '500':
  499. $ref: '#/components/responses/InternalError'
  500. # --- Alerts ---
  501. /reslevis/alerts:
  502. get:
  503. summary: List all alerts
  504. operationId: listAlerts
  505. tags: [Alerts]
  506. responses:
  507. '200':
  508. description: List of alerts
  509. content:
  510. application/json:
  511. schema:
  512. type: array
  513. items:
  514. $ref: '#/components/schemas/Alert'
  515. '500':
  516. $ref: '#/components/responses/InternalError'
  517. /reslevis/alerts/{id}:
  518. get:
  519. summary: Get alert by ID
  520. operationId: getAlertById
  521. tags: [Alerts]
  522. parameters:
  523. - $ref: '#/components/parameters/PathId'
  524. responses:
  525. '200':
  526. description: Single alert
  527. content:
  528. application/json:
  529. schema:
  530. $ref: '#/components/schemas/Alert'
  531. '404':
  532. $ref: '#/components/responses/NotFound'
  533. '500':
  534. $ref: '#/components/responses/InternalError'
  535. patch:
  536. summary: Update alert status
  537. operationId: updateAlertStatus
  538. tags: [Alerts]
  539. parameters:
  540. - $ref: '#/components/parameters/PathId'
  541. requestBody:
  542. required: true
  543. content:
  544. application/json:
  545. schema:
  546. $ref: '#/components/schemas/AlertStatusUpdate'
  547. responses:
  548. '200':
  549. description: Alert status updated
  550. content:
  551. application/json:
  552. schema:
  553. $ref: '#/components/schemas/StatusUpdated'
  554. '400':
  555. $ref: '#/components/responses/BadRequest'
  556. '404':
  557. $ref: '#/components/responses/NotFound'
  558. '500':
  559. $ref: '#/components/responses/InternalError'
  560. delete:
  561. summary: Delete alert by ID
  562. operationId: deleteAlert
  563. tags: [Alerts]
  564. parameters:
  565. - $ref: '#/components/parameters/PathId'
  566. responses:
  567. '200':
  568. description: Alert deleted
  569. content:
  570. application/json:
  571. schema:
  572. $ref: '#/components/schemas/StatusDeleted'
  573. '500':
  574. $ref: '#/components/responses/InternalError'
  575. # --- Aggregated health (location, decoder, bridge, kafka, database) ---
  576. /reslevis/health:
  577. get:
  578. summary: Aggregated health status
  579. description: Returns health from location, decoder, bridge services plus server-checked Kafka and database status.
  580. operationId: getAggregatedHealth
  581. tags: [Health]
  582. responses:
  583. '200':
  584. description: Aggregated health (location, decoder, bridge, kafka, database)
  585. content:
  586. application/json:
  587. schema:
  588. $ref: '#/components/schemas/AggregatedHealth'
  589. '500':
  590. $ref: '#/components/responses/InternalError'
  591. # --- Tracks ---
  592. /reslevis/getTracks/{id}:
  593. get:
  594. summary: List tracks for a tracker UUID
  595. operationId: getTracks
  596. tags: [Tracks]
  597. parameters:
  598. - name: id
  599. in: path
  600. required: true
  601. description: Tracker UUID
  602. schema:
  603. type: string
  604. - name: limit
  605. in: query
  606. description: Max number of tracks to return (default 10)
  607. schema:
  608. type: integer
  609. default: 10
  610. - name: from
  611. in: query
  612. description: Start time (RFC3339)
  613. schema:
  614. type: string
  615. format: date-time
  616. - name: to
  617. in: query
  618. description: End time (RFC3339)
  619. schema:
  620. type: string
  621. format: date-time
  622. responses:
  623. '200':
  624. description: List of tracks
  625. content:
  626. application/json:
  627. schema:
  628. type: array
  629. items:
  630. $ref: '#/components/schemas/Track'
  631. '500':
  632. $ref: '#/components/responses/InternalError'
  633. components:
  634. parameters:
  635. PathId:
  636. name: id
  637. in: path
  638. required: true
  639. description: Resource ID
  640. schema:
  641. type: string
  642. responses:
  643. BadRequest:
  644. description: Invalid request (e.g. invalid JSON)
  645. content:
  646. application/json:
  647. schema:
  648. $ref: '#/components/schemas/Error'
  649. example:
  650. error: bad_request
  651. message: invalid request body
  652. NotFound:
  653. description: Resource not found
  654. content:
  655. application/json:
  656. schema:
  657. $ref: '#/components/schemas/Error'
  658. example:
  659. error: not_found
  660. message: resource not found
  661. InternalError:
  662. description: Internal server error
  663. content:
  664. application/json:
  665. schema:
  666. $ref: '#/components/schemas/Error'
  667. example:
  668. error: internal_error
  669. message: failed to complete operation
  670. ServiceUnavailable:
  671. description: Service not ready (e.g. DB unavailable)
  672. content:
  673. application/json:
  674. schema:
  675. $ref: '#/components/schemas/Error'
  676. example:
  677. error: not_ready
  678. message: database not available
  679. schemas:
  680. Error:
  681. type: object
  682. required: [error]
  683. properties:
  684. error:
  685. type: string
  686. description: Error code (bad_request, not_found, internal_error, not_ready)
  687. message:
  688. type: string
  689. description: Human-readable message
  690. StatusCreated:
  691. type: object
  692. properties:
  693. status:
  694. type: string
  695. example: created
  696. StatusUpdated:
  697. type: object
  698. properties:
  699. status:
  700. type: string
  701. example: updated
  702. StatusDeleted:
  703. type: object
  704. properties:
  705. status:
  706. type: string
  707. example: deleted
  708. Gateway:
  709. type: object
  710. properties:
  711. id: { type: string }
  712. name: { type: string }
  713. mac: { type: string }
  714. status: { type: string }
  715. model: { type: string }
  716. ip: { type: string }
  717. position: { type: string }
  718. x: { type: number, format: float }
  719. y: { type: number, format: float }
  720. notes: { type: string }
  721. floor: { type: string }
  722. building: { type: string }
  723. Zone:
  724. type: object
  725. properties:
  726. id: { type: string }
  727. name: { type: string }
  728. groups:
  729. type: array
  730. items: { type: string }
  731. floor: { type: string }
  732. building: { type: string }
  733. TrackerZone:
  734. type: object
  735. properties:
  736. id: { type: string }
  737. zoneList:
  738. type: array
  739. items: { type: string }
  740. tracker: { type: string }
  741. days: { type: string }
  742. time: { type: string }
  743. Tracker:
  744. type: object
  745. properties:
  746. id: { type: string }
  747. name: { type: string }
  748. mac: { type: string }
  749. status: { type: string }
  750. model: { type: string }
  751. ip: { type: string }
  752. position: { type: string }
  753. x: { type: number, format: float }
  754. y: { type: number, format: float }
  755. notes: { type: string }
  756. floor: { type: string }
  757. building: { type: string }
  758. battery: { type: integer }
  759. batteryThreshold: { type: integer }
  760. temperature: { type: integer }
  761. ParserConfig:
  762. type: object
  763. description: Beacon parser configuration (name is the primary key)
  764. properties:
  765. name: { type: string }
  766. min: { type: integer }
  767. max: { type: integer }
  768. pattern:
  769. type: array
  770. items: { type: string }
  771. configs:
  772. type: object
  773. additionalProperties:
  774. $ref: '#/components/schemas/ParserConfigEntry'
  775. ParserConfigEntry:
  776. type: object
  777. properties:
  778. length: { type: integer }
  779. offset: { type: integer }
  780. order: { type: string }
  781. Settings:
  782. type: object
  783. properties:
  784. ID: { type: integer }
  785. current_algorithm: { type: string }
  786. location_confidence: { type: integer }
  787. last_seen_threshold: { type: integer }
  788. beacon_metric_size: { type: integer }
  789. HA_send_interval: { type: integer }
  790. HA_send_changes_only: { type: boolean }
  791. RSSI_enforce_threshold: { type: boolean }
  792. RSSI_min_threshold: { type: integer }
  793. SettingsUpdate:
  794. type: object
  795. description: Partial update; only provided fields are updated
  796. additionalProperties: true
  797. Alert:
  798. type: object
  799. properties:
  800. id: { type: string }
  801. tracker_id: { type: string }
  802. type: { type: string }
  803. status: { type: string }
  804. timestamp: { type: string, format: date-time }
  805. AlertStatusUpdate:
  806. type: object
  807. required: [status]
  808. properties:
  809. status:
  810. type: string
  811. description: New status (e.g. resolved, acknowledged)
  812. ServiceStatus:
  813. type: object
  814. description: Health of an external service (e.g. Kafka, database)
  815. properties:
  816. status:
  817. type: string
  818. enum: [up, down, unknown]
  819. message:
  820. type: string
  821. description: Error detail when status is down
  822. BaseHealth:
  823. type: object
  824. properties:
  825. uptime: { type: string, description: Duration string }
  826. activeReaders: { type: array, items: { type: string } }
  827. activeWriters: { type: array, items: { type: string } }
  828. activeBeacons: { type: array, items: { type: string } }
  829. LocationHealth:
  830. allOf:
  831. - $ref: '#/components/schemas/BaseHealth'
  832. - type: object
  833. properties:
  834. activeSettings: { type: array, items: { type: object } }
  835. DecoderHealth:
  836. allOf:
  837. - $ref: '#/components/schemas/BaseHealth'
  838. BridgeHealth:
  839. allOf:
  840. - $ref: '#/components/schemas/BaseHealth'
  841. AggregatedHealth:
  842. type: object
  843. description: Health from location, decoder, bridge (via Kafka) plus server-checked Kafka and database
  844. properties:
  845. location: { $ref: '#/components/schemas/LocationHealth' }
  846. decoder: { $ref: '#/components/schemas/DecoderHealth' }
  847. bridge: { $ref: '#/components/schemas/BridgeHealth' }
  848. kafka: { $ref: '#/components/schemas/ServiceStatus' }
  849. database: { $ref: '#/components/schemas/ServiceStatus' }
  850. Track:
  851. type: object
  852. properties:
  853. id: { type: string }
  854. timestamp: { type: string, format: date-time }
  855. type: { type: string }
  856. status: { type: string }
  857. gateway: { type: string }
  858. gatewayMac: { type: string }
  859. tracker: { type: string }
  860. trackerMac: { type: string }
  861. subject: { type: string }
  862. subjectName: { type: string }
  863. floor: { type: string }
  864. signal: { type: integer }
  865. building: { type: string }