49706e0cd200699d46ca16846d5f6548534de930
17 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
49706e0cd2 |
feat: add insurance/Takaful tracking, liabilities, and asset ownership verification
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. |
||
|
|
d5e25e9f8e |
Seed 5 fully-populated demo families with dummy assets, coverage, and trees
Per explicit request: "full dummy data on at least 5 families with dummy assets and family members." Seeded directly against the live Supabase backend (SQL, not driving the UI 5x) for speed and reliability, then verified through the actual live app rather than trusting the inserts. 5 families, each with a distinct role in demonstrating the app: - The Ismail Family (100% coverage) — near-fully-planned estate: Hibah, bank-mandate nomination, digital-custody (key-escrow) nomination, business-continuity (company shares). Has an extra member (spouse) and an agent/mutawalli. - The Rahman Family (UK, 20% coverage) — diaspora market, partial coverage, exercises Wassiyah (charitable bequest) alongside Hibah/ Nomination. Has an extra adult-child member. - The Osman Family (31% coverage) — deliberately mostly UNCOVERED to demonstrate the Coverage Dashboard's warning state and per-asset suggestions; includes a sole-proprietorship business with the waqf-enterprise redirect note. - The Yusuf Family (94% coverage) — young family, digital-asset-heavy (multisig nomination). Shares the same mutawalli/agent as Ismail — demonstrates one professional agent managing multiple families. - The Karim Family (100% coverage) — Family Waqf demo: an apartment dedicated as corpus with a named mutawalli and successor. Every fast-path channel type (Hibah, EPF/bank-mandate, digital-custody in both multisig and key-escrow modes, business-continuity in both company-shares and sole-proprietorship modes, trust, family waqf) and every family role combination (owner-only, owner+member, owner+member+ agent, shared cross-family agent) now has at least one real example. Each family also has a genealogy tree (3-6 people, parent/child and spouse relationships) so the Tree tab is never empty for a demo. DEMO_DATA.md documents all logins (shared password DemoPassword123!), what each family demonstrates, and the verification method. verify-demo-families.cjs: confirms all 5 families actually render correctly in the live app, not just that the SQL succeeded — sign-in, correct asset count, non-zero estate total, coverage percentage, correct person count, non-empty tree render. 35/35 passing. Also fixed a genuinely flaky e2e-uat.cjs assertion found while re-verifying after seeding — same instant-isVisible()-after-fixed-wait pattern already fixed elsewhere in this session, now using a proper waitFor(). Stable across 3 consecutive runs (32/32 each). Full sweep after seeding: e2e-fastpath 16/16, e2e-trust 12/12, e2e-business 10/10, e2e-digital-vehicle 10/10, e2e-property 9/9, e2e-other 4/4, e2e-info 31/31, e2e-per-member 11/11, e2e-family-tree 9/9 — 209/209 total across all suites plus the 35 demo-family checks. |
||
|
|
e7a111c387 |
Add mini family genealogy tree with per-person photos
Per explicit request: "mini family genealogy mapping with ability to add
photos on each family member." Scoped via clarifying questions: people are
lightweight records independent of login accounts (most real tree nodes —
grandparents, deceased relatives, young children — never sign up),
relationships support parent/child + spouse (enough to render a real
multi-generation tree), photos go to Supabase Storage (native to the
backend already in use, no new infrastructure).
Schema: nf_people (name, gender, birth/death dates, notes, optional
linked_user_id if the person also happens to have a real account,
photo_path) and nf_relationships (person_a/person_b + type: parent_of
directional, spouse_of symmetric). Both family-member-shared like the
Asset Registry — any owner/agent/member can view and edit, unlike the
per-author Wassiyah/Waqf model. New private Storage bucket
nf-people-photos, path convention {family_id}/{person_id}/{filename} so
RLS can check family membership straight from the path without a join.
New FamilyTree.svelte: add/edit/delete a person, upload/replace/remove
their photo (signed URLs, 1hr TTL, refreshed on every load since the
bucket is private), link/unlink relationships, and a recursive generational
tree render — roots are anyone with no recorded parent, spouses shown
inline next to their partner rather than as separate branches.
e2e-family-tree.cjs: 4-person 3-generation tree built end to end against
the live backend — add people, link parent/child + spouse relationships,
upload a real PNG to Supabase Storage and confirm it renders as the
avatar, remove it and confirm it reverts to the initial-letter fallback,
edit a person's notes, delete a relationship, and confirm a second family
under the same account sees none of this tree (isolation, same pattern
already proven for Wassiyah/Waqf). Found two real test-authoring bugs
along the way (not app bugs): a case-insensitive :has-text substring match
on "Spouse" was also matching the relationship-type select's own "is
spouse of" option text, and a person-summary click meant to inspect an
already-expanded card was instead toggling it closed. Both fixed by
selecting on DOM position/structure instead of loose text matching.
9/9 passing.
Full regression sweep: e2e-uat 32/32, e2e-fastpath 16/16, e2e-trust 12/12,
e2e-business 10/10, e2e-digital-vehicle 10/10 (one transient failure on
first run, passed clean on retry — consistent with earlier-observed
flakiness under heavy parallel test load, not a regression),
e2e-property 9/9, e2e-other 4/4, e2e-info 31/31, e2e-per-member 11/11,
e2e-family-tree 9/9 — 174/174 total.
|
||
|
|
5adbad6d53 |
Real SMTP heir notifications — no third-party signup needed
Per explicit direction to use existing VPS/Bitwarden/Gitea infrastructure instead of waiting on a Resend signup. Bitwarden's MCP unlock/list both hung (server-side issue, confirmed via direct CLI retry too — not something to keep retrying), so this used the VPS and Gitea directly. Found real, working infrastructure already in place: a documented but never-deployed falah-ibaas email connector (SMTP wrapper) at /opt/falah-ibaas/connectors/email, backed by a local Postfix relay that Ghost already uses successfully in production on the same VPS (mail__options__host=172.17.0.1:25, no auth needed internally). Built nf-mail-relay: a small HTTP wrapper (Python stdlib, no deps) around that connector, deployed as a Docker Swarm service on the existing Traefik network at https://nfmailrelay.falahos.my, bind-mounting the connector code read-only so it stays in sync with any future updates to it. Shared-secret bearer auth (X-Relay-Secret) — verified a wrong secret gets rejected with 401. notify-heirs Edge Function rewired to call this relay instead of Resend. Two real bugs found and fixed via actual testing, not code review: - The function only took memberId, but a person can belong to multiple families — .maybeSingle() against multiple trigger rows failed closed (correctly, but silently, as "not triggered"). Function and both call sites (db.js notifyHeirs, MutawalliDashboard) now require and pass familyId too, matching the same composite-key fix already applied to the trigger tables themselves. - No CORS/OPTIONS handling: a browser's preflight OPTIONS request has no body, and calling req.json() on it crashed the function before any headers were sent — surfaced in the browser as a generic "Failed to send a request" with no detail. Added an OPTIONS short-circuit and CORS headers on every response path. Verified with a real send to a live inbox through the full chain (browser -> Edge Function -> VPS relay -> Postfix -> SMTP), not just a connectivity check. Also fixed a stale e2e-trust.cjs assertion using the same instant-isVisible()-after-fixed-wait pattern already fixed elsewhere in this session — real app behavior was correct, only the test's timing assumption was wrong. e2e-per-member.cjs's heir-notification check now asserts an actual "Sent" result via the real relay instead of accepting either Sent or a not-configured failure. Full sweep: e2e-uat 32/32 (stable across 3 runs, one earlier run's failure was a one-off network blip under heavy parallel test load), e2e-fastpath 16/16, e2e-trust 12/12 (stable across 3 runs), e2e-business 10/10, e2e-digital-vehicle 10/10, e2e-property 9/9, e2e-other 4/4, e2e-info 31/31, e2e-per-member 11/11 — 165/165 total. |
||
|
|
9eb2ce7ce3 |
Per-member estate model: each family member authors their own Wassiyah/Waqf,
mutawalli executes on any member's trigger, heir email notification Per explicit product direction: "all members of the family can make their own wassiyah or waqif. The mutawali or the trustee agent can access and execute those wassiyah and waqif upon any event triggers. Warith or the heir will be automatically notified via email." Schema: nf_family_members.role now includes 'member' (authors own documents, doesn't manage the family). nf_wassiyah_settings/nf_wassiyah_bequests/ nf_waqf_designations gained author_id — each is now per-author, not per-family. Added recipient_email / beneficiary_email columns for warith notification targets. New nf_member_triggers (composite PK family_id+ member_id) and nf_member_attestors: a per-member death trigger, separate from the legacy family-wide nf_death_triggers (kept for backward compatibility, still exercised by existing suites). RLS: any family member can READ any other member's Wassiyah/Waqf (the mutawalli needs full visibility to execute), but only the document's own author can WRITE to it — not even the owner. Firing a member's trigger requires the caller to have role agent/owner AND not be the member themselves (enforced in the policy's WITH CHECK, not just the UI) — matches "the mutawalli executes, never for themselves." New UI: FamilyManagement gained a role selector (member vs agent) on invites. New MutawalliDashboard.svelte — the trustee's execution surface: pick any family member, see their Wassiyah/Waqf read-only, set up attestors + death cert ref, fire their trigger (blocked for self both by disabled UI and by RLS), then trigger heir email notifications. Edge Function notify-heirs deployed (Deno, uses Resend): reads the triggered member's Wassiyah recipients and Waqf beneficiaries wherever an email was recorded, sends each a notice. Returns a clear 501 rather than failing silently until RESEND_API_KEY is set as a project secret. Three real bugs found via testing against the live backend, not visible from code review alone: - listFamilyMembers() never selected user_id — every member-scoped lookup on the new dashboard was silently keying off undefined. - nf_member_triggers keyed by member_id alone: since a person can belong to multiple families, firing a trigger in one family marked them "triggered" in every other family they belong to. Fixed to composite (family_id, member_id) key. - Classic Svelte 5 $state pitfall: (proxyObject[key] ??= []).push(item) mutates the plain array literal the ??= expression evaluates to, not the proxy-wrapped array Svelte actually tracks — so pushed items were silently invisible to the UI forever. Fixed by building on a plain object and assigning to the $state variable once. Also found and fixed the same design smell in the older WassiyahGenerator/FamilyWaqfDesignator authorId handling: it was snapshotted once via currentUser()?.id at mount instead of read live off the session store, which could silently break writes on a remount that happened before session hydration finished — now reads live and guards refresh() on it being present. CoverageDashboard and DeathTrigger updated to check ANY family member's Waqf corpus for coverage (not just one author's), since coverage is a family-wide view even though authorship is per-member now. e2e-per-member.cjs: new suite covering the full flow — owner invites a member and an agent; member authors a private Wassiyah (invisible to other members, confirming per-author isolation); mutawalli sees it on their dashboard and fires the member's trigger; member cannot fire their own; heir notification call completes with either Sent or a clear "not configured" failure, never hangs. 11/11 passing. Full regression sweep after these changes: e2e-uat 32/32 (stable across 3 consecutive runs), e2e-fastpath 16/16, e2e-trust 12/12, e2e-business 10/10, e2e-digital-vehicle 10/10, e2e-property 9/9, e2e-other 4/4, e2e-info 31/31, e2e-family-agent 12/12 (updated for the new invite-form role selector), e2e-per-member 11/11 — 178/178 total, no regressions. |
||
|
|
b9a98bd97a |
Restore all 8 pre-auth E2E suites with a sign-in prelude; fix bugs they found
New e2e-auth-helper.cjs: shared signInFreshFamily() prelude — signs in as the confirmed test owner account and creates a uniquely-named family per run, so accumulated data from a previous run's assets/hibah/etc. (now persisted in Supabase, not wiped with the browser context like localStorage was) can never bleed into another run's percentage/coverage assertions. All 8 suites (e2e-uat, e2e-fastpath, e2e-trust, e2e-business, e2e-digital-vehicle, e2e-property, e2e-other, e2e-info) now call it in place of the old anonymous page.goto(BASE). Restoring them surfaced two real product bugs, not just test staleness: 1. WassiyahGenerator.svelte was never migrated to Supabase in the earlier backend work — it still called the old local storage.js load()/save() for assets, bequests, and witnesses, so the one-third meter silently read an empty local cache and always showed 0. Migrated to family-scoped Supabase tables (new nf_wassiyah_bequests, nf_wassiyah_settings, with member-scoped RLS) matching the pattern used for Hibah/Nominations/etc. 2. storage.js's exportAll() did an unguarded JSON.parse on every "nf."-prefixed localStorage key, but family.js stores activeFamilyId as a raw string (not JSON-encoded) — one malformed parse threw and silently aborted the whole export before the file download fired. Made exportAll defensive: falls back to the raw string on a parse failure instead of throwing. The remaining test failures were async-timing gaps inherent to the move from synchronous localStorage reads to async Supabase fetches: several assertions checked <select> option counts or newly-created rows immediately after a fixed short wait, before the async load/refresh had actually landed. Fixed by replacing blind isVisible()/fixed-timeout checks with proper waitFor()/polling in the test helpers (selectByText, corpus-select population, row-creation checks) — not a product bug, but worth fixing since the old timing assumptions no longer hold now that data is live and shared instead of instant and local. Results: e2e-uat 32/32, e2e-fastpath 16/16, e2e-trust 12/12, e2e-business 10/10, e2e-digital-vehicle 10/10, e2e-property 9/9, e2e-other 4/4, e2e-info 31/31 — 124/124. Re-verified e2e-family-agent (12/12) and e2e-smoke-authed (24/24) still pass after the WassiyahGenerator migration. 160/160 total across all ten suites. |
||
|
|
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. |
||
|
|
4250f8da14 |
Fix "Other" asset type: was suggesting a channel that doesn't exist
nonprobate.js's suggestedChannel() had no case for the "Other" type (or
anything else that fell through every specific check) — it defaulted to
{ channel: 'nomination', label: 'EPF / Takaful nomination' }. Two bugs:
(1) recommending a retirement/insurance nomination for a generic asset
that could be anything (a collectible, a domain name, an heirloom) makes
no sense, and (2) 'nomination' isn't a real value in NominationRegistry's
CHANNEL_TYPES (epf/takaful/bank-mandate/trust/business-continuity/
digital-custody) — the suggestion pointed at a channel that doesn't exist.
Default now points to Hibah — the safest general-purpose fast path since
it needs no institution or legal structure, with a note to consider a
trust setup instead if the asset is high-value or income-generating.
e2e-other.cjs: new suite confirming the fixed suggestion, the corrected
in-app reasoning text, and that following it (Hibah) actually reaches
100% coverage. 4/4 passing. Re-verified all seven prior suites (32/32,
16/16, 12/12, 10/10, 10/10, 9/9, 31/31) — 136/136 total, no regressions.
|
||
|
|
10289e2d92 |
Verify property/land coverage across all three applicable fast-path channels
No code changes needed — land/property was already correctly wired through Hibah (offer/acceptance/possession now), Waqf (dedicated corpus via Family Waqf Designator), and Trust (via Nomination Registry, added earlier this session). This adds explicit isolated verification since prior tests only exercised one channel per property asset at a time. e2e-property.cjs: three separate property assets, each covered through a different channel, confirming Coverage Dashboard correctly attributes each (Hibah/Waqf/Trust) and reaches 100%, and Death Trigger generates a distinct execution packet for all three. 9/9 passing. Re-verified e2e-uat.cjs (32/32), e2e-fastpath.cjs (16/16), e2e-trust.cjs (12/12), e2e-business.cjs (10/10), e2e-digital-vehicle.cjs (10/10), e2e-info.cjs (31/31) — 132/132 total, no regressions. |
||
|
|
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. |
||
|
|
3badc5caaa | Fix E2E test bugs (regex selectOption, tab context) — full suite now 32/32 green | ||
|
|
eb1ce59159 |
Wire language switcher into Settings; add E2E UAT suite
- App.svelte: language toggle (EN/BM) wired to existing i18n.js store, header tagline reflects selection. Was previously dead code with no UI control (found by e2e-uat.cjs during full-flow UAT). - e2e-uat.cjs: Playwright-driven E2E UAT against the live deployment — real clicks/typing through all 7 tabs, faraid textbook-case verification, heir-exclusion blocking, marad al-mawt guard, 1/3 cap override flow, claim issuance/transfer, export/delete-all guards, PWA and console-error checks. |
||
|
|
6690696f7f |
Initial build: Horizon 1 Prevention Suite + Horizon 2 Unlock demo
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. |