diff --git a/build/config/file-size-baseline.json b/build/config/file-size-baseline.json index 58748ce5e4..d4b4b73e2a 100644 --- a/build/config/file-size-baseline.json +++ b/build/config/file-size-baseline.json @@ -3,7 +3,7 @@ "threshold_lines": 2000, "files": { "src/Meridian.Application/FundStructure/InMemoryFundStructureService.cs": 4492, - "src/Meridian.Contracts/Ledger/AccountingConfigurationDtos.cs": 2616, + "src/Meridian.Contracts/Ledger/AccountingConfigurationDtos.cs": 2625, "src/Meridian.FinancialOperations/AccountingClose/AccountingReportPackageService.cs": 2226, "src/Meridian.FinancialOperations/AccountingSystem/AccountingSystemIntegrationService.cs": 2336, "src/Meridian.FinancialOperations/OperationsContinuity/OperationsContinuityWorkflow.cs": 2169, @@ -11,11 +11,11 @@ "src/Meridian.FinancialOperations/PrivateCapital/PrivateCapitalActivityProjectionBuilder.cs": 2146, "src/Meridian.FinancialOperations/PrivateCapital/PrivateCapitalCloseCockpitService.cs": 2052, "src/Meridian.Ui.Shared/Endpoints/FundStructureEndpoints.cs": 2969, - "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs": 3712, + "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs": 3646, "src/Meridian.Ui.Shared/Endpoints/WorkstationEndpoints.cs": 7488, "src/Meridian.Ui.Shared/Evidence/EvidenceContributors.cs": 2954, "src/Meridian.Ui.Shared/Evidence/FileEvidenceArtifactStore.cs": 2565, - "src/Meridian.Ui.Shared/Services/AccountingConfigurationService.cs": 5359, + "src/Meridian.Ui.Shared/Services/AccountingConfigurationService.cs": 5373, "src/Meridian.Ui.Shared/Services/AccountingProductionReadinessService.cs": 3518, "src/Meridian.Ui.Shared/Services/FinancialRecordExplorerReadService.cs": 3576, "src/Meridian.Ui.Shared/Services/FundOperationsWorkspaceReadService.cs": 4616, @@ -28,12 +28,12 @@ "src/Meridian.Ui/dashboard/src/lib/dev-fixtures.ts": 6663, "src/Meridian.Ui/dashboard/src/screens/accounting-screen.close-cockpit.view-model.ts": 3592, "src/Meridian.Ui/dashboard/src/screens/accounting-screen.governance.view-model.ts": 4978, - "src/Meridian.Ui/dashboard/src/screens/accounting-screen.tsx": 7537, + "src/Meridian.Ui/dashboard/src/screens/accounting-screen.tsx": 7531, "src/Meridian.Ui/dashboard/src/screens/accounting-screen.view-model.ts": 7269, - "src/Meridian.Ui/dashboard/src/screens/data-screen.tsx": 2608, + "src/Meridian.Ui/dashboard/src/screens/data-screen.tsx": 2411, "src/Meridian.Ui/dashboard/src/screens/data-screen.view-model.ts": 5017, "src/Meridian.Ui/dashboard/src/screens/evidence-workbench-screen.view-model.ts": 2295, - "src/Meridian.Ui/dashboard/src/screens/live-quotes-screen.view-model.ts": 2637, + "src/Meridian.Ui/dashboard/src/screens/live-quotes-screen.view-model.ts": 2042, "src/Meridian.Ui/dashboard/src/screens/operations-continuity-screen.tsx": 2500, "src/Meridian.Ui/dashboard/src/screens/operations-continuity-screen.view-model.ts": 4054, "src/Meridian.Ui/dashboard/src/screens/portfolio-screen.view-model.ts": 2541, @@ -45,7 +45,7 @@ "src/Meridian.Ui/dashboard/src/screens/strategy-screen.view-model.ts": 3492, "src/Meridian.Ui/dashboard/src/screens/trading-screen.tsx": 2605, "src/Meridian.Ui/dashboard/src/screens/trading-screen.view-model.ts": 5355, - "src/Meridian.Ui/dashboard/src/types.ts": 11139, + "src/Meridian.Ui/dashboard/src/types.ts": 11142, "src/Meridian.Wpf/ViewModels/Accounting/AccountingCloseViewModel.cs": 2653, "src/Meridian.Wpf/ViewModels/Accounting/AccountingConfigureViewModel.cs": 5545, "src/Meridian.Wpf/ViewModels/FundLedgerViewModel.cs": 3468, diff --git a/docs/generated/repository-structure.md b/docs/generated/repository-structure.md index 699f23b885..aba2405ff9 100644 --- a/docs/generated/repository-structure.md +++ b/docs/generated/repository-structure.md @@ -4964,6 +4964,8 @@ Meridian-main │ │ │ │ │ └── ui │ │ │ │ │ ├── accordion.test.tsx │ │ │ │ │ ├── accordion.tsx +│ │ │ │ │ ├── async-region.test.tsx +│ │ │ │ │ ├── async-region.tsx │ │ │ │ │ ├── badge.tsx │ │ │ │ │ ├── breadcrumb.tsx │ │ │ │ │ ├── button.test.tsx @@ -4987,6 +4989,8 @@ Meridian-main │ │ │ │ │ ├── dialog.view-model.ts │ │ │ │ │ ├── drawer.test.tsx │ │ │ │ │ ├── drawer.tsx +│ │ │ │ │ ├── error-boundary.test.tsx +│ │ │ │ │ ├── error-boundary.tsx │ │ │ │ │ ├── eyebrow.tsx │ │ │ │ │ ├── feedback-primitives.test.tsx │ │ │ │ │ ├── field-support.test.tsx @@ -5020,11 +5024,15 @@ Meridian-main │ │ │ │ │ ├── risk-control-panel.tsx │ │ │ │ │ ├── risk-control-panel.view-model.test.ts │ │ │ │ │ ├── risk-control-panel.view-model.ts +│ │ │ │ │ ├── screen-layout.test.tsx +│ │ │ │ │ ├── screen-layout.tsx │ │ │ │ │ ├── segmented-control.test.tsx │ │ │ │ │ ├── segmented-control.tsx │ │ │ │ │ ├── select.tsx │ │ │ │ │ ├── sheet.test.tsx │ │ │ │ │ ├── sheet.tsx +│ │ │ │ │ ├── skeleton.test.tsx +│ │ │ │ │ ├── skeleton.tsx │ │ │ │ │ ├── spinner.tsx │ │ │ │ │ ├── status-banner.tsx │ │ │ │ │ ├── stepper.test.tsx @@ -5188,12 +5196,15 @@ Meridian-main │ │ │ │ │ ├── daily-control-tower-screen.tsx │ │ │ │ │ ├── data-screen.capability-matrix.view-model.test.ts │ │ │ │ │ ├── data-screen.capability-matrix.view-model.ts +│ │ │ │ │ ├── data-screen.cell-actions.test.tsx +│ │ │ │ │ ├── data-screen.cell-actions.tsx │ │ │ │ │ ├── data-screen.corporate-action-inbox.view-model.test.ts │ │ │ │ │ ├── data-screen.corporate-action-inbox.view-model.ts │ │ │ │ │ ├── data-screen.coverage-gaps.view-model.test.ts │ │ │ │ │ ├── data-screen.coverage-gaps.view-model.ts │ │ │ │ │ ├── data-screen.data-quality.view-model.test.ts │ │ │ │ │ ├── data-screen.data-quality.view-model.ts +│ │ │ │ │ ├── data-screen.data-regions.tsx │ │ │ │ │ ├── data-screen.evidence-timeline.ts │ │ │ │ │ ├── data-screen.linked-context.ts │ │ │ │ │ ├── data-screen.operator-focus.ts @@ -5201,6 +5212,7 @@ Meridian-main │ │ │ │ │ ├── data-screen.query-panel.view-model.ts │ │ │ │ │ ├── data-screen.security-master.ts │ │ │ │ │ ├── data-screen.test.tsx +│ │ │ │ │ ├── data-screen.tone-styles.ts │ │ │ │ │ ├── data-screen.tsx │ │ │ │ │ ├── data-screen.view-model.test.ts │ │ │ │ │ ├── data-screen.view-model.ts diff --git a/docs/status/api-contract-coverage-dashboard.json b/docs/status/api-contract-coverage-dashboard.json index 5af956df3d..884a7ddf30 100644 --- a/docs/status/api-contract-coverage-dashboard.json +++ b/docs/status/api-contract-coverage-dashboard.json @@ -1859,307 +1859,307 @@ { "method": "GET", "path": "/api/ledger/books", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:25", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:28", "documented": true }, { "method": "GET", "path": "/api/ledger/books/{ledgerBookId:guid}", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:52", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:55", "documented": true }, { "method": "POST", "path": "/api/ledger/books", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:75", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:78", "documented": true }, { "method": "POST", "path": "/api/ledger/books/rollout-assessment", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:106", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:109", "documented": true }, { "method": "GET", "path": "/api/ledger/periods", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:147", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:150", "documented": true }, { "method": "POST", "path": "/api/ledger/periods", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:185", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:188", "documented": true }, { "method": "POST", "path": "/api/ledger/periods/{periodId:guid}/close", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:217", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:220", "documented": true }, { "method": "GET", "path": "/api/ledger/periods/{periodId:guid}/journal-entries", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:261", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:264", "documented": true }, { "method": "GET", "path": "/api/ledger/aggregates/{aggregateId:guid}/journal-entries", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:305", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:308", "documented": true }, { "method": "GET", "path": "/api/ledger/periods/{periodId:guid}/trial-balance", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:354", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:357", "documented": true }, { "method": "GET", "path": "/api/ledger/periods/{periodId:guid}/trial-balance-report", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:379", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:382", "documented": true }, { "method": "GET", "path": "/api/ledger/periods/{periodId:guid}/pnl-summary", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:404", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:407", "documented": true }, { "method": "GET", "path": "/api/ledger/reports/trial-balance", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:429", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:432", "documented": true }, { "method": "GET", "path": "/api/ledger/reports/pnl-summary", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:488", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:491", "documented": true }, { "method": "GET", "path": "/api/ledger/accounting-configuration", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:547", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:550", "documented": true }, { "method": "POST", "path": "/api/ledger/accounting-configuration/chart", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:575", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:578", "documented": true }, { "method": "POST", "path": "/api/ledger/accounting-configuration/templates", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:606", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:609", "documented": true }, { "method": "POST", "path": "/api/ledger/accounting-configuration/posting-rules", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:637", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:640", "documented": true }, { "method": "POST", "path": "/api/ledger/accounting-configuration/posting-rules/promotion-approvals", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:668", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:671", "documented": true }, { "method": "POST", "path": "/api/ledger/accounting-configuration/posting-rules/test-cases", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:704", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:707", "documented": true }, { "method": "POST", "path": "/api/ledger/accounting-configuration/preview", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:735", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:738", "documented": true }, { "method": "POST", "path": "/api/ledger/accounting-configuration/posting-rules/dry-run", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:770", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:773", "documented": true }, { "method": "POST", "path": "/api/ledger/accounting-configuration/posting-rules/candidates", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:811", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:814", "documented": true }, { "method": "POST", "path": "/api/ledger/accounting-configuration/posting-rules/candidates/post", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:854", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:857", "documented": true }, { "method": "POST", "path": "/api/ledger/accounting-configuration/posting-rules/projection-sets", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:898", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:901", "documented": true }, { "method": "POST", "path": "/api/ledger/accounting-configuration/posting-rules/tests", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:941", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:944", "documented": true }, { "method": "POST", "path": "/api/ledger/accounting-configuration/activate", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:982", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:985", "documented": true }, { "method": "GET", "path": "/api/ledger/accounting-configuration/audit", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1017", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1020", "documented": true }, { "method": "GET", "path": "/api/ledger/close-management/period-plan/{workflowId:guid}", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1045", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1048", "documented": true }, { "method": "POST", "path": "/api/ledger/close-management/period-plan/configuration", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1071", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1074", "documented": true }, { "method": "POST", "path": "/api/ledger/close-management/late-adjustments", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1121", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1124", "documented": true }, { "method": "POST", "path": "/api/ledger/close-management/late-adjustments/review", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1171", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1174", "documented": true }, { "method": "POST", "path": "/api/ledger/close-management/task-signoffs", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1221", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1224", "documented": true }, { "method": "POST", "path": "/api/ledger/close-management/evidence-review", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1271", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1274", "documented": true }, { "method": "POST", "path": "/api/ledger/close-management/period-lock", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1321", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1324", "documented": true }, { "method": "POST", "path": "/api/ledger/reports/accounting-package", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1375", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1378", "documented": true }, { "method": "POST", "path": "/api/ledger/reports/accounting-package/certification", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1426", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1429", "documented": true }, { "method": "GET", "path": "/api/ledger/reports/accounting-packages", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1479", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1482", "documented": true }, { "method": "GET", "path": "/api/ledger/reports/accounting-packages/{packageId}/exports/{artifactId}", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1516", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1519", "documented": true }, { "method": "GET", "path": "/api/ledger/journal-entry-workbench", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1562", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1565", "documented": true }, { "method": "GET", "path": "/api/ledger/private-capital/activity", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1588", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1591", "documented": true }, { "method": "GET", "path": "/api/ledger/private-capital/fund-event-record", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1620", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1623", "documented": true }, { "method": "GET", "path": "/api/ledger/private-capital/fund-event-command-center", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1663", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1666", "documented": true }, { "method": "GET", "path": "/api/ledger/private-capital/capital-account-subledger", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1704", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1707", "documented": true }, { "method": "GET", "path": "/api/ledger/private-capital/report-output", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1765", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1768", "documented": true }, { "method": "GET", "path": "/api/ledger/private-capital/capital-account-workbench", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1836", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1839", "documented": true }, { "method": "POST", "path": "/api/ledger/journal-entry-workbench/drafts", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1883", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1886", "documented": true }, { "method": "POST", "path": "/api/ledger/journal-entry-workbench/validate", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1934", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1945", "documented": true }, { "method": "POST", "path": "/api/ledger/journal-entry-workbench/submit-approval", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1975", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1991", "documented": true }, { "method": "POST", "path": "/api/ledger/journal-entry-workbench/evidence", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:2020", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:2036", "documented": true }, { "method": "POST", "path": "/api/ledger/journal-entry-workbench/lifecycle-action", - "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:2063", + "source": "src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:2079", "documented": true }, { diff --git a/docs/status/api-contract-coverage-dashboard.md b/docs/status/api-contract-coverage-dashboard.md index 6d4f7522c3..9be1e58409 100644 --- a/docs/status/api-contract-coverage-dashboard.md +++ b/docs/status/api-contract-coverage-dashboard.md @@ -233,60 +233,60 @@ Tracks whether mapped API routes and workstation DTO contracts are visible in th | `POST` | `/api/lean/sync` | Documented | `src/Meridian.Ui.Shared/Endpoints/LeanEndpoints.cs:179` | | `GET` | `/api/lean/sync/status` | Documented | `src/Meridian.Ui.Shared/Endpoints/LeanEndpoints.cs:230` | | `POST` | `/api/lean/verify` | Documented | `src/Meridian.Ui.Shared/Endpoints/LeanEndpoints.cs:87` | -| `GET` | `/api/ledger/accounting-configuration` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:547` | -| `POST` | `/api/ledger/accounting-configuration/activate` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:982` | -| `GET` | `/api/ledger/accounting-configuration/audit` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1017` | -| `POST` | `/api/ledger/accounting-configuration/chart` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:575` | -| `POST` | `/api/ledger/accounting-configuration/posting-rules` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:637` | -| `POST` | `/api/ledger/accounting-configuration/posting-rules/candidates` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:811` | -| `POST` | `/api/ledger/accounting-configuration/posting-rules/candidates/post` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:854` | -| `POST` | `/api/ledger/accounting-configuration/posting-rules/dry-run` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:770` | -| `POST` | `/api/ledger/accounting-configuration/posting-rules/projection-sets` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:898` | -| `POST` | `/api/ledger/accounting-configuration/posting-rules/promotion-approvals` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:668` | -| `POST` | `/api/ledger/accounting-configuration/posting-rules/test-cases` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:704` | -| `POST` | `/api/ledger/accounting-configuration/posting-rules/tests` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:941` | -| `POST` | `/api/ledger/accounting-configuration/preview` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:735` | -| `POST` | `/api/ledger/accounting-configuration/templates` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:606` | -| `GET` | `/api/ledger/aggregates/{aggregateId:guid}/journal-entries` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:305` | -| `GET` | `/api/ledger/books` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:25` | -| `POST` | `/api/ledger/books` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:75` | -| `POST` | `/api/ledger/books/rollout-assessment` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:106` | -| `GET` | `/api/ledger/books/{ledgerBookId:guid}` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:52` | -| `POST` | `/api/ledger/close-management/evidence-review` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1271` | -| `POST` | `/api/ledger/close-management/late-adjustments` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1121` | -| `POST` | `/api/ledger/close-management/late-adjustments/review` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1171` | -| `POST` | `/api/ledger/close-management/period-lock` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1321` | -| `POST` | `/api/ledger/close-management/period-plan/configuration` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1071` | -| `GET` | `/api/ledger/close-management/period-plan/{workflowId:guid}` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1045` | -| `POST` | `/api/ledger/close-management/task-signoffs` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1221` | +| `GET` | `/api/ledger/accounting-configuration` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:550` | +| `POST` | `/api/ledger/accounting-configuration/activate` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:985` | +| `GET` | `/api/ledger/accounting-configuration/audit` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1020` | +| `POST` | `/api/ledger/accounting-configuration/chart` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:578` | +| `POST` | `/api/ledger/accounting-configuration/posting-rules` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:640` | +| `POST` | `/api/ledger/accounting-configuration/posting-rules/candidates` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:814` | +| `POST` | `/api/ledger/accounting-configuration/posting-rules/candidates/post` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:857` | +| `POST` | `/api/ledger/accounting-configuration/posting-rules/dry-run` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:773` | +| `POST` | `/api/ledger/accounting-configuration/posting-rules/projection-sets` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:901` | +| `POST` | `/api/ledger/accounting-configuration/posting-rules/promotion-approvals` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:671` | +| `POST` | `/api/ledger/accounting-configuration/posting-rules/test-cases` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:707` | +| `POST` | `/api/ledger/accounting-configuration/posting-rules/tests` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:944` | +| `POST` | `/api/ledger/accounting-configuration/preview` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:738` | +| `POST` | `/api/ledger/accounting-configuration/templates` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:609` | +| `GET` | `/api/ledger/aggregates/{aggregateId:guid}/journal-entries` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:308` | +| `GET` | `/api/ledger/books` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:28` | +| `POST` | `/api/ledger/books` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:78` | +| `POST` | `/api/ledger/books/rollout-assessment` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:109` | +| `GET` | `/api/ledger/books/{ledgerBookId:guid}` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:55` | +| `POST` | `/api/ledger/close-management/evidence-review` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1274` | +| `POST` | `/api/ledger/close-management/late-adjustments` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1124` | +| `POST` | `/api/ledger/close-management/late-adjustments/review` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1174` | +| `POST` | `/api/ledger/close-management/period-lock` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1324` | +| `POST` | `/api/ledger/close-management/period-plan/configuration` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1074` | +| `GET` | `/api/ledger/close-management/period-plan/{workflowId:guid}` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1048` | +| `POST` | `/api/ledger/close-management/task-signoffs` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1224` | | `POST` | `/api/ledger/journal-automation/dividend-intake` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.JournalAutomation.cs:19` | | `POST` | `/api/ledger/journal-automation/fee-accrual-intake` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.JournalAutomation.cs:61` | | `POST` | `/api/ledger/journal-automation/period-close-intake` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.JournalAutomation.cs:103` | -| `GET` | `/api/ledger/journal-entry-workbench` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1562` | -| `POST` | `/api/ledger/journal-entry-workbench/drafts` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1883` | -| `POST` | `/api/ledger/journal-entry-workbench/evidence` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:2020` | -| `POST` | `/api/ledger/journal-entry-workbench/lifecycle-action` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:2063` | -| `POST` | `/api/ledger/journal-entry-workbench/submit-approval` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1975` | -| `POST` | `/api/ledger/journal-entry-workbench/validate` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1934` | -| `GET` | `/api/ledger/periods` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:147` | -| `POST` | `/api/ledger/periods` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:185` | -| `POST` | `/api/ledger/periods/{periodId:guid}/close` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:217` | -| `GET` | `/api/ledger/periods/{periodId:guid}/journal-entries` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:261` | -| `GET` | `/api/ledger/periods/{periodId:guid}/pnl-summary` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:404` | -| `GET` | `/api/ledger/periods/{periodId:guid}/trial-balance` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:354` | -| `GET` | `/api/ledger/periods/{periodId:guid}/trial-balance-report` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:379` | -| `GET` | `/api/ledger/private-capital/activity` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1588` | -| `GET` | `/api/ledger/private-capital/capital-account-subledger` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1704` | -| `GET` | `/api/ledger/private-capital/capital-account-workbench` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1836` | -| `GET` | `/api/ledger/private-capital/fund-event-command-center` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1663` | -| `GET` | `/api/ledger/private-capital/fund-event-record` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1620` | -| `GET` | `/api/ledger/private-capital/report-output` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1765` | -| `POST` | `/api/ledger/reports/accounting-package` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1375` | -| `POST` | `/api/ledger/reports/accounting-package/certification` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1426` | -| `GET` | `/api/ledger/reports/accounting-packages` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1479` | -| `GET` | `/api/ledger/reports/accounting-packages/{packageId}/exports/{artifactId}` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1516` | -| `GET` | `/api/ledger/reports/pnl-summary` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:488` | -| `GET` | `/api/ledger/reports/trial-balance` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:429` | +| `GET` | `/api/ledger/journal-entry-workbench` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1565` | +| `POST` | `/api/ledger/journal-entry-workbench/drafts` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1886` | +| `POST` | `/api/ledger/journal-entry-workbench/evidence` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:2036` | +| `POST` | `/api/ledger/journal-entry-workbench/lifecycle-action` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:2079` | +| `POST` | `/api/ledger/journal-entry-workbench/submit-approval` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1991` | +| `POST` | `/api/ledger/journal-entry-workbench/validate` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1945` | +| `GET` | `/api/ledger/periods` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:150` | +| `POST` | `/api/ledger/periods` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:188` | +| `POST` | `/api/ledger/periods/{periodId:guid}/close` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:220` | +| `GET` | `/api/ledger/periods/{periodId:guid}/journal-entries` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:264` | +| `GET` | `/api/ledger/periods/{periodId:guid}/pnl-summary` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:407` | +| `GET` | `/api/ledger/periods/{periodId:guid}/trial-balance` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:357` | +| `GET` | `/api/ledger/periods/{periodId:guid}/trial-balance-report` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:382` | +| `GET` | `/api/ledger/private-capital/activity` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1591` | +| `GET` | `/api/ledger/private-capital/capital-account-subledger` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1707` | +| `GET` | `/api/ledger/private-capital/capital-account-workbench` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1839` | +| `GET` | `/api/ledger/private-capital/fund-event-command-center` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1666` | +| `GET` | `/api/ledger/private-capital/fund-event-record` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1623` | +| `GET` | `/api/ledger/private-capital/report-output` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1768` | +| `POST` | `/api/ledger/reports/accounting-package` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1378` | +| `POST` | `/api/ledger/reports/accounting-package/certification` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1429` | +| `GET` | `/api/ledger/reports/accounting-packages` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1482` | +| `GET` | `/api/ledger/reports/accounting-packages/{packageId}/exports/{artifactId}` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:1519` | +| `GET` | `/api/ledger/reports/pnl-summary` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:491` | +| `GET` | `/api/ledger/reports/trial-balance` | Documented | `src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs:432` | | `GET` | `/api/loans/portfolio` | Documented | `src/Meridian.Ui.Shared/Endpoints/DirectLendingEndpoints.cs:1094` | | `POST` | `/api/loans/rebuild-all` | Documented | `src/Meridian.Ui.Shared/Endpoints/DirectLendingEndpoints.cs:1105` | | `GET` | `/api/loans/rebuild-checkpoints` | Documented | `src/Meridian.Ui.Shared/Endpoints/DirectLendingEndpoints.cs:1085` | diff --git a/docs/status/coverage-report.md b/docs/status/coverage-report.md index 85682ac033..fb09dd9838 100644 --- a/docs/status/coverage-report.md +++ b/docs/status/coverage-report.md @@ -5,7 +5,7 @@ ## Overall Coverage -**2706 / 7354** items documented (**36.8%**) — Grade: **F** +**2698 / 7338** items documented (**36.8%**) — Grade: **F** ```text [=======-------------] 36.8% @@ -15,15 +15,15 @@ | Category | Documented | Total | Coverage | Grade | | ---------- | ----------- | ------- | ---------- | ------- | -| Public Classes / Interfaces | 2586 | 6931 | 37.3% | F | -| API Endpoints | 106 | 276 | 38.4% | F | +| Public Classes / Interfaces | 2578 | 6916 | 37.3% | F | +| API Endpoints | 106 | 275 | 38.5% | F | | Configuration Options | 3 | 136 | 2.2% | F | | Provider Implementations | 0 | 0 | 100.0% | A | | ADR Implementations | 11 | 11 | 100.0% | A | ## Undocumented Items -### Public Classes / Interfaces (4345 undocumented) +### Public Classes / Interfaces (4338 undocumented) | Item | Location | | ------ | ---------- | @@ -76,7 +76,8 @@ | `RestatementCandidateResult` | `src/Meridian.Application/SecurityMaster/IPeriodAwareRestatementResolver.cs:44` | | `SecurityMasterRevisionRecord` | `src/Meridian.Application/SecurityMaster/ISecurityMasterRevisionStore.cs:52` | | `NullSecurityMasterPricingService` | `src/Meridian.Application/SecurityMaster/NullSecurityMasterClearwaterServices.cs:10` | -| ... and 4295 more | | +| `NullSecurityMasterCashFlowService` | `src/Meridian.Application/SecurityMaster/NullSecurityMasterClearwaterServices.cs:37` | +| ... and 4288 more | | ### API Endpoints (170 undocumented) @@ -192,8 +193,8 @@ ## Recommendations -1. **Public Classes / Interfaces**: 4345 undocumented types. Consider generating API docs with DocFX (`docfx docfx.json`) to cover the long tail of public types automatically. -2. **API Endpoints**: 170 endpoint(s) missing from `docs/reference/api-reference.md`. Run the endpoint audit and update the API reference table. +1. **Public Classes / Interfaces**: 4338 undocumented types. Consider generating API docs with DocFX (`docfx docfx.json`) to cover the long tail of public types automatically. +2. **API Endpoints**: 169 endpoint(s) missing from `docs/reference/api-reference.md`. Run the endpoint audit and update the API reference table. 3. **Configuration Options**: 133 config key(s) not found in `docs/generated/configuration-schema.md`. Re-run the configuration schema generator to synchronise. --- diff --git a/docs/status/doc-health-dashboard.json b/docs/status/doc-health-dashboard.json index 20b27db9d7..32e889ee85 100644 --- a/docs/status/doc-health-dashboard.json +++ b/docs/status/doc-health-dashboard.json @@ -1,7 +1,7 @@ { "total_files": 543, - "total_lines": 90801, - "orphaned_count": 208, + "total_lines": 90797, + "orphaned_count": 207, "no_heading_count": 38, "stale_count": 0, "todo_count": 204, @@ -2148,7 +2148,7 @@ }, { "path": "docs/generated/repository-structure.md", - "line_count": 7958, + "line_count": 7970, "has_heading": true, "todo_count": 9, "last_modified_utc": "1970-01-01T00:00:00+00:00", @@ -4364,7 +4364,7 @@ }, { "path": "src/Meridian.Storage/README.md", - "line_count": 326, + "line_count": 337, "has_heading": true, "todo_count": 1, "last_modified_utc": "1970-01-01T00:00:00+00:00", diff --git a/docs/status/doc-health-dashboard.md b/docs/status/doc-health-dashboard.md index 80bebf0fd8..2bacb277fc 100644 --- a/docs/status/doc-health-dashboard.md +++ b/docs/status/doc-health-dashboard.md @@ -20,9 +20,9 @@ Data sources: `repo markdown (*.md)`, `file modification metadata` | Metric | Value | | -------- | ------- | | Total documentation files | 543 | -| Total lines | 90,801 | +| Total lines | 90,797 | | Average file size (lines) | 167.2 | -| Orphaned files | 208 | +| Orphaned files | 207 | | Files without headings | 38 | | Stale files (>90 days) | 0 | | TODO/FIXME markers | 204 | @@ -85,7 +85,7 @@ These files are not linked from any other Markdown file in the repository: - `Meridian Design System/VISUAL_FOUNDATIONS.md` - `Meridian Design System/components/charts/CandleChart.prompt.md` - `Meridian Design System/components/charts/ChartCard.prompt.md` -- ... and 188 more +- ... and 187 more ## Trend diff --git a/src/Meridian.Contracts/Ledger/AccountingConfigurationDtos.cs b/src/Meridian.Contracts/Ledger/AccountingConfigurationDtos.cs index 9c3c093c8a..3d81ceccba 100644 --- a/src/Meridian.Contracts/Ledger/AccountingConfigurationDtos.cs +++ b/src/Meridian.Contracts/Ledger/AccountingConfigurationDtos.cs @@ -722,7 +722,13 @@ public sealed record ManualJournalEntryLineDto( string? TaxLotId = null, string? Description = null, string? EvidenceLink = null, - LedgerDimensionSetDto? Dimensions = null); + LedgerDimensionSetDto? Dimensions = null, + // Structured ledger-account identity beyond the chart path. Automated drafts built from + // scoped trial-balance rows (for example period-close entries on symbol- or + // financial-account-scoped revenue/expense accounts) carry these so posting lands on the + // scoped account and actually zeroes the scoped balance instead of an unscoped aggregate. + string? LedgerAccountSymbol = null, + string? LedgerAccountFinancialAccountId = null); public sealed record ManualJournalEntryEvidenceAttachmentDto( string AttachmentId, diff --git a/src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs b/src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs index c6030c348c..3c3f8ea562 100644 --- a/src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs +++ b/src/Meridian.Ui.Shared/Endpoints/LedgerEndpoints.cs @@ -20,6 +20,9 @@ namespace Meridian.Ui.Shared.Endpoints; public static partial class LedgerEndpoints { + private const string ClosingEntryClientRejectionMessage = + "Closing entries are produced by the governed period-close workflow and cannot be submitted as manual journal drafts."; + public static void MapLedgerEndpoints(this WebApplication app, JsonSerializerOptions jsonOptions) { app.MapGet(UiApiRoutes.LedgerBooks, async ( @@ -1893,6 +1896,14 @@ normalizedReportPackId is null && return ServiceUnavailable(); } + // Closing entries are the sanctioned exception to the closed-period posting bar; only the + // in-process period-close automation may produce them. Reject client-submitted ClosingEntry + // drafts so this HTTP boundary cannot be used to post to a closed period. + if (request.Draft?.EntryType == ManualJournalEntryTypeDto.ClosingEntry) + { + return Results.BadRequest(new { error = ClosingEntryClientRejectionMessage }); + } + try { var tenantContext = HttpContextWorkstationTenantContextAccessor.Resolve(context); @@ -1944,6 +1955,11 @@ normalizedReportPackId is null && return ServiceUnavailable(); } + if (request.Draft?.EntryType == ManualJournalEntryTypeDto.ClosingEntry) + { + return Results.BadRequest(new { error = ClosingEntryClientRejectionMessage }); + } + try { var tenantContext = HttpContextWorkstationTenantContextAccessor.Resolve(context); diff --git a/src/Meridian.Ui.Shared/Services/AccountingConfigurationService.cs b/src/Meridian.Ui.Shared/Services/AccountingConfigurationService.cs index a8e9b67640..41de1287ef 100644 --- a/src/Meridian.Ui.Shared/Services/AccountingConfigurationService.cs +++ b/src/Meridian.Ui.Shared/Services/AccountingConfigurationService.cs @@ -3993,11 +3993,19 @@ private async Task BuildManualJournalEntryWriteAsync( } var amount = Math.Abs(line.Amount); + // Preserve the structured ledger-account identity (symbol / financial account) supplied by + // automated drafts so scoped postings (for example period-close entries on broker-scoped + // revenue) land on the scoped account and zero the scoped trial-balance row rather than an + // unscoped aggregate. Client-entered lines leave these null, matching prior behavior. lines.Add(new LedgerEntry( CreateDeterministicGuid("manual-je-line", draft.JournalEntryId.ToString("D"), line.LineId, line.Side.ToString()), draft.JournalEntryId, timestamp, - new LedgerAccount(account.AccountName, accountType), + new LedgerAccount( + account.AccountName, + accountType, + NormalizeOptional(line.LedgerAccountSymbol), + NormalizeOptional(line.LedgerAccountFinancialAccountId)), line.Side == AccountingTemplateLineSideDto.Debit ? amount : 0m, line.Side == AccountingTemplateLineSideDto.Credit ? amount : 0m, description, diff --git a/src/Meridian.Ui.Shared/Services/AutomatedJournalDraftIntakeService.cs b/src/Meridian.Ui.Shared/Services/AutomatedJournalDraftIntakeService.cs index 5e5fae25bc..c2656a6816 100644 --- a/src/Meridian.Ui.Shared/Services/AutomatedJournalDraftIntakeService.cs +++ b/src/Meridian.Ui.Shared/Services/AutomatedJournalDraftIntakeService.cs @@ -222,7 +222,9 @@ private static ManualJournalEntryDraftDto BuildDraftDto( SecurityDisplayName: line.account.Symbol, Description: line.account.ToString(), EvidenceLink: firstEvidenceLink, - Dimensions: LedgerDimensionMapper.ToDto(line.dimensions)); + Dimensions: LedgerDimensionMapper.ToDto(line.dimensions), + LedgerAccountSymbol: line.account.Symbol, + LedgerAccountFinancialAccountId: line.account.FinancialAccountId); }) .ToArray(); diff --git a/src/Meridian.Ui/dashboard/src/types.ts b/src/Meridian.Ui/dashboard/src/types.ts index 22870490b9..86e95eb929 100644 --- a/src/Meridian.Ui/dashboard/src/types.ts +++ b/src/Meridian.Ui/dashboard/src/types.ts @@ -7351,6 +7351,8 @@ export interface ManualJournalEntryLine { taxLotId?: string | null; description?: string | null; evidenceLink?: string | null; + ledgerAccountSymbol?: string | null; + ledgerAccountFinancialAccountId?: string | null; } export interface ManualJournalEntryEvidenceAttachment { diff --git a/tests/Meridian.Tests/Ui/AutomatedJournalEventProducerTests.cs b/tests/Meridian.Tests/Ui/AutomatedJournalEventProducerTests.cs index 687db0ef37..bf9d6f1de6 100644 --- a/tests/Meridian.Tests/Ui/AutomatedJournalEventProducerTests.cs +++ b/tests/Meridian.Tests/Ui/AutomatedJournalEventProducerTests.cs @@ -396,11 +396,34 @@ private static ILedgerBookService LedgerBookServiceWithClosedPeriod( private static LedgerPeriodTrialBalanceLineDto TrialBalanceLine( string accountName, string accountType, decimal debits, decimal credits, decimal balance, - LedgerDimensionSetDto? dimensions = null) - => new(accountName, accountType, Symbol: null, FinancialAccountId: null, + LedgerDimensionSetDto? dimensions = null, string? symbol = null, string? financialAccountId = null) + => new(accountName, accountType, Symbol: symbol, FinancialAccountId: financialAccountId, DebitTotal: debits, CreditTotal: credits, Balance: balance, EntryCount: 1, Dimensions: dimensions); + [Fact] + public async Task Runner_PeriodCloseIntake_PreservesAccountSymbolAndFinancialAccountScope() + { + var fixture = CreateIntakeFixture(); + // A financial-account-scoped revenue balance (broker-specific dividend income) must close to + // the scoped account so the scoped trial-balance row is zeroed, not an unscoped aggregate. + var bookService = LedgerBookServiceWithClosedPeriod( + TrialBalanceLine("Dividend Income", "Revenue", 0m, 250m, 250m, + symbol: "AAPL", financialAccountId: "broker-1")); + var runner = new AutomatedJournalIntakeRunner( + fixture.Intake, new FeeScheduleAccrualEventProducer(), ledgerBookService: bookService); + + var result = await runner.RunPeriodCloseIntakeAsync(new RunPeriodCloseDraftIntakeRequest( + "fund-alpha", "USD", "fund-controller", ClosedPeriodId, BookId)); + + var draft = result.Intake.Created.Should().ContainSingle().Subject; + draft.Lines.Should().Contain(line => + line.LedgerAccountFinancialAccountId == "broker-1" && + line.LedgerAccountSymbol == "AAPL" && + line.Amount == 250m, + "the scoped revenue account's identity must survive onto the closing draft line so posting zeroes the scoped balance"); + } + [Fact] public async Task Runner_PeriodCloseIntake_PreservesDimensionSplitClosingLines() { diff --git a/tests/Meridian.Tests/Ui/WorkstationEndpointsTests.AccountingConfiguration.cs b/tests/Meridian.Tests/Ui/WorkstationEndpointsTests.AccountingConfiguration.cs index 7f47dfb4c5..3c961409a5 100644 --- a/tests/Meridian.Tests/Ui/WorkstationEndpointsTests.AccountingConfiguration.cs +++ b/tests/Meridian.Tests/Ui/WorkstationEndpointsTests.AccountingConfiguration.cs @@ -911,6 +911,37 @@ await client.PostAsJsonAsync( missingPrivateCapitalActivity.CapitalAccountSubledgers.Should().BeEmpty(); } + [Fact] + public async Task ManualJournalEntrySaveEndpoint_RejectsClientSubmittedClosingEntry() + { + await using var app = await CreateAppAsync( + RegisterAccountingConfigurationServices, + currentUserPermissions: UserPermission.AdminMaintenance, + currentUserCompanyId: "company-alpha"); + var client = app.GetTestClient(); + + // A closing entry may only be produced by the in-process period-close automation. A client + // stamping EntryType=ClosingEntry would otherwise bypass the closed-period posting bar. + var closingDraft = ManualJournalEntryDraft() with + { + EntryType = ManualJournalEntryTypeDto.ClosingEntry + }; + + using var saveResponse = await client.PostAsJsonAsync( + UiApiRoutes.LedgerManualJournalEntryDrafts, + new SaveManualJournalEntryDraftRequest(closingDraft, "browser-user"), + ServerJsonOptions); + using var validateResponse = await client.PostAsJsonAsync( + UiApiRoutes.LedgerManualJournalEntryValidate, + new ValidateManualJournalEntryDraftRequest(closingDraft, "browser-user"), + ServerJsonOptions); + + saveResponse.StatusCode.Should().Be(HttpStatusCode.BadRequest); + validateResponse.StatusCode.Should().Be(HttpStatusCode.BadRequest); + var saveBody = await saveResponse.Content.ReadAsStringAsync(); + saveBody.Should().Contain("period-close workflow"); + } + [Fact] public async Task ManualJournalEntryWorkbenchEndpoints_StampsTrustedRoleProfileScopeOnAudit() {