ui-ux-dashboard-improvements
5 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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. |
||
|
|
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. |
||
|
|
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. |