ルーティング (routes)¶
routes/* は HTTP API の集合で、Express ルータを機能別に分割し /api 配下へマウントします。
別途 /call/* で通話 UI を提供します。
マウント構成(全体像)¶
-
routes/index.js
/api→apiRoutes(io)(device / player / admin を合流)
/call→callRoutes(通話 UI) -
routes/apiRoutes.js(/api 配下) routes/device/*(端末向け)routes/player/*(プレイヤ向け)routes/admin/*(人間向け)
認証・認可の前提¶
requireHumanUserによりuserExternalId必須(query/body/params のいずれか)assertUserCanAccessDevice/assertUserCanAccessCustomerは RDS 参照でアクセス確認requireMasterUserはMASTER_USER_EXTERNAL_IDSによる管理者限定requireInternalTokenはx-internal-tokenヘッダ必須(INTERNAL_API_TOKENと一致)- 端末 mTLS 系 API は Host が
device.api.xrobotics.jpかつx-client-certヘッダ必須 - X.509 から certId を計算し、IoT で thingName を解決して
deviceIdとして扱う
1) Device 向け(/api)¶
IP/MAC/Device Info 登録(認証なし)¶
POST /api/ip/register
Body:{ deviceId, localIp, iface?, byInterface? }POST /api/mac/register
Body:{ deviceId, macAddress, iface?, byInterface? }POST /api/device-info/register
Body:{ deviceId, info }
同期完了通知(RDS 更新)¶
POST /api/devices/:deviceId/sync-complete
Body:{ customerId?, playlistId?, syncedAt? }
syncedAtが指定された場合は日時として検証し、device_playlists.last_sync_atを更新。
端末ログ転送(mTLS)¶
POST /api/logs/journal
x-client-cert必須。CloudWatch Logs に書き込み。
IoT バンドル取得(mTLS)¶
GET /api/iot/bundle
署名付き URL と SHA256 を返す(存在しない場合は204)。
OTA マニフェスト取得(mTLS)¶
GET /api/ota/manifest
signage-jetson/signage-server/xignage-edge-detection/signage-jetson-patchesをまとめて返却。
2) Player 向け(/api)¶
プレイリスト取得¶
GET /api/devices/:deviceId/playlist
Query:customerId?,playlistId?
端末の割当プレイリストを解決し、再生用の配列を返す。
メディアマニフェスト¶
GET /api/devices/:deviceId/media-manifest
Query:customerId?,playlistId?
S3 の presigned download URL を含むメディア一覧を返す。
TODO¶
/api/playlist/thumbnail
TODO: プレイリストレスポンスがこの URL を返すが、該当ルート定義が見当たらない。
根拠:signage-aws-nodejs/routes/player/devicePlaylistRoutes.js:157(thumbnailUrl生成)。
3) Admin/Human 向け(/api)¶
Commands(/api/commands/*)¶
GET /api/commands/send
Query:deviceId,command,fileName?,isSingle?
commandはplayVideo|showImage|switchViewに限定POST /api/commands/send
Body:{ deviceId, command, payload }
commandはsetVolume|toggleVolumeのみPOST /api/commands/start//stop//rotate//updatePOST /api/commands/network/resetPOST /api/commands/sync-content(admin-ui 向け)POST /api/commands/network/report
Socket 側へnet:reportを emit し、ACK を 15 秒待機
Device Settings(/api/deviceSettings)¶
GET /api/deviceSettings?deviceId=...GET /api/deviceSettings/:deviceIdPATCH /api/deviceSettings/:deviceId
autoPlaylist必須。Socket でgetConfig/updateConfigを送信し ACK を待機
Device Wi-Fi(/api/deviceWifi)¶
GET /api/deviceWifi/:deviceIdGET /api/deviceWifi/:deviceId/networksDELETE /api/deviceWifi/:deviceId/:ssid
Socket でgetWifiNetworks/deleteWifiNetworkを送信し ACK を待機
Device Info / Status¶
GET /api/device-info?deviceId=...
登録済み info を{ key, value }配列で返却POST /api/device-info/update
requestDeviceInfoを Socket へ送信して取得GET /api/status?deviceId=...
接続状態(接続中/未接続)
IP / MAC 参照¶
GET /api/ip?deviceId=...&iface?&full?GET /api/mac?deviceId=...&iface?&full?
full=1の場合は既知インタフェースを埋めたスナップショットを返す
Power¶
POST /api/device/power/shutdownPOST /api/device/power/reboot
Versions / Patch¶
GET /api/version/versions?deviceId=...GET /api/patchMigState?deviceId=...
OpenAI¶
POST /api/openai/ask
OPENAI_API_KEY必須。返答はio.emit('updateText', { text })で配信。
Doorbell¶
POST /api/doorbell/start-call
Daily の Room を作成し、doorbell:startCallをデバイスへ送信POST /api/doorbell/end-call
switchView('kiosk.html')をデバイスへ送信
Content(/api/content/*)¶
Media¶
GET /api/content/mediaPOST /api/content/media/upload-urlPOST /api/content/media/complete-uploadPATCH /api/content/media/:mediaIdDELETE /api/content/media/:mediaIdPOST /api/content/media/thumbnail(内部トークン必須)
Playlists¶
GET /api/content/playlistsPOST /api/content/playlistsPATCH /api/content/playlists/:idDELETE /api/content/playlists/:idGET /api/content/playlists/:id/itemsPUT /api/content/playlists/:id/itemsPOST /api/content/playlists/:playlistId/itemsDELETE /api/content/playlists/:playlistId/items/:playlistItemId
Device Playlist Mapping¶
PUT /api/content/device-playlists/:deviceIdGET /api/content/device-playlists
Device Playlist 状態(/api/devices/*)¶
GET /api/devices/:deviceId/playlist-assignmentGET /api/devices/:deviceId/sync-status
User(/api/user/*)¶
GET /api/user/devices
devices/customers/selectedDeviceId/selectedCustomerIdを返却
4) Admin/Master & Internal(/api)¶
Admin 管理(/api/admin/*)¶
requireMasterUser を必須とし、DB を直接操作します。
GET/POST/PATCH/DELETE /api/admin/devicesGET/POST/DELETE /api/admin/device-usersGET/POST/PATCH/DELETE /api/admin/customers
IoT 管理(/api/admin/iot/*)¶
GET /api/admin/iot/drift/:deviceId(IoT と DynamoDB の差分検出)POST /api/admin/iot/publish/:deviceId(バンドル再発行)POST /api/admin/iot/cleanup/:deviceId(古い証明書の削除)
IoT Drift(/api/iot/*)¶
GET /api/iot/drift/:deviceId(x-internal-token必須)
mTLS Last Seen(/api/mtls/*)¶
GET /api/mtls/last-seen/:deviceId(x-internal-token必須)GET /api/admin/mtls/last-seen/:deviceId(Master ユーザ or 内部トークン)
DynamoDB Ledger(/api/ledger/*)¶
GET /api/ledger/devices(Master ユーザ)GET /api/ledger/devices/:deviceId(Master ユーザ)GET /api/admin/ledger/devices(Master ユーザ)GET /api/admin/ledger/devices/:deviceId(Master ユーザ)
5) Call UI(/call/*)¶
GET /call/join/mobile/:callId
Daily 通話用の HTML UI を返す(モバイル参加用)GET /call/join/device/:callId
Daily 通話用の HTML UI を返す(デバイス参加用)
共通前提¶
- 接続管理:
deviceSockets: Map<deviceId, socketId>(requestStores.js) - Socket サーバ:
getIO()(socket/index.js) - エラー方針:
400入力不足 /403権限不足 /404未接続 /500内部異常
タイムアウトは原則504相当(実装差あり)