managarten/services/mana-sync/internal/sync
Till JS bfa1c0260f feat(mana-sync): persist actor JSON on every sync_changes row
Adds an opaque JSON `actor` column alongside the existing field_timestamps
so cross-device consumers can distinguish user / ai / system writes. The
server never parses the shape — it just stores and re-emits the blob the
webapp stamped in its Dexie hook.

- `sync/types.go` — Change.Actor as json.RawMessage with omitempty; nil
  for pre-actor clients so wire remains backward-compatible
- `store/postgres.go`
  - Migrate: CREATE TABLE includes `actor JSONB` for fresh DBs;
    ALTER TABLE ADD COLUMN IF NOT EXISTS actor JSONB for existing ones
    (idempotent, safe to re-run)
  - RecordChange signature takes json.RawMessage; pgx writes nil as NULL
  - All three SELECT paths (GetChangesSince, GetAllChangesSince,
    StreamAllUserChanges) return actor, Scan into ChangeRow.Actor
  - ChangeRow.Actor added with doc noting "missing = user" consumer rule
- `sync/handler.go` — Change.Actor threaded through HandleSync →
  RecordChange, and populated on both changeFromRow (pull/POST replies)
  and convertChanges (SSE stream)
- Tests: roundtrip of an AI-actor payload + omitempty verification for
  pre-actor clients. All existing tests still pass.

Webapp types still need `actor?: Actor` on SyncChange + PendingChange to
match the wire, and applyServerChanges needs to stamp __lastActor /
__fieldActors from incoming changes for Workbench attribution on other
devices — both tracked as separate follow-ups.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 23:31:01 +02:00
..
handler.go feat(mana-sync): persist actor JSON on every sync_changes row 2026-04-14 23:31:01 +02:00
handler_test.go feat(mana-sync): persist actor JSON on every sync_changes row 2026-04-14 23:31:01 +02:00
types.go feat(mana-sync): persist actor JSON on every sync_changes row 2026-04-14 23:31:01 +02:00