53 Commits

Author SHA1 Message Date
Konrad du Plessis
e71109d27e docs: scrub SiteReport from CLAUDE.md + park rebuild (capture doc)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 02:11:37 +02:00
Konrad du Plessis
a502bac8ec docs: TDD plan for SiteReport removal (3 tasks, HARD STOP)
Task 1 revert attendance flow (TDD via 2 rewritten cross-ref tests),
Task 2 delete the SiteReport surface + 5 test classes + autogenerate
0018_delete_sitereport (suite 209->193), Task 3 docs. HARD STOP +
grep-clean/makemigrations-check gate before any push. Local-only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 01:27:40 +02:00
Konrad du Plessis
777c7c6dcc docs: SiteReport removal design + future-rebuild capture doc
Konrad-approved design to fully remove the SiteReport / "Log Today's
Work" feature (drop core_sitereport, no backup, revert post-attendance
to redirect-home). Capture doc preserves the schema-as-Python pattern,
the flow, recovery pointers, and rebuild guidance. Local-only; the
removal itself is HARD-STOPPED before push.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 01:23:09 +02:00
Konrad du Plessis
aaca0b36d3 docs: production caught up & verified (Manager/Salaried bundle live)
Konrad confirmed the 36-commit bundle "all working well" on prod
(17 May 2026). Flip CLAUDE.md + parked-work.md production status from
"deploy pending" to " fully caught up & verified at 80d96d7".
Also flags the in-progress (local-only) SiteReport removal.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 01:21:22 +02:00
Konrad du Plessis
80d96d7c91 docs: breadcrumb accuracy — Manager/Salaried bundle pushed (4c25011), deploy pending
Flip parked-work.md + CLAUDE.md from "paused, not pushed" to "pushed to
origin/ai-dev d7015b9..4c25011, Flatlogic VM deploy pending (migrate +
collectstatic + restart-last)". Prevents a fresh session reading stale
"not pushed" status.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 23:50:13 +02:00
Konrad du Plessis
4c250110e2 docs: note Pay Salary quick action (rides paused bundle)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 23:06:25 +02:00
Konrad du Plessis
56c10ab938 docs: TDD plan for Pay Salary quick action (2 tasks, HARD STOP)
Task 1: tile + deep-link hook + render test (TDD on the Django-render
part; auto-click is JS/manual-checklist). Task 2: docs. Suite 207->208.
Nothing pushed until Konrad's local verification.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 22:54:30 +02:00
Konrad du Plessis
fb19655a1d docs: design for Pay Salary dashboard quick action
Konrad-approved: a home-dashboard admin Quick Actions tile that
deep-links /payroll/?action=pay-salary and auto-clicks the existing
paySalaryBtn (then strips the param). Reuses all existing machinery;
no view/model/URL change. Rides the same paused-bundle HARD STOP.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 22:52:58 +02:00
Konrad du Plessis
b397cdf46c docs: note Salary auto-scope picker (rides paused bundle)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 22:31:28 +02:00
Konrad du Plessis
0c705129f6 docs: TDD plan for Salary auto-scope picker (2 tasks, HARD STOP)
2 small tasks: (1) toggleProjectField() Salary sync + _paySalaryOpen
re-apply, (2) docs. JS-only — manual-checklist verified, suite stays
207/207. Nothing pushed until Konrad's local verification.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 22:14:06 +02:00
Konrad du Plessis
8f443faebc docs: design for Salary auto-scope picker (filter + auto-untick)
Konrad-approved: when Add-Adjustment type=Salary, auto-set the pay-type
filter to Managers-only, hide daily rows, and untick any selected daily
worker so a Salary can never silently target a daily worker. Pure JS,
hooks the toggleProjectField() chokepoint. Rides the same HARD STOP.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 22:12:03 +02:00
Konrad du Plessis
0d77d7228d docs: note managers pay-type filter (rides with paused Manager/Salaried)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 14:05:34 +02:00
Konrad du Plessis
45871225e1 docs: TDD plan for Managers pay-type filter (4 tasks, HARD STOP)
4 bite-sized TDD tasks: (1) worker_list ?pay_type= view+tests,
(2) /workers/ dropdown, (3) Add-Adjustment modal data-pay-type +
client-side toggle, (4) docs. ~205/205 expected. Nothing pushed until
Konrad's local verification — rides with paused Manager/Salaried.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 13:17:39 +02:00
Konrad du Plessis
4aac2c1cf2 docs: design for Managers pay-type filter (Approach A, display-only)
Konrad-approved design for a display-only ?pay_type= filter on /workers/
and a "Managers only" toggle on the Add-Adjustment modal picker. No
model/migration/URL changes; rides with the paused Manager/Salaried
feature's HARD STOP (nothing pushed until local verification).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 13:13:30 +02:00
Konrad du Plessis
4d06b83e30 docs: correct Salary verification step (manual amount entry, not auto-filled)
Final whole-feature review flagged the design doc's verification
checklist step 4 over-promised an auto-filled amount. Manual entry is
intentional; corrected so Konrad's local verification expectations match
actual behaviour. Docs-only, local-only — feature still NOT pushed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 22:00:26 +02:00
Konrad du Plessis
61e1f1492c docs: document Manager/Salaried pay; park feature pending Konrad local verify + 2 follow-ups 2026-05-15 21:45:12 +02:00
Konrad du Plessis
482f88bb10 fix: add missing 0017 AlterField migration for Salary choice; correct plan premise 2026-05-15 19:28:58 +02:00
Konrad du Plessis
4dadb7cf23 docs: add Manager / Salaried Pay implementation plan (8 TDD tasks)
Task-by-task TDD plan: Worker.pay_type + migration, Salary additive
type, attendance/absence picker exclusions, add_adjustment Salary
branch, per-project salaried-cost report line + byte-for-byte
daily-numbers regression guard, UI, docs. Ends with a HARD STOP
before any push for Konrad's local verification.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 19:03:26 +02:00
Konrad du Plessis
325c59d4a1 docs: add Manager / Salaried Pay design (Approach A, approved)
Models a manager as a Worker with a pay_type discriminator, reusing the
existing loan/adjustment/payslip/payroll pipeline. New 'Salary'
adjustment type, project-attributed; managers excluded from
attendance/absence pickers so daily-worker math is provably untouched.
HARD STOP after implementation for local verification before any push.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 18:57:53 +02:00
Konrad du Plessis
9713b89ede docs: park post-attendance-flow-v2 (designed+planned, execution paused)
Konrad paused execution. parked-work.md now has a "⏸ Paused —
ready to execute" section pointing at the design (110545b) + plan
(29c36be) commits, with the resume instruction and the hard-stop
constraint. All 3 commits are local-only on ai-dev — nothing
pushed until Konrad verifies the flow locally.
2026-05-15 13:11:15 +02:00
Konrad du Plessis
29c36bede7 docs: post-attendance flow v2 implementation plan
4 small TDD tasks (~120 LOC): display rename, attendance 3-button
branch, Site Journal save+absences button, docs. Reuses Round C
next_action pattern. HARD STOP after Task 4 — local verification
by Konrad before any push (UX change to a daily-use path).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 13:05:48 +02:00
Konrad du Plessis
110545b11e docs: post-attendance flow v2 design
Replaces the forced post-attendance SiteReport redirect with 3
explicit buttons (Log Work → dashboard / + Site Journal / +
Absences) + a parallel "Save Site Journal + Add Absences" on the
journal page. Renames the user-facing "Site Report" → "Site
Journal" (display-only, Path-A; frees "Journal" for the parked
voice feature). Reuses the Round C next_action POST mechanism —
no model/migration/URL changes. NOT to be deployed until Konrad
verifies locally.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 13:02:18 +02:00
Konrad du Plessis
d7015b9210 docs: move journal/voice work to explicit backburner track
Konrad's decision (15 May 2026): Phase A.2 (manual JournalEntry
UI) + Phase B (Letterly inbound webhook) are too complex to
interleave with normal app work — they'll be built and tested
offline on a separate track, not in ai-dev.

Verified there is NOTHING to remove or bypass: zero JournalEntry
model/views/urls/templates, zero Letterly/webhook/@csrf_exempt
code anywhere on ai-dev, latest migration is 0015. The working
app was already 100% clean of journal/voice code — these features
never left the design-doc stage.

Doc changes:
- parked-work.md: "Blocked on Konrad's input" section replaced
  with "🧊 Backburner — separate offline track", with an explicit
  "do NOT start in ai-dev" warning and the nothing-to-remove
  verification recorded.
- CLAUDE.md breadcrumb: reframed from "parked pending Q5/Q7
  answers" (implies ready-to-go once answered) to "deliberately
  deferred to offline track — do not pick up as normal feature
  work".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 11:53:04 +02:00
Konrad du Plessis
5162db966a docs: production fully deployed at 1d224bc + capture deploy-ordering lesson
Production caught up — all 14 pending commits live after a
second service restart (the first restart ran before the code
reached the target commit; DEBUG=False's cached template loader
held the old templates until restarted again).

CLAUDE.md:
- 'What's mid-flight' breadcrumb: no longer says pending deploy;
  now states production is at 1d224bc and fully live.
- Flatlogic Deployment section: new '⚠ DEPLOY ORDERING' bullet
  documenting that production runs DEBUG=False → cached template
  loader → restart MUST come after the pull, and template-only
  changes still need a restart (unlike DEBUG=True local dev).
  Includes the symptom ('git log shows right commit but page
  looks old') and the fix (restart again).
- Bumped the {# #} bit-us count + added a grep sanity-check
  one-liner (from the prior commit, retained).

parked-work.md: 'Pending pull-and-restart' section replaced with
'Production status — fully caught up'.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 11:29:26 +02:00
Konrad du Plessis
652168fe88 docs: capture dashboard/report audit pass landing
CLAUDE.md breadcrumb: '6 subsequent commits' → '13 subsequent
commits' with a one-paragraph summary of what's pending pull +
restart on production. Points at parked-work.md for the full
commit table.

parked-work.md:
- 'Pending pull-and-restart' table: added 18c75b2 (calendar
  month) and the 2e6b78d→c02edce audit-pass range as a single
  collapsed entry.
- 'Recently shipped' grew a detailed entry for the 18-finding
  audit pass at the top.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 02:15:53 +02:00
Konrad du Plessis
9bd0e8541d docs: capture absence polish-pass landing + refresh deploy counter
CLAUDE.md breadcrumb: 'subsequent UX polish' → '6 subsequent
commits' so the next session can see at a glance how much is
pending pull-and-restart on production.

parked-work.md:
- 'Small polish follow-ups' section: 7 items cleared on 15 May;
  section header retained as a landing pad for future cleanups.
- 'Pending pull-and-restart' table: added rows for 70fa085
  (day-name in modal) and d1d3e15 (polish pass) so the deploy
  checklist is current.
- 'Recently shipped' grew two new entries at the top: the polish
  pass and the day-name modal change.
2026-05-15 01:11:13 +02:00
Konrad du Plessis
bde6f24bb1 docs: refresh CLAUDE.md + parked-work for 15 May session wins
CLAUDE.md changes:
- 'What's mid-flight' breadcrumb updated: SiteReport/Absences
  migrations are LIVE on prod; only the 4 latest UX commits await
  a pull-and-restart (no migration / collectstatic needed).
- URL Routes table entries for /workers/ and /history/ now document
  the new ?team= filter (and team=none for unassigned / no-team cases).
- Worker Management UI inline description mentions the team filter
  + Absences tab on the worker detail page.
- Two new Coding Style gotchas captured: (1) Bootstrap dropdowns
  inside .card elements get clipped by sibling cards — fix is to
  lift the wrapping card with position:relative + z-index;
  (2) JS reading from data-worker-id was unreliable on production —
  read input[name="workers"][value] directly (the attendance-form
  pattern that's been working for years).

parked-work.md changes:
- Pending-deploy section rewritten: the BIG deploy (migrations +
  collectstatic) is DONE; only 4 small commits await a pull +
  service restart.
- 'Recently shipped' grew two new entries: the team filters on
  /workers/ + /history/, and the two absences UX polish fixes.
- Updated timestamp to 15 May 2026.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 00:50:47 +02:00
Konrad du Plessis
7d4d7b1f8b docs: park the production deploy step + rotate parked-work queue
Worker Absences feature shipped (bf6f0a5..27fe05e), so it's no
longer the active queue item. Promoted the pending production
deploy (run /run-migrate/, collectstatic, restart service) to the
top of parked-work.md — production /history/ is 500ing until those
migrations run. CLAUDE.md breadcrumb updated to flag this as the
next operator action when a fresh session starts.

Also captured the small polish follow-ups from the absences code
reviews (AbsenceQuickForm dead code, N+1 in team_workers_map,
duplicated CSV filter block, etc.) so they don't get lost in a
future janitorial pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 23:43:32 +02:00
Konrad du Plessis
f146af0e35 docs(absences): task-by-task implementation plan
7 tasks + 1 mid-flight checkpoint after Task 5 (CRUD complete).
Each task is TDD: failing test → minimal impl → verify pass →
commit. Target ~38 new tests, ~1700 LOC. Skipped doctor's note
upload (Q7 decision). Risks flagged: OneToOneField SET_NULL
drift, atomic-failure path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 19:04:43 +02:00
Konrad du Plessis
08f312f6e3 docs(absences): worker-absence-records feature design
Captures the 7-Q brainstorm: 8 reasons (Sick / Family Resp /
Annual / Personal-Unpaid / IOD / Suspension / Absconded / Other),
"Paid" checkbox default-off that auto-creates a Bonus
PayrollAdjustment, standalone /absences/log/ form + ✗ quick-action
on the attendance form, separate-page conflict warning with
per-row Remove-from-WorkLog checkboxes, supervisor-scoped
permissions, Level-1 YTD totals on the worker detail page, +3
polish items (dashboard alert, Absences tab, CSV export).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 18:14:43 +02:00
Konrad du Plessis
69c81a4092 docs: add parked-work index for session handoffs
Captures the deferred work (Phase A.2 manual JournalEntry UI,
Phase B Letterly webhook) and queues the next brainstorm topic
(worker absence records). Adds an 8-line breadcrumb at the top
of CLAUDE.md so a fresh session sees it in the first 20 lines.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 17:30:29 +02:00
Konrad du Plessis
bfe4e4d616 docs(ui): design for payroll action-buttons pastel soft-fill
Four buttons at top of /payroll/ currently mix 3 treatments (outline
+ solid btn-primary one-off). Design swaps all 4 to a unified
.btn-action-soft base class with per-button colour modifiers
(Lookup=blue, Pay=amber, Add=green, Price=mauve). Reuses existing
--badge-*-bg tokens for the Add + Price buttons; adds 2 new token
pairs for Lookup + Pay. Removes the shadow-sm / btn-sm / fw-bold
one-offs — the new class handles sizing + weight.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 11:07:37 +02:00
Konrad du Plessis
84e9d247be docs(ux): task-by-task plan for UX Polish Pass
Five tasks: (1) docs/design-tokens.md as the canonical colour
reference; (2) CLAUDE.md UI-vs-DB naming-drift note (ships BEFORE
the rename so it's searchable from minute one); (3) display-only
TYPE_CHOICES rename + auto-migration + template visible-text swap
to get_type_display; (4) badge colour unification on Pending +
History tabs + loan-flag recolor; (5) CSS root-cause fix for the
group-summary narrow-wrap bug (move display:flex from <tr> to <td>).

Execute via subagent-driven-development. Auto mode — no mid-execution
checkpoints.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 09:36:51 +02:00
Konrad du Plessis
9aba9b8fb8 docs(ux): design for UX Polish Pass
Four UX asks bundled in one pass:

1+2. Display-only rename of adjustment types: 'New Loan' (DB) →
     'Loan' (UI), 'Advance Payment' → 'Advance', 'Advance Repayment'
     → 'Advance Repaid'. DB values preserved forever — zero data
     migration, zero formula / constant / CSS / test changes.
3. Unify badge colours across all payroll tabs using the existing
   .badge-type-* semantic palette. Recolour Pending "With loans"
   flag to match the Loan type colour.
4. Fix CSS bug in .adj-group-meta (margin-left:auto doesn't work
   in a <td> — make the td a flex container).

Plus: new docs/design-tokens.md as the canonical colour reference,
and a crucial CLAUDE.md section documenting the UI-vs-DB naming
drift so future Claude sessions don't chase ghosts when writing
formulas / filters / ORM queries that reference the display label
instead of the DB value.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 09:32:23 +02:00
Konrad du Plessis
bcd0112687 docs(perf): task-by-task plan for Quick-Wins Pass A
Four tasks: mtime cache-bust token + tests; install & gate Django
Debug Toolbar dev-only; profile + fix N+1 on /; profile + fix N+1 on
/payroll/ (all four tabs) with before/after summary in the final
commit message.

Execute via subagent-driven-development. Auto mode — no mid-execution
checkpoints.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 00:26:42 +02:00
Konrad du Plessis
d1490c4639 docs(perf): design for Quick-Wins Pass A
Short design covering four changes: mtime-based CSS cache-bust token,
Django Debug Toolbar (dev-only) for profiling, N+1 fixes on Dashboard
and Payroll pages, and a before/after measurement in the commit message.
Scope is deliberately tight — plan B (template splitting) and plan C
(full audit) are deferred until plan A evidence lands.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 00:23:48 +02:00
Konrad du Plessis
620f433d06 docs(adjustments): design for filter-bar v2 (pill unification + density) 2026-04-23 21:54:13 +02:00
Konrad du Plessis
269d86259a docs(adjustments): Shipped block on design doc + CLAUDE.md URL routes
Captures the 11-task implementation, 5 deviations (biggest: the
CP1 pivot from Choices.js chip-multiselect to popover-checkbox
filter UX after Konrad flagged the chip pattern as intrusive),
14 new adjustments-tab tests, and total code churn (~+1400 lines).

CLAUDE.md URL Routes table gains two rows so future sessions
surface /payroll/?status=adjustments and the bulk-delete endpoint.

Feature ready for final whole-feature code review + batched push.
2026-04-23 19:26:46 +02:00
Konrad du Plessis
cf82215511 docs(adjustments): add task-by-task implementation plan
11 tasks + 1 hard-pause checkpoint after Task 4. Targets ~960 LOC
across core/views.py, payroll_dashboard.html, _adjustment_row.html
(new), format_tags.py, custom.css, and tests.py.

Derived from docs/plans/2026-04-23-adjustments-tab-design.md (commit
12edafa) — execution plan for subagent-driven development.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 14:52:06 +02:00
Konrad du Plessis
54080a3e0a docs(inline-filters): append Shipped 2026-04-23 block to design doc
Captures the 6 deviations from the original design (each with driving
feedback + commit SHA), the 5 non-design polish commits, and the test
delta (42 → 47 passing). Keeps the design doc as the first-read for
understanding the feature while preserving decision history from the
Checkpoint-1 iteration.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 14:40:13 +02:00
Konrad du Plessis
124b3f61b6 Plan: Inline Filters (pill-as-dropdown) implementation
Task-by-task plan for the design at 30d0991. 6 tasks, 1 checkpoint
after Task 4 (all pill interactions demoable, modal still as fallback).

Tasks:
1. Backend: project_team_pairs_json context + 2 tests
2. Template: popover shells + Apply button + json_script embeds
3. CSS: pill-editable, pill-dirty, popover, apply-group, toast (~150 lines)
4. JS: pill-popover interactive module (~300 lines, scoped IIFE)
   --- CHECKPOINT 1 ---
5. Retire modal: delete _report_config_modal.html, update index + report
   templates, keep backend context keys (still used by pill markup)
6. QA + shipped note

Scope: ~480 LOC net added (not the ~330 estimated — JS came out larger
once written with proper state management + cross-filter). Tests grow
42 -> 44. One new CDN-loaded library? No — Choices.js already loaded
from Executive Report v2. Zero model changes, zero migrations.

Noted trade-off in Task 5: selected_project_ids / selected_team_ids
context keys were KEPT despite design doc suggesting removal — the
pill popovers still use them for pre-selection + URL-diff init. Only
the modal markup was retired.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 09:31:49 +02:00
Konrad du Plessis
12edafa441 Design: Payroll Adjustments Tab on the payroll dashboard
Second brainstorm output of the day. New tab alongside Pending /
History / Loans & Advances (the URL pattern already established at
?status=pending|paid|loans — this slots in at ?status=adjustments).

Key decisions:
- Semantic badge palette: 5 colour categories mapped across 7 types.
  Loan/advance repayments get +15% saturation — same family, hotter
  signal for "money coming back" vs "money going out".
- Three multi-select filters (Type, Workers, Teams) via Choices.js.
  Teams cross-filter Workers using JSON pair map (mirrors Feature 1's
  project<->team pattern). Auto-remove invalid selections with toast.
- Single-date default with optional range toggle; presets for
  Today / This week / This month.
- Sticky filter bar; sortable columns (Date / Worker / Amount / Status).
- Group-by toggle: Flat / By Type / By Worker. Collapsible group
  headers show count + net sum per group (+R additive / -R deductive).
- Bulk action bar (floating) for multi-row delete on unpaid rows only.
  New endpoint POST /payroll/adjustments/bulk-delete/ filters
  payroll_record__isnull=True for safety.
- Inline row actions reuse existing modals: Preview (unpaid) /
  View Payslip (paid) / Edit + Delete (unpaid). Zero new modal code.
- Empty state, keyboard Esc, URL state for everything (bookmark-safe).

Scope: ~960 lines, ~12 tasks, 2 checkpoints. Uses existing
#addAdjustmentModal / #editAdjustmentModal / #payslipPreviewModal
already on payroll_dashboard.html — zero duplication.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 09:26:01 +02:00
Konrad du Plessis
30d0991956 Design: inline filters on report page (+ cross-filter)
Brainstorm output — Konrad's Checkpoint-3 UX request, now spec'd.

Key decisions:
- Pill-as-dropdown: existing filter pills become clickable popovers
- Explicit Apply button; hidden when no pending changes
- Modal retired; dashboard 'Generate Report' becomes a plain link
- Bidirectional cross-filter: selecting a project hides teams that
  haven't worked on it (and vice versa). Strict behaviour with
  auto-removal of now-invalid selections + toast notice.
- URL contract unchanged; PDF download unchanged (still uses
  current querystring).

One new context key (project_team_pairs_json) serialises distinct
(project_id, team_id) pairs from WorkLog for client-side cross-filter.
~80 CSS lines for popover + dirty state + toast; ~150 JS lines for
one scoped module (createElement + textContent, XSS-safe).

Scope: 5-6 focused tasks, 1 checkpoint.
Next step: Feature 2 brainstorm (Payroll Adjustments Browser) before
handing both to writing-plans.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 02:06:49 +02:00
Konrad du Plessis
3dab09cea3 Docs: mark Executive Report v2 as shipped (23 Apr 2026)
QA summary:
- 42/42 tests pass
- manage.py check clean
- No pending migrations
- Route sanity: /report/, /report/?project=1&project=2, /report/pdf/ all
  resolve (302 as anon, 200 as admin)
- PDF generation verified for populated and empty date ranges

Appends a "Shipped" block to the design doc that captures the final
QA state, the deferred items, and the notable design decisions made
during implementation. Konrad's inline-filter UX improvement (raised
during Checkpoint 3) is explicitly flagged for a future brainstorm.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 00:18:48 +02:00
Konrad du Plessis
e2eb889a29 Plan: Executive Payroll Report v2 implementation
Task-by-task plan for the design committed at 27cdb46. 14 tasks with
4 hard-pause checkpoints at natural demo points:
  - After Task 6  (backend helpers done)
  - After Task 8  (multi-select modal + filter pills)
  - After Task 12 (full HTML layout — all 4 chapters)
  - After Task 14 (PDF mirrored + QA + shipped note)

Task 1 is a pure refactor (extract _compute_outstanding from index())
so later tasks can reuse the dashboard math with filters. Tasks 2-5
add the new helpers alongside existing code with failing-test-first
discipline. Task 6 switches the main helper to multi-value filters
(project_ids/team_ids) — existing behaviour preserved via backward-
compatible getlist. Tasks 7-12 restructure the HTML template into
Hero + 4 chapters. Task 13 mirrors in the PDF. Task 14 QAs and ships.

~11 new tests across 4 test classes; total grows from 28 to ~39.

One new dependency: Choices.js 10.2.0 via CDN, admin-only gated,
graceful fallback to native multi-select on CDN failure.

Follows the CLAUDE.md conventions: # === SECTION === comments,
plain-English docstrings, subquery-filter pattern for M2M filters,
single-batched push at the end, Co-Authored-By trailer on every
commit, never amend.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 21:45:31 +02:00
Konrad du Plessis
27cdb46ec9 Design: Executive Payroll Report v2
Brainstorm output for rebuilding /report/ as an executive-grade dashboard.

Key decisions captured:
- Multi-select filters (Choices.js) with empty=all semantics
- Hero KPI band: Paid / Outstanding NOW / Avg R/day / Avg R/month
- Chapter I: Lifetime context with working-day denominator for avg cost
- Chapter II: Selected period (existing content, restructured)
- Chapter III: Worker breakdown (existing, restyled)
- Chapter IV: NEW team × project activity pivot

Current Outstanding reuses dashboard math (live, stamped with generation
time). Company cost velocity = lifetime cost / distinct work-log dates;
monthly = daily × 30.44.

No model changes. One new CDN dep (Choices.js). Target: ~650 LOC
including ~120 new tests. Four checkpoint pauses proposed for the
subsequent implementation plan.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 21:38:26 +02:00
Konrad du Plessis
6d37d1ba9b Task 10: add Task 3 full-payload test + mark design doc as shipped
Adds a consolidated regression test to WorkLogPayrollAjaxTests that
exercises: paid worker serialization shape, null team branch, OT flag
in JSON, full_page_url value, and adjustment payslip-link serialization.
Closes the 'Important' coverage gap flagged in Task 3's quality review.

Also appends a 'Shipped' block to the design doc summarising QA
status and capturing all five deferred nits (admin-gate consistency,
template branch tests, |default:0 redundancy, admin-gate expression
readability, background vs background-color) so they survive the
merge into project history.

All 19 tests pass. manage.py check clean. No migrations needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 18:23:24 +02:00
Konrad du Plessis
0ec3f66739 Plan: work log -> payroll cross-link implementation plan
Task-by-task plan for implementing the modal + /history/<id>/ page
designed in the companion design doc. 10 tasks, 4 hard-pause review
checkpoints (after tasks 2, 4, 6, 10). TDD for the pure helper
function (bootstraps the currently-empty core/tests.py), view-level
tests for the AJAX + detail endpoints, manual smoke tests for the
template/JS work.

Uses the existing worker_lookup_ajax JSON+DOM pattern for the modal
(createElement + textContent, not innerHTML) to match the codebase's
XSS-safe convention. Full page is server-side rendered via a Django
template.

No model changes. No migrations. Admin-only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 13:34:21 +02:00
Konrad du Plessis
1c00ba2628 Design: work log -> payroll cross-link (modal + /history/<id>/ page)
Brainstorm output for the next UI refinement. Adds a click-through from
any historic work log (Work History, team detail Recent Work Logs, project
detail Recent Work Logs) to a compact modal showing paid/unpaid status per
worker, with links out to /workers/<id>/ and /payroll/payslip/<pk>/. The
modal has a "Open full page" button that navigates to a new
/history/<log_id>/ route for bookmark-able detail + pay-period context
(via get_pay_period). Admin-only; supervisors unchanged.

Read-only pass; no model changes, no migrations. Uses existing data:
PayrollRecord.work_logs (M2M) and PayrollAdjustment.work_log (FK).

Also fixes local dev: run_dev.bat now sets DJANGO_DEBUG=true so runserver
auto-serves /static/ (prior behaviour: CSS 404 on localhost because
Django's dev server only serves static files when DEBUG=True; production
keeps DEBUG=false and is served by Apache, so unaffected).

Design doc: docs/plans/2026-04-22-work-log-payroll-crosslink-design.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 13:23:33 +02:00
Konrad du Plessis
3c28387dd3 WIP: 2026-04-22 session checkpoint
Complete working state of the session. Will be split into two deploy
phases (safety scaffolding then feature release) before merging to ai-dev.

Includes:
- Security fixes (email creds / SECRET_KEY / DEBUG / CSRF)
- Backup + restore management commands and browser endpoints
- WeasyPrint migration (replaces xhtml2pdf)
- New Worker fields + WorkerCertificate + WorkerWarning models
- Worker / Team / Project friendly management UIs
- Dashboard cert-expiry card + Manage All buttons
- Bootstrap tooltips (global init + theme-aware CSS)
- Django admin template override (taller M2M pickers)
- Money filter for ZAR currency formatting
- Resources dropdown nav
- Massive CLAUDE.md expansion + deploy plan docs

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 00:19:15 +02:00