HOCO B2B
Team tasksAnis

SRV-23 — Offline sync — batch replay, delta pulls, idempotency

Idempotency records for every mutation, /sync/batch replay with per-item results and conflict codes, /sync/delta cursors for the delegate's offline scopes, occurredAt plausibility rules.

FieldDetails
Task codeSRV-23
PhaseP1 — V1 build & integration
Product scopeV1
StatusDone (Mon 19 Oct 2026)
StartMon 19 Oct 2026
DueMon 19 Oct 2026
ResponsibleAnis — Full-stack developer
Co-responsible—
Effort1.25 person-day(s) planned · 5 from scratch · size S
Area · appServer · server
Depends onSRV-21
UnblocksMOB-12
Milestones—

Summary

Idempotency records for every mutation, /sync/batch replay with per-item results and conflict codes, /sync/delta cursors for the delegate's offline scopes, occurredAt plausibility rules.

Description

Delegates work under weak network, so their app keeps the tour, visits, notes and photos locally and replays actions later (cahier §7.3; SYN-01…SYN-05). This task implements the server side of offline sync: idempotency records for every mutation, sync.batch that replays an ordered list of queued actions (each with its client UUIDv7 id, op, Idempotency-Key, occurredAt and body) and returns per-item results (SyncItemResult: APPLIED, REPLAYED, CONFLICT, REJECTED, RETRY) with stable conflict codes, and sync.delta that serves changes since a cursor for the delegate's offline scopes (today's and upcoming tours and visits, resellers in scope, tasks, visit types and checklists, reference lists, catalog subset for assisted orders) including tombstones when something leaves the scope. occurredAt plausibility follows AUTHORING §3 (future > 5 min or older than 72 h → OCCURRED_AT_OUT_OF_RANGE). Out of scope: the Flutter outbox (hoco_offline, Imad) and module business rules (SRV-21).

Subtasks

#SubtaskOwner
1Batch envelope schema (max 100 items / 5 MB), sequential execution per item in its own transaction, results array aligned with input orderAnis
2Op registry mapping batch ops to module procedures (delegate.visits., delegate.tours., delegate.resellers., delegate.tasks., delegate.assisted.*) with the same validationAnis
3Idempotent replay per item (REPLAYED with the original result) and client-id upserts for offline-creatable recordsAnis
4Dependency handling: item referencing a client id created earlier in the batch or in a previous batch; RETRY when the parent is missingAnis
5Conflict rules and codes: VISIT_LOCKED, TOUR_CLOSED, RESELLER_MERGED, OUT_OF_SCOPE, STALE_VERSION with the current server state in detailsAnis
6occurredAt / receivedAt storage and plausibility checks (OCCURRED_AT_OUT_OF_RANGE)Anis
7sync.delta: per-scope monotonic cursors (updatedAt + id), page size, tombstones for deletions and scope exits (e.g. reseller reassigned)Anis
8Metrics: batch sizes, conflict rates, replay counts per delegate for supportAnis
9Conflict-handling and retry policy alignment with hoco_offlineImad

Deliverables

  • apps/server/src/modules/sync/{batch.ts,op-registry.ts,delta.ts,cursors.ts,router.ts}
  • packages/contracts/src/sync.ts with item result and conflict schemas
  • /docs/srs/offline-sync-design updated with the final conflict codes

Acceptance criteria

  • Replaying the same batch twice returns REPLAYED for every item and creates no duplicate visit, photo, note or prospect (SYN-05)
  • An item with occurredAt 4 days in the past is REJECTED with OCCURRED_AT_OUT_OF_RANGE
  • Ending a visit that the back-office already locked returns CONFLICT VISIT_LOCKED with the server state
  • A reseller reassigned to another delegate appears as a tombstone in the next sync.delta of the previous delegate
  • A batch of 100 items completes within 5 seconds on staging

Requirements covered

RequirementTitleRelease
SYN-01Back-office → apps flows: accounts, roles, zones, tours, objectives, tasks, catalog, prices, stock, promotions, order statuses, invoices, notifications, support repliesV1
SYN-02Apps → back-office flows: sign-ups, profiles, orders, addresses, payments, claims, positions, visits, photos, checklists, reports, installs, conversionsV1
SYN-03Critical data sent immediately when a connection is availableV1
SYN-04Delegate app keeps the tour, visits, notes and photos locally under weak networkV1
SYN-05Sync queue handling retries, duplicates (idempotency), errors and conflictsV1

API surface

Endpoint groupOperations
Offline sync & location3

Test measures

  • DB tests for replay, dependency ordering and conflicts
  • Fuzz test: random interleaving of offline actions and back-office edits keeps invariants (no duplicates, no lost reports)
  • Joint test with Imad: airplane-mode tour on a device, then sync

Risks

  • Clock skew on delegate phones — keep both occurredAt and receivedAt, use receivedAt for ordering conflicts and occurredAt only for display and plausibility

KPI

  • Delivered by Mon 19 Oct 2026 within 1.25 person-day(s).
  • Every acceptance criterion above demonstrated before hand-off; linked requirements' acceptance criteria pass.
  • Zero open critical defects, permission gaps or data-integrity regressions at sign-off.

Generated from content/plan/tasks.json by scripts/generate-team-tasks.mjs. Dates are computed by the scheduler (Sunday–Thursday weeks, holidays excluded) — change the plan, not this page.

On this page