DJ-92: Account Overview dashboard (/api/account-summary + Angular /dashboard) - #30
Conversation
…nto devin/1755440000-dj92-account-summary-dashboard
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
DJ-92 verified end-to-endTested against the running dev stack (Spring Boot :8080 + Angular :9000, H2 dev data). Raw Dashboard renders live data from /api/account-summaryCards matched the API JSON exactly ( To prove the figures are live and not a fixture, a new bank account ( Navigation + auth gating
Cosmetic observations (not blockers)
|




Summary
DJ-92 — first user-facing summary screen: a read-only aggregation endpoint plus an authenticated Angular page at
/dashboardshowing total balance, per-account balances and the 10 most recent operations. Backend and frontend were built in parallel against the contract frozen indocs/account-summary-contract.md(copied verbatim from DJ-92), which is the single source of truth for both sides.Backend —
GET /api/account-summaryAuthenticated-only (anonymous →
401),AccountSummaryResource→AccountSummaryService(@Transactional(readOnly = true)).Aggregation is 4 fixed queries — no N+1 per account:
The repository methods return nested interface projections (
AccountBalanceProjection,RecentOperationProjection) rather than the service DTOs, because the project's ArchUnit rule forbidsrepository→servicedependencies;AccountSummaryServicemaps projections to DTOs.Contract invariants enforced in the DTOs, not the callers: monetary fields are
setScale(2, HALF_UP)in their setters,totalBalancedefaults to0.00, and the arrays default to empty so they are nevernullon an empty database.Frontend —
/dashboardLazy standalone component guarded by
UserRouteAccessService(anonymous SPA navigation redirects to login), reached from the navbar and a home-page link, all strings via i18n.DashboardServicefollows the existing service shape:Signals +
inject(); amounts via thecurrencypipe, dates via the sharedFormatMediumDatetimePipe; separate empty states for accounts (#no-accounts) and operations (#no-operations).The temporary mock used while the endpoint was being built in parallel is gone —
getSummary()always hits HTTP; onlyHttpTestingControllerand the component-level service stub remain, insidedashboard.spec.ts.Verification
Gates:
./mvnw verify(168 tests),./npmw test(404 tests),./npmw run lint,./mvnw -Pprod clean verify— all green.End-to-end against the running app with data seeded through the existing entity screens: total balance
$176,885.48matches the sum of the 12 accounts, operation count and per-account counts match, recent operations are date-desc and capped at 10, negative amounts render as-$54.20. Anonymouscurl /api/account-summary→401; anonymous/dashboard→ redirected to/login. Empty state is covered byAccountSummaryResourceITanddashboard.spec.ts.Before
After
Link to Devin session: https://partner-workshops.devinenterprise.com/sessions/207f4f91b2fc4bfba4446fddf35f5546
Requested by: @neilspalding-hub