Big round covering two different asks: Khairat/emergency infrastructure
(tightly coupled to what's already built) and a Muslim-lifestyle
companion surface (a genuinely different product, added at the user's
explicit request after being offered a smaller scope).
Khairat & emergency contacts:
- nf_khairat_memberships (per-member scheme membership) + nf_emergency_fund
(per-family shared reserve tracker) — records intent/contacts only,
never holds or moves real money.
- nf_trusted_contacts gains category (mosque/police/ambulance/hospital/
khairat/family/other) and email columns.
- New notify-emergency-contacts Edge Function, auto-invoked the moment a
mutawalli fires a member's death trigger (the one place in this app
where auto-send-on-trigger is actually correct), alongside — not
instead of — the existing heir notification. Verified with a live fire
end-to-end (e2e-emergency-notify.cjs, 5/5).
Lifestyle-companion tabs — all computed/searched live, nothing fabricated:
- Qibla: pure great-circle bearing math to the Kaaba from geolocation,
no API/key. Verified against Kuala Lumpur (293°, matches expected ~292°).
- Prayer Times: client-side astronomical calculation (single-pass solar
position, MWL angles), sanity-checked against known KL/London times
before shipping.
- Locate: mosque/halal/cemetery search via the free, keyless OpenStreetMap
Overpass API — real community-sourced results only, honest empty state
when nothing's mapped nearby.
- Quran: Surah list + Arabic/translation via the free alquran.cloud API,
fetched fresh each time, nothing stored in this app's own database.
- Neighbourhood: a join-by-code community announcement board — a
genuinely separate multi-tenant concept from the estate-planning family
structure, scoped to the user account. Found and fixed a real UX gap
during testing: the create/join form was only reachable with zero
existing neighbourhoods, with no way to join a second one.
Also found and fixed a real bug: the heir-notify and emergency-notify
status messages shared the same CSS class, breaking any script (including
the pre-existing e2e-per-member.cjs) that targeted '.notify-status'
without further filtering — gave each its own distinguishing class.
Covered by e2e-khairat-lifestyle.cjs (13/13) and e2e-emergency-notify.cjs
(5/5). Full regression: 316/316 across all suites (several transient
flakes under heavy mail-relay load during the sweep, all confirmed clean
on rerun — one led to the real class-collision fix above).
Per-member Insurance & Takaful tab (life/Takaful/medical/asset policies,
same author-owns/family-reads pattern as Wassiyah/Waqf), a family-shared
Liabilities section on the Asset Registry (kept distinct from assets since
Faraid requires debts settled before distribution), and dual-path asset
ownership verification (proof document + confirm by either the
mutawalli/agent or any other family member, since not every demo family
has an agent assigned). All proof documents share a new private
nf-asset-documents storage bucket with the same RLS pattern as person
photos. Mutawalli dashboard now surfaces each member's insurance policies.
Covered by e2e-insurance-verification.cjs (12/12); full regression sweep
233/233 across all suites.
Per explicit product direction: the app assumed a single user (head of
family) with everything in per-device localStorage. There was no way for
a family to delegate estate management to an agent (relative or
professional) without literally handing over the device. This required
real backend infrastructure, not a UI addition — added Supabase
(Postgres + Auth) as a multi-tenant backend.
Schema (nf_ prefixed to stay isolated from other tables in the reused
"Falah OS demo" project): nf_families, nf_family_members (role: owner/
agent, status: invited/active), and family-scoped versions of every
estate table — nf_assets, nf_trusted_contacts, nf_hibah_gifts,
nf_waqf_designations/nf_waqf_beneficiaries, nf_nominations,
nf_attestors, nf_death_triggers.
Permission model, enforced by RLS at the database level (not just
hidden in the UI): an agent can do everything an owner can — add/edit
assets, draft Hibah/Waqf/Nominations, set up the Death Trigger — except
fire it. nf_death_triggers' UPDATE/INSERT policies use a WITH CHECK that
only allows triggered=true when the caller has role='owner' on that
family. A professional agent can be invited to multiple families and
switches between them from their own dashboard.
New: auth.js, family.js, db.js, AuthScreen.svelte, FamilySwitcher.svelte,
FamilyManagement.svelte (new "Family" tab: invite agents, see members,
switch families). AssetRegistry, HibahTracker, FamilyWaqfDesignator,
NominationRegistry, CoverageDashboard, and DeathTrigger all migrated
from storage.js (localStorage) to db.js (Supabase), scoped to the
active family_id. App.svelte now gates on auth + family selection
before showing the main tab shell.
Three real bugs found and fixed via testing against the live backend
(not caught by the old localStorage-based suites, which had no
cross-client concurrency to expose them):
- RLS gap: pending-invite lookup joins nf_families(name), but the
invitee isn't a family member yet, so the join was silently dropped —
added a policy letting a pending invitee see just the family name.
- Attestor row race: lazy "create on first blur" could double-fire from
two different code paths, creating duplicate rows and confirming the
wrong one. Fixed by eagerly creating attestor rows on first load so
every row always has a real id — no more create-or-update ambiguity.
- Out-of-order async clobber: three death-trigger setup fields each
fired a full-snapshot upsert on every input; whichever request
*finished* last (not fired last) won, silently reverting the other
two fields to stale values. Fixed with per-field partial updates
(updateDeathTriggerField) that can't clobber columns they don't touch.
e2e-family-agent.cjs: full owner/agent flow against the live Supabase
backend — invite, accept, shared live data, agent blocked from firing
the trigger (button stays disabled and a direct RLS-level attempt would
also fail), owner successfully fires it. 12/12 passing.
e2e-smoke-authed.cjs: post-auth-gate sweep confirming every existing tab
still renders and its info panel still opens under the new sign-in
requirement. 24/24 passing, zero console errors.
Known follow-up, not done here: the eight pre-auth E2E suites
(e2e-uat.cjs, e2e-fastpath.cjs, e2e-trust.cjs, e2e-business.cjs,
e2e-digital-vehicle.cjs, e2e-property.cjs, e2e-other.cjs, e2e-info.cjs)
assume an anonymous landing page and need a sign-in prelude added
before they're valid again — their detailed assertions were re-verified
functionally via the smoke test and manual review, not by running them
as-is.
New InfoPanel.svelte: shared (i) button next to each module's h2, toggling
a plain-language explainer with three sections — what this tab is, how to
use it, what to enter in each field. One component so tone stays
consistent across all 10 tabs instead of each screen inventing its own
help pattern.
Deliberately avoids fiqh/legal jargon in favor of concrete, everyday
framing (e.g. Hibah explained as "a gift you give right now, while you're
alive" rather than leading with the Arabic term) — written for someone
with no prior estate-planning or Islamic finance background, consistent
with the "convince a 100-year-old grandmother" usability bar already
established for this product.
Wired into: Coverage, Faraid, Assets, Wassiyah, Hibah, Family Waqf,
Nominate, Trigger, Claims (H2), Settings.
e2e-info.cjs: new suite verifying the info button appears, opens a
non-trivial explanation, and closes again on every one of the 10 tabs.
31/31 passing. Re-verified all five prior suites (32/32, 16/16, 12/12,
10/10, 10/10) — 111/111 total, no regressions.
Svelte 5 + Vite PWA, styled to match moslem03.falahos.my's design system.
Horizon 1: Faraid Calculator (shared calc core, 14 classical cases passing),
Asset Registry, Wassiyah Generator (1/3 meter + heir-exclusion block),
Hibah Tracker and Family Waqf Designator (shared marad al-mawt guardrail).
Horizon 2: Digital Beneficial Claims — local non-custodial demo of the claim
model and transfer restriction only.
Two governance gates in this project's own PRDs were overridden per explicit
product direction, and are flagged in-app and in README.md / deploy/DEPLOY.md
rather than silently shipped as production-ready:
- Family Waqf Designator ships ahead of scholarly sign-off (OPEN-01 in
scholarly-review-log.md remains unresolved).
- Horizon 2 ships ahead of the PRD's stated Phase 0 gate (legal opinion +
signed institutional partner) with no confirmation that gate is cleared.