diff --git a/CLAUDE.md b/CLAUDE.md index f9a38ac..8215693 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,12 +1,19 @@ # FoxFitt LabourPay v5 ## What's mid-flight — read this first -**Parked / deferred work:** see `docs/plans/parked-work.md` for the -short list of features that are designed, half-built, or blocked on -Konrad's input. The active next-up brainstorm topic is **worker -absence records** (leave / sick / AWOL tracking). Phase A.2 (manual -JournalEntry UI) and Phase B (Letterly inbound webhook) from the -Site Work Logging design are parked pending Q5 / Q7 answers. +**Parked / deferred work:** see `docs/plans/parked-work.md`. + +**⚠ Operator action pending:** SiteReport (`0013`) + Absences (`0014` ++ `0015`) migrations need to run on production. Visit +`https://foxlog.flatlogic.app/run-migrate/` once + ask Gemini to +run `collectstatic` + restart `django-dev.service`. The /history/ +page is currently 500ing on production until this is done — see +parked-work.md "Production deploy" section for the full sequence. + +Phase A.2 (manual JournalEntry UI) and Phase B (Letterly inbound +webhook) from the Site Work Logging design are parked pending Q5 / Q7 +answers. The Worker Absences feature shipped on 14 May 2026 (commits +`bf6f0a5` → `27fe05e` on `ai-dev`). ## Coding Style - Always add clear section header comments using the format: # === SECTION NAME === diff --git a/docs/plans/parked-work.md b/docs/plans/parked-work.md index 6d8a568..7766b48 100644 --- a/docs/plans/parked-work.md +++ b/docs/plans/parked-work.md @@ -1,60 +1,67 @@ # Parked / deferred work -> Updated 14 May 2026. A small index of features that are designed, -> half-built, or blocked on input — but **not** the active priority. -> When a fresh session opens, glance here first to see what's +> Updated 14 May 2026 (late evening). A small index of features that +> are designed, half-built, blocked on input, or pending an operator +> step. When a fresh session opens, glance here first to see what's > already on the workbench. --- -## Active queue +## ⚠ Needs operator action (production) -### Worker absence records (NEW — to brainstorm) +### Production deploy of SiteReport + Absences (pending Konrad) -**Status:** Not yet brainstormed. Requested by Konrad in the -session that shipped Site Report Phase A.1. +**Status:** All code committed and pushed to `origin/ai-dev` (HEAD +`27fe05e` as of 14 May 2026 late evening). Production at +`https://foxlog.flatlogic.app/` has pulled the new code but is +crashing on `/history/` with: -**One-line description:** Per-worker leave / sick / AWOL records, -separate from the implicit "not in a WorkLog" state. Likely mirrors -the `WorkerWarning` / `WorkerCertificate` pattern (per-worker, dated, -reason, optional document upload). +``` +ProgrammingError: (1146, "Table 'app_38686.core_sitereport' doesn't exist") +``` -**Recommended next action:** New session → run -`/superpowers:brainstorm` with the prompt: +**Why:** Flatlogic auto-pulled the new code but didn't run migrations. +The new template logic references `log.site_report`, which queries a +table that doesn't exist yet on the production MySQL. -> "Worker absence records — should mirror the WorkerWarning pattern -> (per-worker, dated, optional doc). Need to define absence TYPES -> (paid leave / sick / AWOL / family responsibility / unpaid leave / -> public holiday / suspension), how absences show on -> /history/ and worker detail pages, and whether each type affects -> payroll calculations (paid leave should still generate a daily-rate -> amount; AWOL should not)." +**The fix (~2 minutes total):** -**Things to consider in the brainstorm:** -- **Type taxonomy.** Paid leave, sick leave, AWOL, family - responsibility, unpaid leave, public holiday, suspension. Each - has different payroll implications. -- **Payroll integration.** Does a "paid leave" absence auto-generate - a PayrollAdjustment (bonus-style, equal to one daily rate) on the - worker for that day? AWOL should NOT. Public holidays — depends - on SA labour law / FoxFitt policy. -- **UI placement.** Worker detail page tab (sibling to Certifications - and Warnings)? A tab/filter on `/history/`? A standalone - `/absences/` list? -- **Bulk entry.** Mark a whole team absent for a public holiday in - one form submission. Save a click per worker. -- **Document upload.** Doctor's notes / leave-form scans. Re-use - `validate_max_5mb()` from `core/forms.py`. -- **Admin / supervisor scoping.** Supervisors can mark absent - workers on their team; admins see everything. -- **Reporting.** Per-worker annual leave-day totals on the worker - batch report. +1. **Backup first** (safety net) — visit + `https://foxlog.flatlogic.app/backup-data/` while logged in as + admin. Download the `.json` file to a safe location. +2. **Run pending migrations** — visit + `https://foxlog.flatlogic.app/run-migrate/`. Applies three + migrations: + - `0013_add_site_report` — creates `core_sitereport` table (fixes + the immediate /history/ error) + - `0014_add_absence` — creates `core_absence` table + - `0015_absence_project` — adds `project` FK to absence +3. **Refresh static files + restart service** — ask Gemini in + Flatlogic to run: + ``` + python3 manage.py collectstatic --noinput + sudo systemctl restart django-dev.service + ``` + Needed because `static/css/custom.css` has new + `.badge-absence-*` rules — without `collectstatic`, the reason + badges on the new pages will render with no color. +4. **Smoke test (incognito)** — visit `foxlog.flatlogic.app/history/` + (should load), `/absences/` (should load), `Resources → + Absences` (admin dropdown should now have it). Log one test + absence end-to-end. -**Models to learn from in `core/models.py`:** -- `WorkerWarning` — per-worker, severity choices, dated, optional - document, ordered `-date`. Good shape match. -- `WorkerCertificate` — per-worker, type choices with `unique_together`, - `valid_until` expiry, `is_expired` / `expires_soon` properties. +**Rollback if anything breaks:** visit +`https://foxlog.flatlogic.app/restore-data/`, upload the backup +from step 1, ask Gemini to restart the service. + +**Why this is parked, not urgent:** The /history/ error only fires +when someone actively uses the History page. The dashboard, +attendance log, and payroll pages all work fine. Konrad chose to +defer the deploy step — that's the right call when you don't have +time to babysit a deploy properly. + +**Reference:** the deployment hazard is documented in CLAUDE.md +under "Migrations" in the Flatlogic/AppWizzy Deployment section. --- @@ -97,6 +104,47 @@ verification, shared-secret URL token. --- +## Small polish follow-ups from the Absences feature + +These were flagged during code review of the absences feature but +deemed non-blocking. They can roll into a future janitorial pass. + +- **`AbsenceQuickForm` is defined but never wired up** — + `core/forms.py:797-827`. Originally planned for a per-worker ✗ + modal on the attendance form, but Round C replaced that paradigm + with the "Submit + Log Absences" button. Either wire the form up + somewhere or delete the class. ~30 LOC. +- **N+1 in `team_workers_map` build** — affects both `attendance_log` + and `absence_log`. Pre-existing in `attendance_log`; Round A + inherited the pattern. Fix is to use + `Prefetch('workers', queryset=Worker.objects.filter(active=True), + to_attr='active_workers_cached')` like the payroll dashboard does. + Recommend extracting `_build_team_workers_map(user)` as a shared + helper. +- **`absence_list` permission check duplicates `_user_can_log_absences`** — + `core/views.py:5535` inlines `is_admin(user) or + user.supervised_teams.exists()` instead of calling the helper. + Trivial DRY cleanup. +- **`--badge-neutral-bg` referenced but never defined** — + `static/css/custom.css` near line 2197. The CSS uses + `var(--badge-neutral-bg, #6c757d)` for `.badge-absence-unpaid` and + `.badge-absence-other`; the fallback always wins because the + variable isn't declared in `:root`. Either define it in both + themes or drop the `var()` wrapper. +- **`conflicting_worklogs()` runs N queries per (worker, date) pair** — + `core/forms.py:785-786`. Fine at FoxFitt's scale. Worth profiling + if/when batch sizes grow. +- **CSV export filter block is duplicated** — `core/views.py` + `absence_export_csv` copies the filter logic from `absence_list`. + TODO comment in code says "factor into `_apply_absence_filters` + when a third filter joins." +- **Paid-checkmark icon in `site_report_detail.html`** uses + `color: var(--badge-bonus-bg)` (a BACKGROUND color) as foreground + — fails WCAG contrast on white. Same fix as we applied to absence + templates (use `text-success`). Trivial one-line change. + +--- + ## Defaulted (not blocking — flag if you disagree) From Q9, Q4 of the Site Work Logging brainstorm: @@ -114,11 +162,23 @@ From Q9, Q4 of the Site Work Logging brainstorm: ## Recently shipped (for context, so a fresh session knows what just landed) +- **Worker Absences feature** (commits `bf6f0a5` → `27fe05e`, + 14 May 2026): Complete absence-tracking system. 8 reason choices, + optional project FK (auto-attributes paid-absence Bonus + adjustments to the project), date-range logging with weekend + toggles, supervisor scoping (admin sees all; supervisors see + their teams). Standalone `/absences/log/` form + "Submit + Log + Absences" shortcut on attendance form. List/edit/delete + CSV + export. Worker-detail "Absences" tab with YTD totals. Dashboard + alert card "X absent in last 7 days". Bidirectional cascade with + PayrollAdjustment via `_sync_absence_payroll_adjustment` helper + (single-chokepoint design, transaction.atomic-wrapped). All 12 + commits pushed to `origin/ai-dev`. Test count: 85 → 149 (+64 + tests). All ai-dev tests green. - **Phase A.1 — SiteReport** (commit `864ae72`, 14 May 2026): Model, migration `0013_add_site_report.py`, form, two-step flow - from attendance log, 16 new tests. All 85 / 85 tests passing. - `CLAUDE.md` updated with model summary + `site_report_schema.py` - pattern section. + from attendance log, 16 new tests. `CLAUDE.md` updated with model + summary + `site_report_schema.py` pattern section. - **Pastel soft-fill payroll action buttons** (commit `6c6ade9`, 24 Apr 2026): unified Worker Lookup / Batch Pay / Add Adjustment / Price Overtime treatment.