Commit graph

3 commits

Author SHA1 Message Date
Ullrich Schäfer
61a2d0085b
one source of truth for Route/Activity shapes; enforce api contracts
Route and Activity existed three times: hand-written interfaces in
packages/types, Zod contracts in packages/api, and Drizzle columns in
packages/db — each with different fields and nullability. The
hand-written ones had drifted so far they had zero importers; the Zod
contracts were advisory because v1 handlers hand-rolled Response.json
shapes nothing validated.

- packages/types keeps only what both apps actually share (Waypoint,
  WaypointPoiTags) and documents where row types and wire contracts
  live; the dead Route/RouteMetadata/RouteVersion/Activity interfaces
  are gone
- packages/db exports canonical inferred row types (RouteRow,
  ActivityRow, RouteVersionRow, UserRow)
- packages/api contracts are reconciled with the real wire format
  (RouteVersionSchema gains the id and createdBy fields the endpoint
  has always returned) and gain Create*ResponseSchemas
- apiJson(schema, payload) in api-guard parses every v1 response
  through its contract: drift is now a thrown ZodError in tests/CI,
  unknown keys are stripped, and payloads are compile-checked as
  z.input of the schema

Enforcement immediately caught two real drifts: nullable DB
descriptions could ship null where the contract promises string (now
coalesced at the boundary), and GET /api/v1/activities/:id was missing
the routeName and photos fields its contract declares.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 07:39:50 +02:00
Ullrich Schäfer
067e2ebd0b
fix: enforce Terms gate on bearer-token API requests
Mobile API requests authenticated via OAuth2 bearer tokens bypassed the
Terms gate that the root loader applies to web cookie sessions. Extend
requireApiUser to compare the user's termsVersion with TERMS_VERSION
and return a structured 403 { code: "TERMS_OUTDATED", currentTermsVersion }
on mismatch so mobile clients can surface their own re-acceptance UI.

Spec delta on journal-auth captures the new requirement.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 01:59:28 +02:00
Ullrich Schäfer
18c3c37eaf
Implement Journal REST API v1 endpoints
Add all REST API endpoints for mobile app consumption:

Routes:
- GET /api/v1/routes — paginated list with cursor, Zod validation
- GET /api/v1/routes/:id — full detail with GPX, versions
- POST /api/v1/routes — create with Zod-validated body
- PUT /api/v1/routes/:id — update, creates new version
- DELETE /api/v1/routes/:id — returns 204

Activities:
- GET /api/v1/activities — paginated list with cursor
- GET /api/v1/activities/:id — full detail
- POST /api/v1/activities — create with GPX stat extraction
- DELETE /api/v1/activities/:id — returns 204

Supporting:
- POST /api/v1/routes/compute — BRouter proxy
- POST /api/v1/uploads — presigned upload URL generation

Device management:
- GET /api/v1/auth/devices — list connected devices with isCurrent
- DELETE /api/v1/auth/devices/:id — revoke device token
- Store device_name on token exchange

Infrastructure:
- requireApiUser() guard — returns 401 with structured error
- apiError() helper for consistent error responses
- All endpoints use Zod schemas from @trails-cool/api for validation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 00:57:27 +02:00