Design fixes: - D6: Cleaned up, points to separate activity-recording change - D13: Locked in TanStack Query + Zustand + React Context - D14: Tile hosting (OpenFreeMap default, configurable tileUrl) - D15: Photo/media (presigned upload URLs, thumbnails) - D16: Journal REST API implementation (api.v1.*.ts route modules) New specs (4): - web-push-relay: Web Push → APNs/FCM relay (Mastodon pattern) - api-contract-package: @trails-cool/api with Zod schemas - device-management: Connected devices list + revoke - photo-media: Presigned uploads, thumbnails, photo display Task updates: - Added Phase 2: Journal REST API (16 tasks) - Added Phase 7: Notifications (8 tasks) - Renumbered all phases (1-7) - 112 total tasks Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1.8 KiB
1.8 KiB
ADDED Requirements
Requirement: Connected devices list
The Journal web settings page SHALL display a list of connected devices (active OAuth2 sessions).
Scenario: View connected devices
- WHEN the user opens the account settings page on the Journal web UI
- THEN a "Connected Devices" section lists all active OAuth2 tokens with device name, last active timestamp, and approximate location (derived from IP)
Scenario: Device shows last active time
- WHEN a device makes an API request using its OAuth2 token
- THEN the Journal updates the token's last active timestamp and IP address
Requirement: Device metadata on token
Each OAuth2 token SHALL store device name, last active timestamp, and IP address.
Scenario: Device name stored on token exchange
- WHEN the mobile app exchanges an authorization code for tokens via
POST /oauth/token - THEN the device name (sent in the request body, e.g., "iPhone 15, iOS 18") is stored alongside the token record
Scenario: Last active updated on API use
- WHEN a bearer token is used to authenticate an API request
- THEN the token's
lastActiveAtandlastActiveIpfields are updated
Requirement: Revoke individual device tokens
Users SHALL be able to revoke individual device sessions from the Journal web settings page.
Scenario: Revoke device from web
- WHEN the user clicks "Revoke" on a connected device in the Journal settings
- THEN the OAuth2 token for that device is deleted and all subsequent API requests from that device fail with 401
Scenario: Revoke device from API
- WHEN a client sends
DELETE /api/v1/auth/devices/:idwith a valid bearer token - THEN the targeted device token is revoked (the requesting device can revoke other devices, not itself via this endpoint)