diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 1baaa58d..28d7ed4a 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -32,6 +32,7 @@ {"id":"zakapp-aer","title":"Release v0.9.2 Preparation","description":"Epic for release v0.9.2 including security cleanup, test fixes, and documentation updates.","status":"open","priority":0,"issue_type":"epic","owner":"agent@zakapp.dev","created_at":"2026-02-07T12:59:25.245154194Z","created_by":"ZakApp Agent","updated_at":"2026-02-07T12:59:25.245154194Z"} {"id":"zakapp-aer.1","title":"Complete Test Suite Stabilization \u0026 CI Quality Gates","description":"## Objective\nEnsure all tests are passing and establish quality gates to prevent regression.\n\n## Scope\n1. **Server Integration Tests** (6 test suites)\n - statusTransitions.test.ts\n - liveTracking.test.ts\n - hawlDetection.test.ts\n - hawlInterruption.test.ts\n - invalidOperations.test.ts\n - finalization.test.ts\n\n2. **Unit Tests** (all server/src)\n3. **Contract Tests** (if applicable)\n4. **E2E Tests** (if applicable)\n\n## Tasks\n\n### Phase 1: Fix API Contract Mismatches\n- [ ] Investigate POST /api/nisab-year-records validation requirements\n- [ ] Identify all required fields and validation rules\n- [ ] Update tests OR fix API to match expected behavior\n- [ ] Document API contract in OpenAPI/Swagger\n\n### Phase 2: Run Full Test Suite\n- [ ] Run all server tests: `npm run test:server`\n- [ ] Document all failing tests with error messages\n- [ ] Categorize failures by type (auth, validation, data model, etc.)\n- [ ] Create subtasks for each category of failures\n\n### Phase 3: Stabilization\n- [ ] Fix all auth-related test failures\n- [ ] Fix all validation-related test failures\n- [ ] Fix all database constraint failures\n- [ ] Fix all business logic failures\n- [ ] Ensure 100% test pass rate\n\n### Phase 4: Quality Gates\n- [ ] Add pre-commit hook to run affected tests\n- [ ] Update CI/CD to fail on test failures\n- [ ] Add test coverage reporting\n- [ ] Set minimum coverage threshold (recommend 70%)\n- [ ] Add integration test smoke tests to PR checks\n\n### Phase 5: Documentation\n- [ ] Document test setup requirements\n- [ ] Document how to run tests locally\n- [ ] Create testing guidelines for contributors\n- [ ] Document known limitations/assumptions\n\n## Acceptance Criteria\n- [ ] All integration tests pass (0 failures)\n- [ ] All unit tests pass (0 failures)\n- [ ] CI pipeline includes test gates\n- [ ] Test documentation is up-to-date\n- [ ] No test is skipped without justification\n\n## Success Metrics\n- Test pass rate: 100%\n- Build time: \u003c 5 minutes\n- Test coverage: \u003e 70%\n- Zero flaky tests\n\n## Notes\nThis is critical for v0.9.2 release stability.","status":"in_progress","priority":0,"issue_type":"task","owner":"agent@zakapp.dev","created_at":"2026-02-07T14:14:02.610630175Z","created_by":"ZakApp Agent","updated_at":"2026-02-08T02:56:30.097203189Z","dependencies":[{"issue_id":"zakapp-aer.1","depends_on_id":"zakapp-aer","type":"parent-child","created_at":"2026-02-07T14:14:02.612833789Z","created_by":"ZakApp Agent"}]} {"id":"zakapp-b9p","title":"Enforce feature branch workflow in AGENTS.md","description":"Update AGENTS.md to mandate feature branches and Pull Requests instead of direct pushes to main. Define naming convention feature/\u003cissue-id\u003e-\u003cslug\u003e.","status":"closed","priority":1,"issue_type":"task","owner":"agent@zakapp.dev","created_at":"2026-02-07T12:44:50.123953172Z","created_by":"ZakApp Agent","updated_at":"2026-02-07T12:45:19.648501154Z","closed_at":"2026-02-07T12:45:19.648501154Z","close_reason":"Closed"} +{"id":"zakapp-biy","title":"feat: Fix liability deduction in Zakat calculations","description":"Liabilities are tracked in the UI but are never deducted from Zakat calculations. The server hardcodes totalLiabilities: 0 in server/src/routes/zakat.ts, producing incorrect Zakat amounts.\n\n**Changes needed:**\n- Replace 5 hardcoded liability values with actual queries to wealthAggregationService.calculateTotalLiabilities()\n- Update netWorth calculation to subtract liabilities\n- Wire up liabilitiesIncluded in calculation responses\n\n**Files:**\n- server/src/routes/zakat.ts (lines 166, 175, 217-218, 227)\n- server/src/services/wealthAggregationService.ts (already has calculateTotalLiabilities method)\n\n**Risk:** Low - uses existing service, can start with simple 'sum all active liabilities' approach\n\n**Effort:** ~3 hours","status":"in_progress","priority":1,"issue_type":"task","owner":"agent@zakapp.dev","created_at":"2026-02-17T13:45:05.69512055Z","created_by":"ZakApp Agent","updated_at":"2026-02-17T13:45:31.292961945Z"} {"id":"zakapp-bm7","title":"Auto-run database migrations on first startup","description":"Database migrations must run automatically when containers start for the first time. Currently users get 'table does not exist' errors and must manually run migrations. Add init container or startup script to handle this automatically.","notes":"Auto-migrations implemented via migrations service in docker-compose.easy.yml:\n- Runs automatically on container startup\n- Executes: npx prisma migrate deploy\n- Gracefully handles already-migrated databases\n- No manual intervention required","status":"closed","priority":1,"issue_type":"task","owner":"agent@zakapp.dev","created_at":"2026-02-06T17:06:16.502975235Z","created_by":"ZakApp Agent","updated_at":"2026-02-06T17:32:22.769381671Z","closed_at":"2026-02-06T17:32:22.769387673Z"} {"id":"zakapp-cqz","title":"Implement single-command setup script with zero configuration","description":"Create an enhanced deploy.sh script that: 1) Detects user's environment (localhost vs IP vs domain), 2) Auto-generates all secrets, 3) Auto-configures .env, 4) Handles port conflicts, 5) Sets up HTTPS if domain provided, 6) Runs migrations, 7) Provides clear next steps. Goal: ./deploy.sh \u0026\u0026 done.","notes":"Created deploy-easy.sh with:\n- Interactive setup wizard\n- Auto-detection of IP address\n- Port conflict detection and resolution\n- Automatic secret generation\n- Environment configuration\n- Clear next steps for user\n\nUsers can now deploy with: ./deploy-easy.sh","status":"closed","priority":1,"issue_type":"task","owner":"agent@zakapp.dev","created_at":"2026-02-06T17:06:23.828853483Z","created_by":"ZakApp Agent","updated_at":"2026-02-06T17:32:22.207168406Z","closed_at":"2026-02-06T17:32:22.207174628Z"} {"id":"zakapp-cuu","title":"Create interactive setup wizard (CLI)","description":"Build an interactive CLI wizard (using inquirer.js or similar) that guides users through setup: asks for domain/IP preference, detects conflicts, suggests fixes, validates configuration, and provides clear status updates. More user-friendly than editing .env files.","status":"closed","priority":2,"issue_type":"task","owner":"agent@zakapp.dev","created_at":"2026-02-06T17:06:29.374167914Z","created_by":"ZakApp Agent","updated_at":"2026-02-07T03:17:48.561427634Z","closed_at":"2026-02-07T03:17:48.561427634Z","close_reason":"Closed"} @@ -40,6 +41,7 @@ {"id":"zakapp-dul","title":"Add health checks and diagnostics dashboard","description":"Create a /status or /diagnostics endpoint that checks: database connectivity, migrations status, crypto API availability, CORS configuration, SSL certificate validity. Provide actionable error messages when something is misconfigured. Help users self-diagnose issues.","status":"closed","priority":2,"issue_type":"task","owner":"agent@zakapp.dev","created_at":"2026-02-06T17:06:31.323159084Z","created_by":"ZakApp Agent","updated_at":"2026-02-07T02:49:45.985698498Z","closed_at":"2026-02-07T02:49:45.985698498Z","close_reason":"Closed"} {"id":"zakapp-dvo","title":"Auto-run database migrations on first deploy","description":"Database migrations are not automatically run when deploying ZakApp via Docker. Users must manually run 'docker compose exec backend npx prisma migrate deploy' before they can create accounts. This causes registration to fail with 'table main.users does not exist' error. Need to add automatic migration on container startup or document this requirement clearly.","status":"closed","priority":2,"issue_type":"bug","owner":"agent@zakapp.dev","created_at":"2026-02-05T22:33:49.761020405Z","created_by":"ZakApp Agent","updated_at":"2026-02-07T12:48:24.857455354Z","closed_at":"2026-02-07T12:48:24.857455354Z","close_reason":"Closed"} {"id":"zakapp-gan","title":"Auto-detect and configure ports to avoid conflicts","description":"Currently port 3000 often conflicts with other services. Implement automatic port detection that finds available ports and configures the app automatically. User should not need to manually edit .env for port conflicts.","notes":"Port auto-detection implemented in deploy-easy.sh:\n- Checks if ports 3000/3443 are in use\n- Automatically finds next available ports\n- Updates .env configuration automatically\n- Informs user of port changes","status":"closed","priority":1,"issue_type":"task","owner":"agent@zakapp.dev","created_at":"2026-02-06T17:06:15.347495457Z","created_by":"ZakApp Agent","updated_at":"2026-02-06T17:32:23.389052688Z","closed_at":"2026-02-06T17:32:23.389058448Z"} +{"id":"zakapp-i6i","title":"feat: Add Dashboard action cards with Hawl countdown timer","description":"Surface the existing useBestAction hook as prominent visual cards on Dashboard, and add visible Hawl countdown timer using existing HawlProgressIndicator component.\n\n**Changes needed:**\n- Create NextActionCard component with variant styling (urgent/warning/setup/maintenance)\n- Integrate action cards into Dashboard after OnboardingGuide\n- Add HawlProgressIndicator prominently near top of Dashboard\n- Style cards with appropriate border colors and icons\n\n**Files:**\n- client/src/pages/Dashboard.tsx\n- client/src/components/dashboard/NextActionCard.tsx (NEW)\n- client/src/components/HawlProgressIndicator.tsx (already exists, integrate it)\n- client/src/hooks/useBestAction.ts (may need minor tweaks)\n\n**Existing components:**\n- useBestAction hook returns complete BestAction type with type, title, description, label, href, variant\n- HawlProgressIndicator is 245 lines, fully functional with countdown, progress bar, dates\n- Button component exists for CTAs\n\n**Risk:** Very Low - mostly UI composition of existing components\n\n**Effort:** ~6 hours","status":"open","priority":2,"issue_type":"task","owner":"agent@zakapp.dev","created_at":"2026-02-17T13:45:23.740738226Z","created_by":"ZakApp Agent","updated_at":"2026-02-17T13:45:23.740738226Z"} {"id":"zakapp-ikp","title":"QA \u0026 Security Audit: Zero-Knowledge Encryption v0.10.0","description":"Comprehensive QA and security review of PRs #276-279 before production deployment. Includes integration testing, security audit, performance benchmarking, and deployment readiness assessment.","notes":"## QA Audit Complete - Feb 08, 2026\n\n**Status:** ⚠️ CONDITIONAL APPROVAL\n\n**Summary:**\n- ✅ Security audit PASSED - cryptographic implementation sound\n- ❌ Test suite FAILING - 138 of 871 tests failing (80.2% pass rate)\n- ⚠️ E2E testing INCOMPLETE - migration wizard not validated\n- ⚠️ Performance UNKNOWN - benchmarks not collected\n\n**Deliverables Created:**\n1. docs/SECURITY_AUDIT_V0.10.0.md - Comprehensive security analysis\n2. docs/QA_SUMMARY_V0.10.0.md - Full QA report with recommendations\n3. docs/ZK_EXECUTIVE_BRIEFING.md - Leadership briefing\n\n**Blocking Issues Created:**\n- zakapp-z2w (P0): Fix test suite failures\n- zakapp-0vy (P1): E2E migration wizard testing\n- zakapp-lo9 (P1): Performance benchmarking\n\n**Recommendation:** \nKeep PRs #276-279 OPEN. Fix test suite first (1-2 days), then complete E2E validation and benchmarking. Final approval estimated Feb 12, 2026.\n\n**Next Steps:**\n1. Engineering team fixes auth middleware test failures\n2. QA team prepares E2E test environment\n3. DevOps team prepares staging environment\n4. Re-audit after tests pass","status":"open","priority":0,"issue_type":"task","owner":"agent@zakapp.dev","created_at":"2026-02-08T15:56:30.700995627Z","created_by":"ZakApp Agent","updated_at":"2026-02-08T16:05:12.723376592Z"} {"id":"zakapp-jbm","title":"Security Assurance","description":"As a security-conscious user, I want assurance that prebuilt images are safe, so that I can trust the deployment.\nAcceptance Criteria:\n- Images hosted on GitHub Container Registry (ghcr.io)\n- Images signed with cosign or similar\n- SBOM (Software Bill of Materials) available\n- Images built from verified source commits\nTechnical Details:\n- Set up GitHub Container Registry with proper permissions\n- Integrate cosign for image signing in CI/CD pipeline\n- Generate SBOMs using tools like `docker sbom` or `syft`\n- Implement vulnerability scanning with Trivy or similar before push\n- Use GitHub Actions to build from tagged commits only\n- Provide verification commands in documentation (e.g., `cosign verify` instructions)\nDependencies: GHCR access and CI/CD setup","status":"closed","priority":2,"issue_type":"task","created_at":"2026-02-05T21:54:25.316428056Z","created_by":"chuwi_agent","updated_at":"2026-02-05T21:56:24.630080186Z","closed_at":"2026-02-05T21:56:24.630080186Z","close_reason":"Closed"} {"id":"zakapp-jis","title":"Production-Ready Event Architecture for Hawl Tracking","description":"**Objective:**\nUpgrade from simple synchronous event triggers to a robust, production-ready event-driven architecture.\n\n**Current Implementation (After zakapp-0q1):**\n- ✅ Synchronous triggers in AssetService\n- ✅ Immediate wealth recalculation\n- ✅ Works for most use cases\n- ⚠️ Potential issues: blocking, no retry, no audit trail\n\n**Production Requirements:**\n\n**1. Asynchronous Event Processing**\n- Asset operations should not block on Hawl tracking\n- Use event queue (Bull/BullMQ) for background processing\n- Retry failed calculations with exponential backoff\n\n**2. Event Sourcing \u0026 Audit Trail**\n- Record all wealth change events\n- Full audit log of what triggered each Hawl state change\n- Ability to replay events for debugging\n\n**3. Idempotency \u0026 Exactly-Once Processing**\n- Handle duplicate events gracefully\n- Ensure each asset change triggers exactly one recalculation\n- Use event IDs and deduplication\n\n**4. Performance \u0026 Scalability**\n- Handle 1000+ concurrent users\n- Queue-based load leveling\n- Rate limiting on expensive operations\n\n**5. Monitoring \u0026 Observability**\n- Metrics: Event processing latency, queue depth, error rates\n- Alerts: Failed calculations, stuck events, queue backlog\n- Distributed tracing for debugging\n\n**6. Database Triggers (PostgreSQL)**\n- Migrate from SQLite to PostgreSQL for production\n- Use native DB triggers for guaranteed event capture\n- LISTEN/NOTIFY for real-time events\n\n**Components:**\n\n**A. Event Queue Service**\n```typescript\nclass EventQueueService {\n async publishAssetChanged(userId: string, assetId: string, action: 'create' | 'update' | 'delete'): Promise\u003cvoid\u003e\n async subscribeToAssetEvents(handler: EventHandler): Promise\u003cvoid\u003e\n}\n```\n\n**B. Event Store**\n```typescript\ninterface AssetChangeEvent {\n id: string;\n userId: string;\n assetId: string;\n action: 'create' | 'update' | 'delete';\n timestamp: Date;\n metadata: Record\u003cstring, any\u003e;\n processed: boolean;\n}\n```\n\n**C. Circuit Breaker**\nIf Hawl tracking service is down, stop processing events temporarily\n\n**D. Dead Letter Queue**\nFailed events go to DLQ for manual investigation\n\n**Technology Stack Options:**\n- **Queue**: Bull/BullMQ (Redis-backed) or AWS SQS\n- **Database**: PostgreSQL with native triggers\n- **Monitoring**: Prometheus + Grafana\n- **Tracing**: OpenTelemetry\n\n**Migration Path:**\n1. Phase 1: Keep synchronous triggers (zakapp-0q1)\n2. Phase 2: Add async queue alongside sync (dual-write)\n3. Phase 3: Monitor both systems in parallel\n4. Phase 4: Fully migrate to async, remove sync triggers\n5. Phase 5: Add advanced features (event sourcing, etc.)\n\n**Success Criteria:**\n- ✅ Zero data loss during async migration\n- ✅ 99.9% event processing success rate\n- ✅ \u003c5s p99 processing latency\n- ✅ Graceful degradation when services fail\n\n**Timeline:**\n- Not urgent for v0.9.2\n- Plan for v1.0 or later\n- Prerequisite: PostgreSQL migration\n\n**Priority:**\n- P3 (future enhancement)\n- Not blocking current release","status":"open","priority":3,"issue_type":"epic","owner":"agent@zakapp.dev","created_at":"2026-02-07T14:38:15.211046448Z","created_by":"ZakApp Agent","updated_at":"2026-02-07T14:38:15.211046448Z"} @@ -52,6 +54,7 @@ {"id":"zakapp-o95","title":"Resolve merge conflicts in feature/prebuilt-docker-images","description":"Resolve merge conflicts in README.md, docker-compose.prod.yml, and docker-compose.yml on feature/prebuilt-docker-images branch.","status":"closed","priority":1,"issue_type":"task","owner":"agent@zakapp.dev","created_at":"2026-02-06T22:02:31.190750175Z","created_by":"ZakApp Agent","updated_at":"2026-02-06T22:03:51.382804555Z","closed_at":"2026-02-06T22:03:51.382804555Z","close_reason":"Closed"} {"id":"zakapp-qz0","title":"Advanced Retirement Zakat Logic (Fiqh Compliance)","description":"Implement specific calculation methodologies for retirement assets - 'Collectible Value' vs 'Invested Growth' based on scholarly analysis.","status":"in_progress","priority":1,"issue_type":"feature","owner":"agent@zakapp.dev","created_at":"2026-02-13T15:18:58.778767861Z","created_by":"ZakApp Agent","updated_at":"2026-02-13T15:19:06.271771896Z"} {"id":"zakapp-tba","title":"CLEANUP: Resolve 100+ TODO/FIXME comments indicating incomplete features","description":"Codebase contains 100+ TODO/FIXME comments indicating rushed development and incomplete core functionality.\n\nCritical TODOs to resolve:\n- AnnualSummaryService missing payment calculations\n- Zakat routes with stubbed liability handling\n- Missing unique recipient counting in summaries\n- Incomplete methodology handling\n- Push notification service database schema\n- Missing export functionality\n\nApproach:\n1. Prioritize business-critical TODOs\n2. Implement missing functionality or remove dead code\n3. Add proper error handling for incomplete features\n4. Update documentation\n\nVerification: TODO/FIXME count reduced to \u003c20, all critical features implemented.","status":"open","priority":2,"issue_type":"task","owner":"agent@zakapp.dev","created_at":"2026-02-08T00:55:28.830212251Z","created_by":"ZakApp Agent","updated_at":"2026-02-08T00:55:28.830212251Z","labels":["cleanup","maintainability"]} +{"id":"zakapp-umx","title":"feat: Add multi-currency support with user preference","description":"Add ability for users to select their preferred base currency. The currency infrastructure already exists (CurrencyService, metal prices by currency, exchange rate conversion) but users cannot select their preferred currency.\n\n**Changes needed:**\n- Add currency selector to Settings Profile page\n- Create useCurrency hook for formatting\n- Create reusable CurrencyDisplay component\n- Update Dashboard, Assets, Analytics to use user's currency\n- Ensure CurrencyService caching is production-ready\n\n**Files:**\n- client/src/pages/settings/components/ProfileForm.tsx\n- client/src/hooks/useCurrency.ts (NEW)\n- client/src/components/common/CurrencyDisplay.tsx (NEW)\n- client/src/pages/Dashboard.tsx\n- client/src/pages/Assets*.tsx\n- client/src/pages/AnalyticsPage.tsx\n- server/src/services/currencyService.ts\n\n**Existing infrastructure:**\n- CurrencyService already fetches and caches exchange rates\n- ZakatEngine converts assets to USD\n- NisabService fetches metal prices in multiple currencies\n- Asset.currency and Payment.currency fields exist in schema\n\n**Risk:** Low-Medium - exchange rate API reliability (has caching fallback)\n\n**Effort:** ~8-10 hours","status":"open","priority":2,"issue_type":"task","owner":"agent@zakapp.dev","created_at":"2026-02-17T13:45:15.369059847Z","created_by":"ZakApp Agent","updated_at":"2026-02-17T13:45:15.369059847Z"} {"id":"zakapp-vz1","title":"Finalize deployment script cleanup","status":"closed","priority":2,"issue_type":"task","owner":"agent@zakapp.dev","created_at":"2026-02-06T20:33:18.776788604Z","created_by":"ZakApp Agent","updated_at":"2026-02-06T20:33:23.061741955Z","closed_at":"2026-02-06T20:33:23.061741955Z","close_reason":"Closed"} {"id":"zakapp-wlu","title":"SECURITY: Remove exposed production secrets from git history","description":"Multiple .env.backup.* files containing live JWT secrets, encryption keys, and database credentials are committed to the repository despite being in .gitignore. This represents an immediate security breach requiring emergency remediation.\n\nImmediate actions needed:\n1. Remove .env.backup.* files from git tracking\n2. Rotate all exposed secrets in production\n3. Clean git history if secrets were exposed\n4. Update .gitignore to prevent future occurrences\n\nVerification: Run 'git log --all --full-history -- .env*' and confirm no secret exposure.","status":"closed","priority":0,"issue_type":"task","owner":"agent@zakapp.dev","created_at":"2026-02-08T00:55:17.971892975Z","created_by":"ZakApp Agent","updated_at":"2026-02-09T13:51:02.209817035Z","closed_at":"2026-02-09T13:51:02.209817035Z","close_reason":"Closed","labels":["critical","emergency","security"]} {"id":"zakapp-wqy","title":"Fix createdAt Date serialization in auth response","description":"createdAt Date object not appearing in JSON response. Need to force string serialization in AuthController or ApiResponseBuilder.","status":"open","priority":0,"issue_type":"task","owner":"agent@zakapp.dev","created_at":"2026-02-10T03:31:31.991910804Z","created_by":"ZakApp Agent","updated_at":"2026-02-10T03:31:31.991910804Z"} diff --git a/server/src/routes/zakat.ts b/server/src/routes/zakat.ts index 6bda11cc..076e3435 100644 --- a/server/src/routes/zakat.ts +++ b/server/src/routes/zakat.ts @@ -33,6 +33,20 @@ import * as jwt from 'jsonwebtoken'; import { prisma } from '../utils/prisma'; import { getJwtSecret } from '../config/security'; +async function getUserActiveLiabilities(userId: string) { + const liabilities = await prisma.liability.findMany({ + where: { userId, isActive: true }, + select: { type: true, amount: true, name: true }, + }); + + const total = liabilities.reduce((sum, l) => sum + l.amount, 0); + + return { + total, + liabilities: liabilities.map(l => ({ type: l.type, amount: l.amount, name: l.name })), + }; +} + const router = express.Router(); /** @@ -149,13 +163,15 @@ router.post('/calculate', customNisab }; - // Perform calculation + const liabilityData = await getUserActiveLiabilities(req.userId!); + const result = await zakatEngine.calculateZakat({ ...calcRequest, userId: req.userId }); - // Save calculation to database + const netWorth = result.result.totals.totalAssets - liabilityData.total; + const savedCalculation = await prisma.zakatCalculation.create({ data: { userId: req.userId!, @@ -163,8 +179,8 @@ router.post('/calculate', methodology: result.methodology.id, calendarType: result.result.calendarType, totalAssets: result.result.totals.totalAssets, - totalLiabilities: 0, // TODO: Implement liabilities - netWorth: result.result.totals.totalAssets, + totalLiabilities: liabilityData.total, + netWorth, nisabThreshold: result.result.nisab.effectiveNisab, nisabSource: result.result.nisab.nisabBasis, isZakatObligatory: result.result.meetsNisab, @@ -172,7 +188,7 @@ router.post('/calculate', zakatRate: result.methodology.zakatRate, breakdown: JSON.stringify(result.breakdown), assetsIncluded: JSON.stringify(result.result.assets), - liabilitiesIncluded: JSON.stringify([]), // TODO: Implement liabilities + liabilitiesIncluded: JSON.stringify(liabilityData.liabilities), regionalAdjustments: null } }); @@ -186,7 +202,7 @@ router.post('/calculate', await calculationHistoryService.saveCalculation(req.userId!, { methodology: result.methodology.id, calendarType: calcRequest.calendarType, - totalWealth: result.result.totals.totalAssets, + totalWealth: netWorth, nisabThreshold: result.result.nisab.effectiveNisab, zakatDue: result.result.totals.totalZakatDue, zakatRate: result.methodology.zakatRate, @@ -195,7 +211,8 @@ router.post('/calculate', metadata: { calculationId: savedCalculation.id, meetsNisab: result.result.meetsNisab, - nisabBasis: result.result.nisab.nisabBasis + nisabBasis: result.result.nisab.nisabBasis, + totalLiabilities: liabilityData.total }, zakatYearStart: zakatYear.startDate, zakatYearEnd: zakatYear.endDate @@ -214,17 +231,17 @@ router.post('/calculate', calendarType: result.result.calendarType, summary: { totalAssets: result.result.totals.totalAssets, - totalLiabilities: 0, // TODO: Implement liabilities - netWorth: result.result.totals.totalAssets, // TODO: Subtract liabilities + totalLiabilities: liabilityData.total, + netWorth, nisabThreshold: result.result.nisab.effectiveNisab, nisabSource: result.result.nisab.nisabBasis, isZakatObligatory: result.result.meetsNisab, - zakatAmount: result.result.totals.totalZakatDue, - zakatRate: result.methodology.zakatRate + zirconYearAmount: result.result.totals.totalZakatDue, + zirconYearRate: result.methodology.zakatRate }, breakdown: { assetsByCategory: groupAssetsByCategory(result.result.assets), - liabilities: [], // TODO: Implement liabilities + liabilities: liabilityData.liabilities, methodologyRules: { nisabCalculation: result.result.nisab, assetTreatment: result.methodology.businessAssetTreatment,