Commit graph

30 commits

Author SHA1 Message Date
d683045912 removed beads 2026-02-07 17:03:42 +01:00
8096a19081 Audit v4: VAT calc, SAF-T compliance, security hardening, frontend quality
Backend (17 files):
- VAT: REP 25% deductibility (§42), EU reverse charge double-entry (IEUV/IEUY/IVY),
  IVY rate 0%→25%, VatReport Box C/D populated, Basis1 from real revenue
- SAF-T: correct OECD namespace, closing balance net calc, zero-amount fallback,
  credit note auto-numbering (§52)
- Security: BankingController CSRF state token + company auth check,
  attachment canonical path traversal check, discount 0-100% validation,
  deactivated product/customer update guard
- Quality: redact bank API logs, remove dead code (VatCalcService,
  PaymentMatchingService), CompanyAggregate IEmit interfaces, fix URL encoding

Frontend (15 files):
- Fix double "kr." in AmountText and Dashboard Statistic components
- Fix UserSettings Switch defaultChecked desync with Form state
- Remove dual useCompany/useCompanyStore pattern (Dashboard, Moms, Bank)
- Correct SKAT VAT deadline calculation per period type
- Add half-yearly/yearly VAT period options
- Guard console.error with import.meta.env.DEV
- Use shared formatDate in BankConnectionsTab
- Remove dead NONE vatCode check, purge 7 legacy VAT codes from type union
- Migrate S25→U25, K25→I25 across all pages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 01:38:52 +01:00
a7d76df3a7 Close audit v3 issues (books-9te, books-8n5, books-i6l)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 01:15:57 +01:00
1a0922b778 Audit v3: VAT alignment, security, encoding, UX, compliance
VAT System Alignment (LEGAL - Critical):
- Align frontend VAT codes with backend (S25→U25, K25→I25, etc.)
- Add missing codes: UEU, IVV, IVY, REP
- Fix output VAT account 5710→5611 to match StandardDanishAccounts
- Invoice posting now checks fiscal year status before allowing send
- Disallow custom invoice number override (always use auto-numbering)

Security:
- Fix open redirect in AuthController (validate returnUrl is local)
- Store seller CVR/name/address on invoice events (Momsloven §52)

Backend Compliance:
- Add description validation at posting (Bogføringsloven §7)
- SAF-T: add DefaultCurrencyCode, TaxAccountingBasis to header
- SAF-T: add TaxTable to MasterFiles with all VAT codes
- SAF-T: always write balance elements even when zero
- Add financial income account 9100 Renteindtægter

Danish Encoding (~25 fixes):
- Kassekladde: Bogført, Bogføring, Vælg, være, på, Tilføj, Differens
- AttachmentUpload: træk, Understøtter, påkrævet, Bogføringsloven
- keyboardShortcuts: Bogfør, Bogføring display name
- ShortcutsHelpModal: åbne
- DataTable: Genindlæs
- documentProcessing: være
- CloseFiscalYearWizard: årsafslutning

Bugs Fixed:
- Non-null assertion crashes in Kunder.tsx and Produkter.tsx (company!.id)
- StatusBadge typo "Succces"→"Succes"
- HTML entity &oslash; in Kassekladde→proper UTF-8
- AmountText showSign prop was dead code (true || showSign)

UX Improvements:
- Add PageHeader to Bankafstemning and Dashboard loading/empty states
- Responsive columns in Bankafstemning (xs/sm/lg breakpoints)
- Disable misleading buttons: Settings preferences, Kontooversigt edit,
  Loenforstaelse export — with tooltips explaining status
- Add DemoDataDisclaimer to UserSettings
- Fix breadcrumb self-references on 3 pages
- Replace Dashboard fake progress bar with honest message
- Standardize date format DD-MM-YYYY in Bankafstemning and Ordrer
- Replace Input type="number" with InputNumber in Ordrer

Quality:
- Remove 8 redundant console.error statements
- Fix Kreditnotaer breadcrumb "Salg"→"Fakturering" for consistency

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 01:15:45 +01:00
cd5333f07f Close audit v2 issues (books-0ea, books-9ig, books-pos, books-m5a)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 00:18:27 +01:00
709d0a4739 Audit v2: fix security, data integrity, compliance, bugs, encoding, UX
Backend Security & Data Integrity:
- Block negative debit/credit amounts that bypass balance validation
- Require document date at posting (was optional, bypassing fiscal year checks)
- Fix event sourcing anti-pattern: timestamps now stored in events, not UtcNow in Apply
- Add [Authorize] to BankingController OAuth callback
- Add company access check on attachment downloads
- Validate CVR in CompanyAggregate.Create and CompanyAggregate.Update
- Require company CVR for invoice creation (Momsloven §52)
- Delete leftover WeatherForecastController
- Fix duplicate migration number 007 (renamed to 007b)
- Remove dead code in VatCalculationService (identical if/else branches)

Accounting Compliance:
- Add missing VAT accounts to StandardDanishAccounts (5610, 5611, 5620)
- Populate SAF-T TaxInformation on transaction lines (was always null)
- Add AuditFileCountry and TaxRegistrationNumber to SAF-T header

Critical Frontend Bugs:
- Fix Dashboard <a href> causing full page reloads (now uses React Router Link)
- Wire Kassekladde filters to actual data (account, status, date range)
- Pre-populate form when editing existing Kassekladde drafts
- Add detail drawer for "Vis detaljer" action (was just a toast)
- Toggle advanced filters with "Flere filtre" button
- CloseFiscalYearWizard now actually posts closing entries via mutations
- "Create next year" checkbox now creates the next fiscal year

Danish Character Encoding (~50 fixes):
- Fix ø/æ/å across Momsindberetning, DocumentUploadModal, Bankafstemning,
  Kontooversigt, CloseFiscalYearWizard, vatCodes, periodStore, periods,
  accounting, types/periods

Dead Buttons & UX:
- Disable Momsindberetning PDF/Export buttons with tooltips
- FiscalYearSelector "Administrer" now navigates to Settings
- Settings bank tab now uses real BankConnectionsTab component
- Bankafstemning save button disabled with development tooltip
- Replace hardcoded account options with real API data (Bankafstemning, Fakturaer)
- Header help button shows info message, notification bell shows popover

Consistency & Quality:
- Remove 7 console.log statements from production code
- Adopt PageHeader on 6 remaining pages (Kreditnotaer, Settings, Admin, etc.)
- Standardize loading states to Skeleton pattern (5 pages)
- Replace deprecated bodyStyle prop on Ant Design Cards
- Standardize date format to DD-MM-YYYY
- Fix sidebar width mismatch in designTokens
- Fix Kontooversigt breadcrumb pointing to non-existent route

Accessibility:
- Add aria-label to sidebar navigation
- Add +/- prefix to AmountText for color-blind users
- Fix CompanySwitcher permanent skeleton when no companies

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 00:18:19 +01:00
a1c2af6027 Close audit issues (books-ley, books-0xk, books-cws, books-k95)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 21:35:40 +01:00
8e05171b66 Full product audit: fix security, compliance, UX, and wire broken features
Security (Phase 1):
- Add authentication middleware on /graphql endpoint
- Filter company queries by user access (prevent IDOR)
- Add role-based authorization on mutations (owner/accountant)
- Reduce API key cache TTL from 24h to 5 minutes
- Hide exception details in production GraphQL errors
- Fix RBAC in frontend companyStore (was hardcoded)

Wiring broken features (Phase 2):
- Wire Kassekladde submit/void/copy to GraphQL mutations
- Wire Kontooversigt account creation to createAccount mutation
- Wire Settings save to updateCompany mutation
- Wire CreateFiscalYearModal and CloseFiscalYearWizard to mutations
- Replace Momsindberetning mock data with real useVatReport query
- Remove Dashboard hardcoded percentages and fake VAT deadline
- Fix Kreditnotaer invoice selector to use real data
- Fix mutation retry from 1 to 0 (prevent duplicate operations)

Accounting compliance (Phase 3):
- Add balanced entry validation (debit==credit) in JournalEntryDraftAggregate
- Add fiscal year boundary enforcement (status, date range checks)
- Add PostedAt timestamp to posted events (Bogføringsloven §7)
- Add account number uniqueness check within company
- Add fiscal year overlap and gap checks
- Add sequential invoice auto-numbering
- Fix InvoiceLine VAT rate to use canonical VatCodes
- Fix SAF-T account type mapping (financial → Expense)
- Add DraftLine validation (cannot have both debit and credit > 0)

UX improvements (Phase 4):
- Fix Danish character encoding across 15+ files (ø, æ, å)
- Deploy DemoDataDisclaimer on pages with mock/incomplete data
- Adopt PageHeader component universally across all pages
- Standardize active/inactive filtering to Switch pattern
- Fix dead buttons in Header (Help, Notifications)
- Remove hardcoded mock data from Settings
- Fix Sidebar controlled state and Kontooversigt navigation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 21:35:26 +01:00
effb06fc44 Fix infinite navigation loop in CompanyGuard
- Add hasNavigatedRef to prevent multiple navigation calls
- Move /opret-virksomhed route outside CompanyGuard in App.tsx
- Reduce retry count and disable refetchOnWindowFocus to limit re-renders
- Remove activeCompany from useEffect dependencies (use getState() instead)

This fixes "Too many calls to Location or History APIs" error that caused
the app to crash with DOMException.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 23:40:05 +01:00
de235a3da7 Fix company and fiscal year sync issues
- Remove duplicate sync logic from CompanySwitcher (CompanyGuard handles it)
- Validate persisted activeCompany against API response in CompanyGuard
- Reset fiscal year state when switching companies in FiscalYearSelector
- Validate currentFiscalYear belongs to current company's data

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:47:05 +01:00
7d819ace28 Remove mock data and connect frontend to backend GraphQL
- CompanySwitcher: Use useMyCompanies() hook instead of mockCompanies
- FiscalYearSelector: Use useFiscalYears() hook instead of mockFiscalYears
- Kontooversigt: Use useAccounts() and useAccountBalances() hooks
- Kassekladde: Use useActiveAccounts() and useJournalEntryDrafts() hooks
- Bankafstemning: Use useActiveBankConnections() and usePendingBankTransactions()
- Dashboard: Calculate metrics from useAccountBalances(), useInvoices(), useVatReport()

All components now show loading skeletons and empty states appropriately.

Closes books-ljg

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:42:10 +01:00
116b54ee0e Close books-0rs (whitescreen fix)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:24:40 +01:00
88bf4c4450 Fix whitescreen - add missing types, exports and props
Frontend build fixes:
- Add formatDateTimeISO and parseISODate to formatters.ts
- Add default type parameter to fetchGraphQL function
- Add toggleMobileDrawer and mobileDrawerOpen to uiStore
- Add compact prop to CompanySwitcher component
- Add JournalEntryDraft types to accounting.ts
- Add reopened/locked fields to FiscalYear type
- Fix documentProcessing.ts import

Closes books-0rs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:24:36 +01:00
381156ade7 Add frontend components, API mutations, and project config
Frontend:
- API mutations for accounts, bank connections, customers, invoices
- Document processing API
- Shared components (PageHeader, EmptyState, etc.)
- Pages: Admin, Fakturaer, Kunder, Ordrer, Produkter, etc.
- Hooks and stores

Config:
- CLAUDE.md project instructions
- Beads issue tracking config
- Git attributes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:20:03 +01:00
1f75c5d791 Add all backend domain, commands, repositories, and tests
This commit includes all previously untracked backend files:

Domain:
- Accounts, Attachments, BankConnections, Customers
- FiscalYears, Invoices, JournalEntryDrafts
- Orders, Products, UserAccess

Commands & Handlers:
- Full CQRS command structure for all domains

Repositories:
- PostgreSQL repositories for all read models
- Bank transaction and ledger repositories

GraphQL:
- Input types, scalars, and types for all entities
- Mutations and queries

Infrastructure:
- Banking integration (Enable Banking client)
- File storage, Invoicing, Reporting, SAF-T export
- Database migrations (003-029)

Tests:
- Integration tests for GraphQL endpoints
- Domain tests
- Invoicing and reporting tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:19:42 +01:00
b552a6e29f Close books-cdf (skipped - vague description)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 17:45:10 +01:00
1d0ea32452 Close tasks books-8lo, books-ced, books-1rp
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 14:47:57 +01:00
8bf3141ba3 Improve Kontooversigt UX and add missing CVR validation
UX improvements (books-8lo):
- Use PageHeader component for consistent header with breadcrumbs
- Add responsive mobile breakpoints
- Improve accessibility with aria-labels
- Better information hierarchy

Fixes (books-1rp):
- Add missing validateCVRModulus11 function to formatters
- Fixes TypeScript errors in Kunder.tsx and CompanySetupWizard.tsx

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 14:47:45 +01:00
49971b3265 Close tasks books-wzq and books-byl
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 14:40:50 +01:00
b450c94a7e Add demo data disclaimers to Dashboard and Loenforstaelse pages
Uses the DemoDataDisclaimer component to inform users that data
shown on these pages is for demonstration purposes only.

Closes books-wzq

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 14:40:40 +01:00
846711de04 Close completed tasks (books-hzt, books-5tg)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 14:37:16 +01:00
6e78028f98 Add BankReconciliationJob for Hangfire
Creates a recurring Hangfire job that compares bank account balances
from Enable Banking with the corresponding ledger accounts:

- Runs daily via Hangfire recurring schedule
- Supports manual trigger per company via GraphQL
- Flags discrepancies > 1 cent with detailed logging
- Includes retry logic for transient failures

Closes books-5tg

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 14:37:05 +01:00
9b5ed27776 Fix encoding bug and add role helpers for user management
- Add decodeHtmlEntities function to formatters.ts for handling HTML entity decoding
- Add CompanyRole type and role helper functions (getRoleLabel, getRoleColor)
- Add useActiveCompanyRole hook for getting current user's company role
- Add Ledger.Core and QuestPDF project references to backend
- Add additional fields to CompanyReadModelDto

Closes books-hzt

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 14:36:27 +01:00
b60f26a449 Close task books-8ea: Remove username from profile icon
The username text next to the profile icon in the header was already
removed in a previous commit.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 14:24:27 +01:00
f1bbccbf52 Remove username text from header profile icon
The user's name/email is no longer displayed next to the profile avatar
in the header. The avatar dropdown menu remains functional for accessing
user settings and logout.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 14:22:44 +01:00
f826794990 Remove Hurtig Bogforing feature
Delete the quick booking page, components, and store:
- HurtigBogforing.tsx page
- simple-booking/ components (AccountQuickPicker, BankTransactionCard, QuickBookModal, SplitBookModal)
- simpleBookingStore.ts

Remove related navigation and shortcuts:
- Route from routes.tsx
- Menu item from Sidebar
- goToHurtigBogforing shortcut and navigation route
- Command palette icon reference

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 14:18:05 +01:00
1bacbea33b Rename app title from Bogfoering to Books in sidebar
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 14:12:35 +01:00
926085eeab Add OpenID Connect + API Key authentication
Backend:
- Cookie + OIDC + API Key authentication schemes
- ApiKeyAuthenticationHandler with SHA-256 validation and 24h cache
- AuthController with login/logout/profile endpoints
- API Key domain model (EventFlow aggregate, events, commands)
- ApiKeyReadModel and repository for key validation
- Database migration 002_ApiKeys.sql
- CORS configuration for frontend

Frontend:
- authService.ts for login/logout/profile API calls
- authStore.ts (Zustand) for user context state
- ProtectedRoute component for route guards
- Header updated with user display and logout
- GraphQL client with credentials: include

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 11:49:29 +01:00
c4a27f0bac Add frontend environment configuration for API URL injection
- .env.example: Documentation template
- .env.development: Local dev defaults (localhost:5000)
- .env.production: Production defaults (relative /graphql path)
- Updated .gitignore to track non-secret env files

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 03:12:45 +01:00
66f6fa138d Initial commit: Books accounting system with EventFlow CQRS
Backend (.NET 10):
- EventFlow CQRS/Event Sourcing with PostgreSQL
- GraphQL.NET API with mutations and queries
- Custom ReadModelSqlGenerator for snake_case PostgreSQL columns
- Hangfire for background job processing
- Integration tests with isolated test databases

Frontend (React/Vite):
- Initial project structure

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 02:52:30 +01:00