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>
2.6 KiB
2.6 KiB
ADDED Requirements
Requirement: Zod schemas as source of truth
The @trails-cool/api package SHALL define all API request and response shapes as Zod schemas, with TypeScript types inferred via z.infer<>.
Scenario: Server validates request body
- WHEN the Journal server receives a request body for a known endpoint
- THEN it validates the body using the corresponding Zod schema from
@trails-cool/apiand returns a structured 400 error on failure
Scenario: Client validates response
- WHEN the mobile client receives a response from a Journal instance (especially self-hosted on an older version)
- THEN it can optionally validate the response against the Zod schema to detect incompatibilities
Requirement: API version constant
The package SHALL export an API_VERSION semver constant as the single source of truth for the current API version.
Scenario: Version bump in one place
- WHEN the API version needs to be bumped (new endpoint, new field, breaking change)
- THEN the version is changed in
@trails-cool/apiand both the Journal server and mobile client see it at compile time
Requirement: Endpoint path constants
The package SHALL export typed constants for all API endpoint paths.
Scenario: Endpoint paths used by server and client
- WHEN the server registers a route or the client constructs a URL
- THEN both import the path from
@trails-cool/api(e.g.,ENDPOINTS.routes.listresolves to"/api/v1/routes")
Requirement: Request and response schemas
The package SHALL define Zod schemas for all API endpoints.
Scenario: Routes schemas
- WHEN a route-related endpoint is called
- THEN schemas exist for
RouteListResponse,RouteDetailResponse,CreateRouteRequest,UpdateRouteRequest
Scenario: Activities schemas
- WHEN an activity-related endpoint is called
- THEN schemas exist for
ActivityListResponse,ActivityDetailResponse,CreateActivityRequest
Scenario: Auth schemas
- WHEN an auth-related endpoint is called
- THEN schemas exist for
TokenExchangeRequest,TokenResponse,DiscoveryResponse
Scenario: Upload schemas
- WHEN an upload-related endpoint is called
- THEN schemas exist for
PresignedUploadRequest,PresignedUploadResponse
Requirement: Error response schema
The package SHALL define a standard error response schema used by all endpoints.
Scenario: Error shape
- WHEN any API endpoint returns an error
- THEN the response matches the
ApiErrorResponseschema:{ error: string, code: string, fields?: Array<{ field: string, message: string }> }