Falah OS — Nur Falah Estate & Waqf Suite

Sync API architecture — moslem04.falahos.my

A server-side sync layer for moslem04's six local-first modules, gated by casdoor login, encrypted client-side before it ever leaves the device, and surfacing only opt-in metadata to the admin console — never raw estate documents.

Out of scope: moslem03 (Muslim Companion) stays exactly as-is — free, zero signup, no account, no sync, forever. This spec touches nothing there.

01Data flow, end to end

moslem04 (browser) localStorage stays the source of truth offline; sync is additive, not a replacement
casdoor (existing) OIDC login, issues JWT — nothing new to build here
Sync API (new) Accepts encrypted blobs, tags with tenant + user, never decrypts
Postgres (new) Ciphertext + RAMZ tenant column + a small plaintext metadata row
Admin console Reads metadata only — opt-in, read-only, per Phase 2 below

02What gets encrypted vs. what admin can see

Estate plans are the most sensitive data a person will put into this app. The sync API is built so the server — and by extension the admin console — physically cannot read the contents of anyone's Faraid, Wassiyah, Hibah, or Waqf drafts. Encryption happens on-device before upload.

FieldWho can read itNotes
payload_ciphertextUser onlyAES-GCM, key derived from casdoor session + on-device passphrase. Server stores bytes it cannot open.
moduleUser + adminWhich of the 6 modules the record belongs to — plaintext, needed for routing and counts only.
plan_completedUser + adminBoolean per module. Lets the console show "how many people finished their Wassiyah" without seeing a single will.
panel_lawyer_requestedUser + adminExplicit opt-in flag the user sets — the only trigger that surfaces a person to a panel lawyer at all.
tenant_id (RAMZ)Admin onlyWhich tenant/firm this record is scoped to — still pending the row-level isolation decision from the PRD review.
claims_payload (H2)Nobody, not syncedHorizon 2 Claims module is excluded from sync entirely until the Phase 0 legal gate in DEPLOY.md clears.

03Endpoints

MethodPathPurpose
POST/v1/auth/exchangeTrade a casdoor OIDC token for a moslem04 session token
GET/v1/sync/pull?since=<ts>Fetch records changed since last sync — for restoring on a new device
POST/v1/sync/pushBatch upsert of encrypted blobs from the local device queue
DELETE/v1/sync/:record_idTombstone a record — deletes propagate across the user's own devices
POST/v1/consent/panel-lawyerThe one explicit opt-in action that makes a user visible to EstateOS admin at all
GET/v1/admin/metadataAdmin console read — returns only the plaintext metadata fields from §02, RAMZ-scoped

04Conflict handling

These are single-owner personal drafts, not shared documents — so last-write-wins by updated_at is sufficient for five of the six modules. Two exceptions: Family Waqf Designator can involve co-designators, so pushes there append to a change log instead of overwriting; Digital Claims (H2) doesn't sync at all, see §02.

05Rollout phases

Phase 0 Auth + sync plumbing Login, encrypted push/pull, cross-device restore. No admin visibility of any kind.
Phase 1 Opt-in metadata surface Panel-lawyer request flag goes live. Admin sees only what §02 allows.
Phase 2 · blocked Full admin console read view Waits on the RAMZ isolation decision and Core Ledger billing-event readiness — both still open from the earlier PRD review.