diff --git a/CLAUDE.md b/CLAUDE.md index 8215693..8a1c794 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -3,17 +3,20 @@ ## What's mid-flight — read this first **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. +**Production status (15 May 2026):** migrations `0013_add_site_report`, +`0014_add_absence`, `0015_absence_project` are deployed; `/history/` +is no longer crashing on the production VM. The Worker Absences +feature shipped on 14 May 2026 (commits `bf6f0a5` → `27fe05e` on +`ai-dev`). Subsequent UX polish (multi-checkbox-dropdown stacking +fix, absence-form team-filter bug fix, team filter added to +`/workers/` and `/history/`) is on `ai-dev` HEAD but not yet on +production — needs a `git pull` + `sudo systemctl restart +django-dev.service` whenever convenient (no migrations or +collectstatic required for those commits). 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`). +answers — see `docs/plans/parked-work.md`. ## Coding Style - Always add clear section header comments using the format: # === SECTION NAME === @@ -22,6 +25,8 @@ answers. The Worker Absences feature shipped on 14 May 2026 (commits - When creating or editing code, maintain the existing comment structure - **Django template comments `{# ... #}` are SINGLE-LINE only.** Multi-line blocks need `{% comment %}...{% endcomment %}`. A `{#` on line N with no closing `#}` on the same line renders the whole block as literal text onto the page (and silently — no error). This bit us 4× during the Adjustments feature. Also: the literal tokens `{#` and `#}` cannot appear inside a `{% comment %}` block — they'll be parsed as a nested comment marker. Rephrase meta-notes about comment syntax OUTSIDE the block. - **Duplicate `id=""` attributes cause silent bugs.** `document.getElementById()` returns only the FIRST match in DOM order, so adding a second element with an existing id silently steals the handler from the original. Grep the template before assigning any new id (caught `adjSelectAll` collision in Task 6 — header checkbox stole the Add-Adjustment modal's Select-All handler). +- **Bootstrap dropdowns inside `.card` elements get clipped by sibling cards.** A `.dropdown-menu` with `z-index: 1050` rendered inside a filter `.card` will STILL appear behind a sibling table `.card` that follows in document order. Bootstrap's `transform: translate(...)` Popper positioning creates a new stacking context — the z-index is measured INSIDE the parent card, not globally. The fix: lift the wrapping element (e.g. the filter `
`) with `style="position: relative; z-index: 10;"` so the entire card sits above its siblings. The dropdown's local z-index then resolves correctly. Bit us on the Absences filter dropdown (May 2026). +- **JS reading from `data-worker-id` was unreliable; read from `[value]` directly.** Round A's first absence-form team filter rendered `data-worker-id="{{ worker.choice_value }}"` on the row `
` and read it via `row.dataset.workerId`. On production this hid ALL workers when a team was selected — likely a stale-template / template-render mismatch. The proven pattern (used by `attendance_log.html` for years) is to read `row.querySelector('input[name="workers"]').value`. The form widget's `` is the source of truth; data attributes are an unnecessary indirection. ## Project Overview Django payroll management system for FoxFitt Construction, a civil works contractor specializing in solar farm foundation installations. Manages field worker attendance, payroll processing, employee loans, and business expenses for solar farm projects. @@ -335,7 +340,7 @@ numbers on hot pages. - Quick Adjust Button: Each pending payments row has an "Adjust" button (slider icon) that opens the Add Adjustment modal with that worker pre-checked and their most recent project pre-selected. The header "Add Adjustment" button resets the modal to a clean state. Uses `_quickAdjustOpen` flag to distinguish between the two open paths. - Worker Lookup Modal: Clicking any worker name on the payroll dashboard (or using the "Worker Lookup" button) opens a modal with a comprehensive report card — amount payable, outstanding loans, paid this month/year, loans this year, recent activity (last payslip, loan, repayment, advance), active loans table, current project + days on project, PPE sizing, drivers license, and notes. Uses `worker_lookup_ajax` AJAX endpoint. Worker dropdown in modal allows switching workers without closing. - Team & Project Management UIs: Friendlier alternatives to `/admin/core/team/` and `/admin/core/project/`. Reachable via the "Resources" dropdown in the topbar (admin only). **Team pages**: `/teams/` (list + search/filter), `/teams//` (detail with Profile/Pay Schedule/Workers/History tabs — Pay Schedule tab uses the existing `get_pay_period()` helper to show current + next 2 periods), `/teams//edit/` (single-page form for name, supervisor, pay schedule, and workers M2M). **Project pages**: `/projects/`, `/projects//` (tabs: Profile/Supervisors/Teams/Workers/History), `/projects//edit/` (form for name, description, dates, supervisors M2M). Uses `TeamForm` and `ProjectForm` from `core/forms.py` (both simple ModelForms, no inline formsets). Batch reports at `/teams/report/` and `/projects/report/` with CSV exports; PDF exports deferred as a follow-up. Dashboard "Manage Resources" card now has "Manage All Workers/Projects/Teams" footer links on each tab. Django admin remains fully functional as a fallback. -- Worker Management UI: A friendlier alternative to `/admin/core/worker/`. Reachable via the "Resources" topbar dropdown → Workers (admin-only). Pages: `/workers/` (list with search + status filter), `/workers//` (detail with Profile/Certifications/Warnings/History tabs), `/workers//edit/` or `/workers/new/` (single-page form with sections for Personal & Pay, PPE, Documents, Driver's License, plus inline formsets for certifications and warnings). Uses `WorkerForm`, `WorkerCertificateFormSet`, `WorkerWarningFormSet` from `core/forms.py`. The "+ Add Certification" / "+ Add Warning" buttons clone a `