38686-vm/docs/plans/parked-work.md
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

182 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Parked / deferred work
> Updated 15 May 2026. 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.
---
## ⚠ Pending pull-and-restart on production
**Status:** The big absences/SiteReport deploy (migrations
`0013`/`0014`/`0015` + collectstatic + service restart) was
completed on 14 May 2026 — `/history/` no longer crashes,
`/absences/*` is reachable, badge CSS is collected. ✓
Since that deploy, four small commits have shipped to `origin/ai-dev`
that are NOT yet on production:
| Commit | What it does |
|---|---|
| `4368e53` | Fixes the absence-form team filter (workers were all disappearing when a team was selected — read input.value instead of data-attr) |
| `02c6d4d` | Fixes the Reasons multi-checkbox dropdown stacking-context bug on `/absences/` (lifted the filter card above the table card) |
| `4b57cff` | Adds a Team filter to `/workers/` |
| `398a5b2` | Adds a Team filter to `/history/` (and CSV export) |
| `70fa085` | Shows day name in Work Log Payroll modal header ("Friday, 15 May 2026") |
| `d1d3e15` | 7 absence-feature polish follow-ups (dead code removal, N+1 fixes, DRY helpers, WCAG icon contrast) |
**To deploy these:**
- No migrations needed (pure template + view changes; no schema changes).
- No `collectstatic` needed (no new CSS or JS files).
- Just: ask Gemini in Flatlogic to `git pull origin ai-dev` and then `sudo systemctl restart django-dev.service`.
That's the whole sequence. Production should pick up all four
improvements instantly. Rollback is `git reset --hard <previous SHA>`
on the VM if anything looks wrong (no data migrations were involved,
so rollback is safe).
---
## Blocked on Konrad's input
### Phase A.2 — Manual JournalEntry web UI
**Status:** Designed in the Site Work Logging brainstorm. Model
class drafted in the design doc (not yet in `core/models.py`).
Not yet built.
**Blocked on:** Q7 from the original brainstorm — "Who is Vi?" The
answer drives whether `JournalEntry` needs a `recipient` or
`audience` field (i.e. is this a public log, or does it have
specific addressees like a client). **Default if unanswered:** no
recipient field — entries are all-admin-readable.
**Scope when unblocked:** ~1 hour of work. Manual entry form at
`/journal/new/`, list at `/journal/`, edit at `/journal/<id>/edit/`.
Admin-only views. Lives on `ai-dev` (no webhook involvement).
### Phase B — Letterly inbound webhook (`integrations` branch)
**Status:** Designed in the Site Work Logging brainstorm. Belongs
on the `integrations` branch, **not** `ai-dev`.
**Blocked on:** Q5 from the original brainstorm — Konrad needs to
share a sample Letterly webhook payload. Need to know:
- Does it include the recording user (so we can map to a Django User)?
- Does it include project / location metadata, or just the transcript?
- Does it include an audio URL for link-back?
- Does Letterly support custom fields (so a deep-link from
`/site-report/<id>/edit/` could embed a `work_log_id` that the
webhook reads back)?
**Scope when unblocked:** ~3-4 hours including tests + one-off
Letterly account setup. Adds a `@csrf_exempt` view at
`/webhooks/letterly/`, `JournalEntry` row creation, HMAC body
verification, shared-secret URL token.
---
## Small polish follow-ups from the Absences feature
> All 7 cleared on 15 May 2026 (commit `d1d3e15`). Kept the section
> header in place because more polish items will accumulate from
> future code reviews — when they do, append here. The shipped items
> are summarized under "Recently shipped" below.
---
## Defaulted (not blocking — flag if you disagree)
From Q9, Q4 of the Site Work Logging brainstorm:
- **Q9 — photos on site reports.** Deferred to v2 of SiteReport.
Construction supervisors often want to attach a phone photo of
"plinths cast today" but it adds ~50 LOC + storage handling +
thumbnail rendering. v1 ships without.
- **Q4 — per-project metric templates.** Same metric set for all
projects in v1. If/when a non-solar-farm project lands and the
metrics diverge wildly, we add a `MetricTemplate` model. YAGNI
for now — `core/site_report_schema.py` is one Python file edit.
---
## Recently shipped (for context, so a fresh session knows what just landed)
- **Absence-feature polish pass** (commit `d1d3e15`, 15 May 2026):
Seven small cleanups in one focused commit. (1) Deleted unused
`AbsenceQuickForm` (Round C made it obsolete). (2) Extracted
`_build_team_workers_map(user)` helper using `Prefetch(..., to_attr=...)`,
fixing N+1 on both `attendance_log` and `absence_log` (one query
instead of one-per-team). (3) `absence_list` now calls the existing
`_user_can_log_absences` helper. (4) Removed undefined
`var(--badge-neutral-bg)` CSS wrapper — fallback hex was always
winning anyway. (5) `conflicting_worklogs()` rewritten as a single
query with Python-side pair-set filtering — 25-query → 2-query for
a 5×5 form. (6) Extracted `_apply_absence_filters(qs, request)`
shared by `absence_list` + `absence_export_csv` so adding a filter
param now touches one place, not two. (7) `site_report_detail.html`
paid-check icon uses `text-success` instead of background-color
variable as foreground (WCAG contrast fix). 157/157 tests still
green.
- **Day name in Work Log Payroll modal header** (commit `70fa085`,
15 May 2026): The modal opened from /history/ now shows
"Friday, 15 May 2026" instead of "2026-05-15". Pure server-side
`strftime` on the already-loaded `log.date` — zero overhead.
- **Team filters on `/workers/` and `/history/`** (commits `4b57cff`,
`398a5b2`, 15 May 2026): Both pages now have a Team dropdown in
their filter row. `/workers/?team=<id>` filters by Team.workers
M2M membership (who's CURRENTLY on the team); `/history/?team=<id>`
filters by WorkLog.team FK (logs TAGGED with the team when
created — different semantics, intentional). Both accept
`team=none` for the "no team assigned" / "ad-hoc work log" case.
CSV export at `/history/export/` honours the same param.
+8 regression tests.
- **Absences UX polish** (commits `4368e53`, `02c6d4d`, 15 May 2026):
Two production-found bugs fixed. (1) Absence-form team filter was
hiding ALL workers when a team was selected — switched the JS to
read `<input name="workers">[value]` directly instead of going
through `data-worker-id` (proven attendance-form pattern). (2)
Reasons multi-checkbox dropdown on `/absences/` was rendering
behind the table — lifted the filter card with
`position: relative; z-index: 10` so the whole card sits above
its sibling table card in the stacking order. See the Coding
Style section in CLAUDE.md for both gotchas.
- **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). 12
commits pushed to `origin/ai-dev`. Test count: 85 → 149 (+64
tests). Migrations `0013_add_site_report`, `0014_add_absence`,
`0015_absence_project` are LIVE on production as of late 14 May
2026.
- **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. `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.
- **Path A display-only rename** (UX Polish Pass, Apr 2026):
"New Loan" / "Advance Payment" / "Advance Repayment" display as
"Loan" / "Advance" / "Advance Repaid" — but **DB values are
unchanged**. See "UI-vs-DB naming drift" section in `CLAUDE.md`
before writing any filter/comparison on `PayrollAdjustment.type`.
---
## Original Site Work Logging brainstorm
The full Q1-Q13 question list and design rationale lives in
`~/.claude/plans/prancy-painting-brook.md` (local — deliberately
not committed to the repo, since the parts that matter have been
absorbed into `CLAUDE.md` and this file). If Konrad answers Q5 or
Q7 later, refer back to that file for the original framing.