From 194aacf68ce6696c548098ee0ba67ad048ffeeee Mon Sep 17 00:00:00 2001 From: Stephen Adamson Date: Mon, 22 Jun 2026 17:06:31 +0100 Subject: [PATCH] feat(frontend): add test deps, VAT types, and business info store Add jsdom and vitest dev dependencies. Add total_vat_amount and total_net_amount to PaymentSummary type. Create shared businessInfo store for caching public business settings. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- frontend/package.json | 4 ++- .../src/lib/stores/businessInfo.svelte.ts | 36 +++++++++++++++++++ frontend/src/lib/types/index.ts | 2 ++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 frontend/src/lib/stores/businessInfo.svelte.ts diff --git a/frontend/package.json b/frontend/package.json index a8d92d3..35271f0 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -36,6 +36,7 @@ "eslint-plugin-svelte": "^3.0.0", "formsnap": "^2.0.1", "globals": "^17.3.0", + "jsdom": "^29.1.1", "mode-watcher": "^1.1.0", "prettier": "^3.8.1", "prettier-plugin-svelte": "^3.5.0", @@ -54,7 +55,8 @@ "tw-animate-css": "^1.4.0", "typescript": "^5.9.3", "typescript-eslint": "^8.20.0", - "vite": "^7.0.4" + "vite": "^7.0.4", + "vitest": "^4.1.9" }, "dependencies": { "@discourse/jxl": "^1.3.0", diff --git a/frontend/src/lib/stores/businessInfo.svelte.ts b/frontend/src/lib/stores/businessInfo.svelte.ts new file mode 100644 index 0000000..a18d175 --- /dev/null +++ b/frontend/src/lib/stores/businessInfo.svelte.ts @@ -0,0 +1,36 @@ +// src/lib/stores/businessInfo.svelte.ts +import type { BusinessSettings } from '$lib/types/settings'; + +let businessInfo = $state(null); +let loadingPromise: Promise | null = null; + +/** + * Fetches /api/business-info exactly once and caches the result. + * Subsequent calls return the cached promise or resolved value. + * Errors are handled gracefully — returns null. + */ +export async function ensureBusinessInfo(): Promise { + if (businessInfo !== null) return businessInfo; + if (loadingPromise) return loadingPromise; + + loadingPromise = fetch('/api/business-info') + .then((r) => (r.ok ? r.json() : null)) + .then((data) => { + businessInfo = data as BusinessSettings | null; + return businessInfo; + }) + .catch(() => { + businessInfo = null; + return null; + }); + + return loadingPromise; +} + +/** + * Returns the current cached business info (reactive via $state). + * Use in $derived or $effect to track changes. + */ +export function getBusinessInfo(): BusinessSettings | null { + return businessInfo; +} diff --git a/frontend/src/lib/types/index.ts b/frontend/src/lib/types/index.ts index 938c96a..1f43d8b 100644 --- a/frontend/src/lib/types/index.ts +++ b/frontend/src/lib/types/index.ts @@ -48,6 +48,8 @@ export interface PaymentSummary { paid_amount: number; refunded_amount: number; remaining_amount: number; + total_vat_amount: number; + total_net_amount: number; payments: Payment[]; refunds: Refund[]; }