Commit Graph

126 Commits

Author SHA1 Message Date
Bastian Wagner
145ebb924a docs: add implementation plan for team creation via UI
Task-by-task plan covering the loosened create-team role guard,
auto-captain membership on creation, the new TeamsApi/MyTeamsStore
methods, the CreateTeamDialog component, and wiring it into
team-select.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 15:14:47 +02:00
Bastian Wagner
560fcfc11a docs: add design spec for team creation via UI
Brainstormed with the user: any logged-in user should be able to
self-service create a team and becomes its captain, via a dialog on
team-select. Team deletion/archiving is scoped out as a separate
follow-up feature.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 15:03:59 +02:00
Bastian Wagner
84bab04523 fix export type 2026-08-03 15:01:49 +02:00
Bastian Wagner
b21641f37a ag grid 2026-08-03 14:49:35 +02:00
Bastian Wagner
71d76725a4 euro symbol 2026-08-03 11:40:42 +02:00
Bastian Wagner
862a1bea8d Merge branch 'worktree-theoretischer-kassenstand' 2026-08-03 11:32:36 +02:00
Bastian Wagner
3cb8cd9a4a fix: strengthen deactivation-exclusion test and align sign rule with canonical logic
- teams.service.spec.ts: pick a checkpoint older than the adjustment's own
  month so the exclusion test actually fails without the exclusion filter
- teams.service.ts: only negate fine/levy/fee amounts when positive,
  matching TeamMembersService.recomputeBalance and Transaction.setBalance()
  exactly, instead of negating unconditionally
- teams.service.ts: outstanding-history helper now returns a positive
  value when players owe money, matching the house convention already
  established by getOverview()'s team.outstanding
- overview.spec.ts: assert the balance chart's legend becomes visible
- teams.service.spec.ts: add coverage for inactive-player exclusion and
  a positive-balance (prepaid credit) case

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 11:24:34 +02:00
Bastian Wagner
3d774a3455 overflow 2026-08-03 11:16:15 +02:00
Bastian Wagner
ebfaac7590 feat: show theoretical balance line in the cash-balance chart
Adds a second, dashed line to the existing balance-history chart that
includes currently open player dues, so managers can see at a glance
how far the actual cash balance lags behind what has been pledged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 11:05:11 +02:00
Bastian Wagner
d8f13d674d refactor: extract shared backward-reconstruction logic
Extract the month-by-month backward-walk algorithm (used for both
team-level cash balance and player-level debt history) into a single
shared private helper `reconstructBackward()`. This eliminates code
duplication while preserving behavior:

- Team-level balanceHistory: maps movements through signedFlowAmount(),
  rounds each point, calls the shared helper
- Player-level balance history: maps transactions using type.id rule,
  skips rounding (only rounds at final merge to avoid compounding
  errors), calls the shared helper

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 10:58:48 +02:00
Bastian Wagner
1b6ce57fbf feat: add theoretical balance history to team overview stats
Reconstructs each active player's balance per month (same backward
technique as the existing cash-balance history) so the overview stats
endpoint can report what the team balance would be if all currently
open dues had already been paid.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 10:44:22 +02:00
Bastian Wagner
5f619d649c docs: add spec and plan for theoretical cash balance line
Recreated from the main checkout, where these were committed to local
master but not yet pushed and thus missing from this fresh worktree.
2026-08-03 10:31:53 +02:00
Bastian Wagner
fd850f372f docs: add design spec for theoretical cash balance line in overview chart
Adds a second historical line to the existing cash-balance chart showing
what the balance would be if all outstanding player dues were paid,
reconstructed per month the same way the existing balance line is.
2026-08-03 10:21:06 +02:00
Bastian Wagner
27ab505aba berechtigungen 2026-08-03 10:16:42 +02:00
Bastian Wagner
6eeaa3a624 Merge branch 'feature/cash-flow-presentation'
# Conflicts:
#	myteamwallet_frontend_modern/src/app/features/team/cashbox/cashbox.ts
#	myteamwallet_frontend_modern/src/app/features/team/overview/overview.spec.ts
#	myteamwallet_frontend_modern/src/app/features/team/overview/overview.ts
2026-08-02 09:49:30 +02:00
Bastian Wagner
26391b5b2c Merge branch 'feature/manager-guide' 2026-08-02 09:25:09 +02:00
Bastian Wagner
367533f1f5 fix: make cash flow amounts fully accessible 2026-08-02 09:22:39 +02:00
Bastian Wagner
0e8ac74116 feat: add manager guide and contextual help 2026-08-02 09:22:16 +02:00
Bastian Wagner
a94caed85f Merge branch 'worktree-kasse-kpi-charts' 2026-08-01 21:49:07 +02:00
Bastian Wagner
e2f271fd35 fix(teams): gate empty-state and add membership check to overview stats
Whole-branch review findings:

1. balanceHistory/monthlyFlow always returned 12 entries, even for a
   brand-new team with zero transactions, so the frontend's empty-state
   (gated on .length === 0) could never fire for a real "no movements yet"
   team. Now returns empty arrays when there are no relevant movements at
   all (not just none in the last 12 months, so a team with older-but-real
   history still gets a flat chart). Also added the same defensive
   `?? []` guard on players/transactions that getOverview already has, so a
   team with no players/relations loaded doesn't throw.

2. GET :id/overview/stats had no team-membership check -- any logged-in
   user (RoleEnum.user is the default role) could read any other team's
   financial stats by iterating ids. Injected TeamAccessService into
   TeamsService (already a sibling provider in TeamsModule, no module
   wiring needed) and call assertMember(actorUserId, teamId) as the first
   line of getOverviewStats, threaded from the controller via @Req(). Read
   access only (assertMember, not assertManager), matching who can already
   view the overview page. Sibling routes with the same pre-existing gap
   were left untouched, per review scope.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 21:41:54 +02:00
Bastian Wagner
1058d641e7 fix(teams): anchor balanceHistory to team.balance instead of forward-summing
Manual verification against real data (Task 3) found balanceHistory drifted
from team.balance for real teams, since team.balance carries historical
adjustments (e.g. from the removed legacy backend) that don't trace back to
the current payment/credit/expense rows. Forward-summing those rows from
zero could never be trusted to tie out.

Rewrite balanceHistory to anchor on team.balance (the authoritative current
value) and walk the movements backward, newest to oldest, undoing each one
to reconstruct earlier month-end balances. This guarantees the most recent
point equals team.balance by construction, and is mathematically identical
to the old forward sum for teams whose movements fully explain their
balance. monthlyFlow/topOutstanding are unaffected and left as-is.

Updated teams.service.spec.ts to use a fixture where team.balance
intentionally does not equal the sum of its own movements, so the tests
actually exercise the drift-handling behavior instead of a case where
forward-sum and backward-anchor happen to coincide.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 21:02:32 +02:00
Bastian Wagner
f2e6704943 feat: use cash flow presentation in transaction histories 2026-08-01 20:58:22 +02:00
Bastian Wagner
41a557f2c9 test(overview): dedupe the MockChart test double into a shared helper
The vi.mock('chart.js', ...) MockChart class was copy-pasted verbatim
between chart-canvas.spec.ts and overview.spec.ts. Extract it to
shared/chart-canvas/testing/mock-chart.ts and import it via
vi.hoisted(async () => import(...)) in each spec, since vi.mock's
factory is hoisted above regular imports and can't reference a
plain top-level import.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 20:33:22 +02:00
Bastian Wagner
435b8d5c53 feat(overview): add KPI charts to team overview page
Adds three chart.js-backed KPI cards (Kassenstand-Verlauf, Einnahmen &
Ausgaben, Top-10 offene Beitraege) to the existing Uebersicht page,
consuming the new GET teams/:id/overview/stats endpoint via a new
TeamStatsApi service. Introduces a small reusable ChartCanvas shared
component that wraps the Chart.js instance lifecycle via @Input()/
ngOnChanges, following this codebase's existing input-decorator
convention rather than effect().

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 20:21:50 +02:00
Bastian Wagner
239b157015 feat: add team cash flow amount presentation 2026-08-01 20:16:09 +02:00
Bastian Wagner
4e6b945eec docs: define team cash flow presentation 2026-08-01 19:48:50 +02:00
Bastian Wagner
ecb6fd4394 feat(teams): add overview stats endpoint for KPI charts
Adds GET :id/overview/stats + TeamsService#getOverviewStats, aggregating
team-wallet and player payment transactions into a 12-month balanceHistory
(cumulative, carry-forward), monthlyFlow (income/expense), and topOutstanding
(top 10 active debtors) for the upcoming overview KPI charts. fine/levy/fee
and player-level credit are excluded, matching the "Ist-Kasse" cash-flow rule.

Replaces the unmodified NestJS-boilerplate placeholder specs for
TeamsService/TeamsController (which already failed at baseline) with real
tests using the team-access.service.spec.ts direct-construction convention.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 19:44:49 +02:00
Bastian Wagner
6eab6251d5 fehlerhafte tests entfernt 2026-08-01 19:44:07 +02:00
Bastian Wagner
bf1cef961a icon2 2026-08-01 19:22:39 +02:00
Bastian Wagner
369d556a8b icon 2026-08-01 19:20:19 +02:00
Bastian Wagner
727ff0b1af icon 2026-08-01 19:17:25 +02:00
Bastian Wagner
c1238929ef docs: add implementation plan for cashbox KPI charts
Approved plan for the three overview charts (balance history, monthly
income/expense, top-10 outstanding players): new backend aggregation
endpoint plus a chart.js-based frontend integration on the existing
overview page.
2026-08-01 19:13:56 +02:00
Bastian Wagner
b6f311b11b docs: add design spec for cashbox KPI charts on team overview
Brainstormed with the user: three charts on the existing overview page
(balance history, monthly income/expense, top-10 outstanding players),
Chart.js as dependency-free charting lib, new backend aggregation
endpoint since none of the existing endpoints group transactions by
time or category.
2026-08-01 19:05:00 +02:00
Bastian Wagner
5dae4362b2 feat(cashbox): book a catalog penalty directly as a transaction
Adds a catalog picker to the member-booking form in the cashbox (prefills
amount/note/type, stays editable) and a "Buchen" button on each penalty
catalog entry that jumps to the cashbox with that entry preselected via a
penaltyId query param. No backend changes — reuses the existing POST
/transactions flow, the catalog only supplies starting values.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 18:50:58 +02:00
Bastian Wagner
9664187049 altes backend entfenrt 2026-08-01 15:45:49 +02:00
Bastian Wagner
3551641a85 feat(teams): manage player active status and team-role with treasurer safeguard
Team managers (captain and above) can now deactivate/reactivate a player and
change their team-role from the player detail page. Deactivation zeroes the
open balance via an auditable adjustment transaction instead of overwriting
the balance field, and both actions are blocked if they would leave a team
without an active treasurer. Also hardens the existing PUT teams/:id/players
endpoint down to profile-only fields, fixing a typo bug and closing a gap
where any authenticated user could mutate a player's active/role/balance in
any team.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 15:42:09 +02:00
Bastian Wagner
2424a8c025 Merge branch 'feature/penalty-catalog-management' 2026-08-01 15:03:07 +02:00
Bastian Wagner
c7dfdd7498 fix: address penalty catalog review findings 2026-08-01 14:46:58 +02:00
Bastian Wagner
fa05e55d43 feat: manage penalty catalog in modern frontend 2026-08-01 13:32:22 +02:00
Bastian Wagner
17228a52db feat: secure penalty catalog management 2026-08-01 13:17:44 +02:00
Bastian Wagner
4c1bd49405 fixes 2026-08-01 13:17:26 +02:00
Bastian Wagner
45658e42fa docs: add penalty catalog management plan 2026-08-01 12:52:07 +02:00
Bastian Wagner
e3bff40181 Merge branch 'feature/admin-user-management' 2026-08-01 11:50:27 +02:00
Bastian Wagner
945369796e fix: refresh admin self profile state 2026-08-01 11:45:03 +02:00
Bastian Wagner
431eba86e7 fix: align admin profile request validation 2026-08-01 11:20:47 +02:00
Bastian Wagner
d962200b79 test: cover assignment failure recovery 2026-08-01 10:52:17 +02:00
Bastian Wagner
9eec6268d0 fix: lock directory during assignment changes 2026-08-01 10:44:17 +02:00
Bastian Wagner
9dc9dc3dcf fix: stabilize admin user UI state 2026-08-01 10:32:51 +02:00
Bastian Wagner
3ae0fd2000 feat: build admin user management UI 2026-08-01 10:01:25 +02:00
Bastian Wagner
1288f5fc60 fix(mail): resolve templates from __dirname so they exist in the built image
The Docker runtime image only ships dist/, but mail-config.service.ts
pointed at src/mail/mail-templates and nest-cli.json never copied the
.hbs files into dist/ either. This was silently masked before because
the return-before-sendMail bug meant the path was never touched; fixing
that bug now surfaces it as a hard crash on boot (readFileSync throwing
synchronously inside the MailerModule factory). Resolve the templates
dir from __dirname instead, which is correct in both dev (src/mail) and
the compiled image (dist/mail), and add the mail-templates .hbs files
to nest-cli.json's asset copy list so they actually land in dist/.
2026-08-01 09:27:44 +02:00