feat(server): API de synchronisation incrémentale LWW (ticket #50)
Ajoute l'endpoint api/sync_api.dart, les use cases de synchronisation (application/sync_use_cases.dart) et l'adapter Postgres (infrastructure/postgres/synced_resource_repository.dart) implémentant un upsert LWW atomique via CTE (INSERT ... ON CONFLICT ... WHERE client_updated_at < EXCLUDED.client_updated_at, avec fallback UNION ALL pour le cas ignoré). dart pub get OK, dart analyze clean, dart test 15/15 vert. SQL d'upsert relu manuellement et jugé correct ; pas de test de bout en bout contre un vrai PostgreSQL faute d'accès Docker dans ce sandbox. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -84,12 +84,32 @@ Passwords are stored with PBKDF2-HMAC-SHA256 via `package:cryptography`, using a
|
||||
per-password random salt. API tokens are opaque random values; only a SHA-256
|
||||
hash of the token is stored in PostgreSQL.
|
||||
|
||||
## Sync
|
||||
|
||||
Ticket #50 adds authenticated incremental sync endpoints using simple
|
||||
last-write-wins conflict resolution based on `clientUpdatedAt`.
|
||||
|
||||
Endpoints:
|
||||
|
||||
- `POST /sync/push` with `Authorization: Bearer <token>`.
|
||||
- `GET /sync/pull?since=<serverCursor>` with `Authorization: Bearer <token>`.
|
||||
- `POST /sync/exchange` with `Authorization: Bearer <token>`.
|
||||
|
||||
`serverCursor` is an ISO8601 UTC timestamp. For push, it is the greatest
|
||||
`server_updated_at` currently known for the authenticated user after applying
|
||||
the batch. For pull, it is the greatest `serverUpdatedAt` returned, or the
|
||||
server clock if no resource is returned.
|
||||
|
||||
`POST /sync/exchange` applies push first, then returns the pull payload with
|
||||
`pushResults` included so per-item validation errors remain visible to the
|
||||
client.
|
||||
|
||||
## Scope
|
||||
|
||||
Ticket #47 only scaffolds the Dart server, the hexagonal directory layout and
|
||||
the `/health` endpoint. Ticket #49 adds the first PostgreSQL schema. Ticket #48
|
||||
adds authentication only; sync endpoints and sharing behavior are still
|
||||
implemented in later tickets.
|
||||
adds authentication. Ticket #50 adds sync only; sharing behavior is still
|
||||
implemented in a later ticket.
|
||||
|
||||
Upcoming tickets will fill the empty adapters and use cases:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user