a0c70e141125f3540f602ff31007ee2f4660576c
6 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a0c70e1411 |
Add estate agent delegation: real accounts, multi-tenant backend, RLS-enforced roles
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. |
||
|
|
4d244db6d0 |
Add (i) info button to every tab, explained for the average user
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. |
||
|
|
07b9f4f07a |
Cover digital assets and vehicles with proper fast-path instruments
Digital assets: nonprobate.js's suggestion previously claimed channel 'bank-mandate' with label 'Multi-sig / pre-authorized release' — a mismatch, since bank-mandate's fields (institution/nominee/reference) don't fit crypto custody at all. New "digital-custody" channel with custody-type-specific fields: exchange beneficiary feature, self-custody multi-sig (warns that it only works if a living co-signer is already configured), or key-escrow with executor (warns explicitly: never store the actual seed phrase or private key in this app or any single record — only a reference to WHERE access is arranged). Vehicles/jewelry/valuables: were lumped into the same "trust" suggestion as land, which is overkill for movable property that hands over cleanly by a simple Hibah. Suggestion now points straight to Hibah for these; land keeps the trust suggestion since it has no such easy path. CoverageDashboard's suggestion-inline text simplified from an ad-hoc ternary chain into a clean NEXT_STEP_TAB map, now correctly covering hibah/trust/digital-custody/business-continuity. e2e-digital-vehicle.cjs: new suite verifying digital asset exposed -> custody-type warnings -> export -> covered, and vehicle exposed -> Hibah suggestion (not trust) -> covered via Hibah link -> 100% combined coverage. 10/10 passing. Re-verified all four prior suites (32/32, 16/16, 12/12, 10/10) — 80/80 total, no regressions. |
||
|
|
051c9d9a94 |
Cover business interests via a proper continuity instrument
Same gap as land parcels: business assets were routed into the generic trust fields (trustee/successor/beneficiaries), which don't fit — a business needs a continuity instrument, not a trustee holding title. New "business-continuity" channel in Nomination Registry, modelled on the digital-waqif docs repo's own business-succession framework (Clause 9): - Structure selector (sole proprietorship / partnership / company). Sole proprietorship surfaces an explicit warning: it legally dies with the owner, so the only fast-path options are converting to a company or dedicating as a waqf-owned enterprise. - Instrument selector: partnership continuation clause, shareholder buy-sell agreement (the standard fast-path for company shares, often Takaful-funded), or a direct redirect to Family Waqf Designator for a waqf-owned enterprise (nothing duplicated here — reuses that module). - Dedicated business-continuity-draft.txt export, same treatment as the trust deed and waqfiyya exports. - Death Trigger packet text updated with the business-specific execution action (execute buy-sell / continuation clause, file Takaful claim if funded — a private agreement between owners, not a probate filing). e2e-business.cjs: new suite covering exposed->warning->instrument selection->export->100% coverage->execution packet, plus the waqf-enterprise redirect disabling the Add button. 10/10 passing. Re-verified e2e-uat.cjs (32/32), e2e-fastpath.cjs (16/16), and e2e-trust.cjs (12/12) — 70/70 total, no regressions. |
||
|
|
ff47dc9ed2 |
Cover land parcels via proper trust setup, not generic nomination fields
Nomination Registry's "trust" channel type previously reused the same nominee/institution fields as EPF/Takaful/bank nominations — wrong shape for a trust, which needs a trustee (and successor) holding title, not a beneficiary named on a policy. Coverage math already counted any nomination-type entry as fast-path regardless of shape, so land parcels were silently "covered" without the actual structure a trust requires. Now: selecting "trust" swaps in trustee/successor-trustee/beneficiaries fields, and adds a dedicated trust-setup drafting-aid export (same treatment as the Waqf deed export) explaining what still needs a real trust company/lawyer to execute. e2e-trust.cjs: new suite verifying the full path for a land parcel — exposed -> trust suggestion -> trustee fields -> deed export -> coverage flips to 100% -> death trigger generates its execution packet. 12/12 passing. Re-verified e2e-uat.cjs (32/32) and e2e-fastpath.cjs (16/16) with no regressions. |
||
|
|
ad2b3c48a3 |
Rebuild around the real mechanism: bypass Faraid/probate entirely
Product direction clarified: Faraid/probate court adjudication is what takes ~2 years. Assets already moved out of the estate before death (via completed Hibah, dedicated Waqf, or a legally-direct nomination channel) are never in that queue — there's nothing for a court to adjudicate. The app's job is to maximize what's covered by those instruments and make the death-triggered payout fast for whatever is covered. New: - nonprobate.js: coverage model — classifies each Asset Registry entry by fast-path channel (hibah/waqf/nomination) vs exposed (faraid/probate). - CoverageDashboard.svelte: the single number that matters — % of estate that bypasses Faraid entirely, with per-asset next-step suggestions. - NominationRegistry.svelte: third fast-path channel for assets that can't be fully gifted/waqf'd — EPF (EPF Act 1991 s.51), Takaful/insurance (Insurance Act 1996 s.166), bank death-mandate, trust/nominee holding. - DeathTrigger.svelte: the execution layer. Multi-attestor threshold + death certificate reference fires the trigger; generates a ready-to-file execution packet per covered asset, pre-filled from Hibah/Waqf/Nomination records. Explicitly scoped: this app cannot itself move money or transfer title, but removes missing-paperwork/ambiguity as a source of delay so institutions can act in days instead of stacking behind a probate queue. Changed: - HibahTracker/FamilyWaqfDesignator: now link to a specific Asset Registry entry so coverage can be computed; fast-path explanation added to both. - WassiyahGenerator: explicit warning that a wassiyah does NOT bypass probate — it's a post-death instrument, only appropriate for the discretionary one-third, not a fast-track vehicle. Users were previously not told this distinction. - FaraidCalculator: reframed as informational-only, showing what applies to whatever remains uncovered — not itself a mechanism. e2e-fastpath.cjs: new Playwright suite covering the full mechanism end-to-end (coverage 0%->100%, nomination, multi-attestor trigger threshold, execution packet generation) — 16/16 passing. Original e2e-uat.cjs suite re-verified at 32/32 with no regressions. |