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>
This commit is contained in:
Konrad du Plessis 2026-05-17 01:23:09 +02:00
parent aaca0b36d3
commit 777c7c6dcc
2 changed files with 279 additions and 0 deletions

View File

@ -0,0 +1,167 @@
# Remove "Log Today's Work" / SiteReport — Design
**Date:** 17 May 2026
**Status:** Approved by Konrad on 17 May 2026; ready for implementation plan.
**Branch:** `ai-dev` (origin HEAD `aaca0b3` at design time — production
caught up & verified). **HARD STOP before push** — destructive
migration on the daily-use attendance path; Konrad verifies locally
first.
## Goal (one sentence)
Completely remove the optional post-attendance SiteReport ("Log Today's
Work") feature — model, table, code, UI, routes, tests, docs — with no
remnants and nothing broken, reverting the post-attendance flow to its
pre-SiteReport behaviour, and preserve the design thinking in a capture
doc for a future from-scratch rebuild.
## Why
Konrad wants to rethink site-progress logging from scratch separately.
The work mix is shifting ("we might start piling and not cast so many
plinths anymore") so the metric set and the whole scope are genuinely
uncertain — half-fitting code is worse than a clean slate. The feature
was lightly used; **Konrad explicitly accepted irreversible loss of any
existing SiteReport data (no backup)** when choosing the removal path.
## Decision (from the brainstorm)
Konrad chose **"Drop the table — no backup"**: a real migration
(`0018_delete_sitereport`) drops `core_sitereport` on deploy; no
production backup is taken. Full removal, no orphaned model/table.
## §1 — Behavioural change (the only user-visible effect)
`core/views.py::attendance_log` POST, currently ~lines 750-785: after a
successful submit it `return redirect('site_report_edit',
work_log_id=created_log_ids[-1])`. After removal: just
`return redirect('home')` — the existing green "Successfully created N
work log(s)." toast still fires. This reverts to the original
pre-SiteReport behaviour.
- The **`next_action == 'log_absences'`** branch (the "Submit + Log
Absences" shortcut) is **untouched** — unrelated to SiteReport.
- The now-dead `created_log_ids` list (`= []` + `.append()`) and the
Round-C comment's "log_only → Site Report flow" wording are cleaned
up so no dead plumbing remains. `dates_to_log[-1]` (used by the
absences branch) is unaffected.
## §2 — Code / model / template removal (no remnants)
**Delete entire files:**
- `core/site_report_schema.py`
- `core/templates/core/site_report_edit.html`
- `core/templates/core/site_report_detail.html`
**Edit:**
- `core/models.py` — delete the `SiteReport` class + its doc-header block.
- `core/forms.py` — delete `SiteReportForm` and the
`from .site_report_schema import …` line (and the form's surrounding
doc-header comment).
- `core/views.py` — delete `_can_access_site_report`,
`site_report_edit`, `site_report_detail`; remove the `SiteReport`,
`SiteReportForm`, `site_report_schema` imports; drop
`select_related('site_report')` in `work_history` (use plain
`WorkLog.objects` / keep other select_related args intact); remove
the SiteReport redirect block + dead `created_log_ids` plumbing in
`attendance_log` (per §1).
- `core/urls.py` — delete the two `path('site-report/…')` routes.
- `core/admin.py` — delete the `@admin.register(SiteReport)` block and
the `SiteReport` import.
- `core/templates/core/work_history.html` — delete the report
indicator / link block (`{% if log.site_report %}` … the
`site_report_detail` / `site_report_edit` anchors, ~lines 462-471).
**Migration:** after the model is gone, run `python manage.py
makemigrations core` → it generates **`0018_delete_sitereport`**
(`DeleteModel`, depends on `0017_alter_payrolladjustment_type`). Do not
hand-write it — let the autodetector emit the correct
RemoveField/DeleteModel ordering. `makemigrations --check` must be
clean afterwards.
## §3 — Tests
Delete the 5 SiteReport-only classes in `core/tests.py`:
`SiteReportModelTests`, `SiteReportFormTests`, `SiteReportEditViewTests`,
`SiteReportDetailViewTests`, `AttendanceLogRedirectsToSiteReportTests`,
plus the `from core.models import SiteReport` /
`from core.forms import SiteReportForm` lines (~1629-1630) and the
section header comment block (~1624-1631).
The one cross-reference — `test_log_only_explicit_value_still_goes_to_site_report`
(~line 2873, inside the absences-shortcut test class) — asserts the OLD
contract. **Rewrite** it (rename to e.g.
`test_plain_submit_redirects_home`) to assert the NEW contract: a plain
attendance POST (no `next_action` / `next_action='log_only'`) → HTTP
302 to `/`. This keeps regression coverage of the reverted flow rather
than deleting coverage outright.
Full suite must stay green at the new count (209 minus the deleted
SiteReport tests, ± the rewritten one). The exact expected number is
computed and pinned in the plan.
## §4 — Docs
- **CLAUDE.md:** delete the entire "SiteReport metric schema
(Apr 2026)" section; the Key Models `SiteReport` bullet; the
`/site-report/<id>/edit/` and `/site-report/<id>/` URL-routes table
rows; and any two-step-flow / "auto-redirected here after
/attendance/log/ POST" mentions. Add a one-line pointer under the
relevant area: SiteReport removed 17 May 2026 — see capture doc.
(The production breadcrumb was already flipped to ✅ in commit
`aaca0b3`.)
- **docs/plans/parked-work.md:** the **"Post-Attendance Flow v2"**
entry (under "⏸ Paused — ready to execute") is now obsolete — it
reworked the very flow being deleted. Replace it with a short
"SiteReport removed; future rebuild parked" pointer to the capture
doc. Keep the `2026-05-15-post-attendance-flow-v2-*` design/plan
files on disk (prior thinking worth mining) — the capture doc marks
them superseded.
- **New capture doc** `docs/plans/2026-05-17-site-report-removed-capture.md`
(written now, in this design step) — preserves the institutional
knowledge for the future rebuild (see that file).
## §5 — Process / scope
- **Done already (separate, pushed):** the production-caught-up
breadcrumb flip (commit `aaca0b3`).
- **This removal:** writing-plans → subagent-driven execution → **HARD
STOP before any push**. Konrad runs the local verification, then
pushes.
- **Deploy (when Konrad later approves):** pull → `python3 manage.py
migrate` (applies `0018`, drops `core_sitereport`) → restart. **No
`collectstatic`** (no `static/` change — pure code/template/model
deletion). Restart still required (DEBUG=False template cache).
- **No backup** of SiteReport data (Konrad's explicit choice — accepted
irreversible loss).
## Local verification (Konrad — HARD STOP gate)
1. Submit `/attendance/log/` → lands straight on the dashboard `/` with
the green "Successfully created N work log(s)." toast — **no**
"Log Today's Work" page.
2. "Submit + Log Absences" button still jumps to `/absences/log/`
prefilled (unchanged).
3. `GET /site-report/1/edit/` and `GET /site-report/1/` → **404**
(routes gone).
4. Django admin (`/admin/`) shows **no** SiteReport model.
5. `python manage.py makemigrations --check` → clean (no pending);
`python manage.py migrate` applies `0018_delete_sitereport` with no
errors; `core_sitereport` table is gone.
6. Full test suite green.
7. `grep -ri "sitereport\|site_report\|site-report" core/` → only
inert historical migration files `0013`/`0014` match (expected —
immutable history, not a code remnant); zero matches in
models/views/forms/urls/admin/templates/tests.
Then — and only then — Konrad pushes; deploy as in §5.
## Out of scope (deliberately)
- No replacement site-progress feature now (that's the future separate
rethink — captured, not built).
- Absences shortcut, Manager/Salaried, pay-type filter, Salary
auto-scope, Pay Salary quick action — all untouched.
- The historical migrations `0013`/`0014` are NOT edited (immutable
Django history; "no remnants" means no live code/model/UI, not
rewriting migration history).

View File

@ -0,0 +1,112 @@
# SiteReport / "Log Today's Work" — Removed; Future-Rebuild Capture
**Date removed:** 17 May 2026
**Why this doc exists:** Konrad removed the SiteReport feature to
rethink site-progress logging **from scratch, separately**. This file
preserves everything worth knowing so a future session can rebuild it
without re-deriving the design — and without resurrecting code that no
longer fits.
> **Status: NOT a plan. Do NOT implement from this file.** It is a
> knowledge capsule. A future rebuild starts with a fresh
> brainstorming pass (see "When you rebuild" at the bottom).
## Why it was removed (the important part)
The on-site work mix is changing. The original feature was modelled
around a solar-farm foundation workflow (plinths cast, plinth holes
dug, boxes placed, steel placed, …). Konrad's words: *"we might start
piling and not cast so many plinths anymore so the scope might get
bigger or smaller."* The metric set — and whether a fixed metric set is
even the right model — is genuinely unknown. Half-fitting code on a
daily-use path is worse than a clean slate. So: full removal now,
deliberate redesign later when the new workflow is clearer.
Konrad explicitly accepted **irreversible loss of existing SiteReport
rows** (no backup taken) — the data was lightly used and not worth
carrying into a redesign.
## What it did (so you don't have to reverse-engineer it)
A `SiteReport` model, **optional 1:1 with `WorkLog`** (a WorkLog with
no report was a normal historical row). Fields:
- `weather` (choices: sunny/cloudy/rain/storm/hot/cold/windy),
`temperature_min` / `temperature_max` (°C, IntegerField),
free-form `notes`, `created_by`, `created_at`, `updated_at`.
- `metrics` — a `JSONField` of shape
`{'counts': {key: int}, 'checks': {key: bool}}`.
### The one genuinely good idea worth keeping: schema-as-Python, no migration
The metric **keys were NOT model columns**. They lived in a single
Python file `core/site_report_schema.py` (`COUNT_METRICS`,
`CHECK_METRICS`, `label_for()`). Adding/removing/renaming a metric was a
one-line edit + redeploy — **no DB migration**, old rows degrade
gracefully (missing key → 0/unchecked; retired key still shows via
`label_for` fallback). `SiteReportForm` iterated the schema at
`__init__` to build dynamic `IntegerField`/`BooleanField`s and
serialised back into the JSON blob on `save()`.
**This pattern is the single most reusable lesson.** Given Konrad's
"scope may get bigger or smaller" concern, a flexible-by-default schema
(JSON blob + a Python/DB-driven field list) is almost certainly the
right foundation again — possibly upgraded to an admin-managed
`MetricTemplate` model if per-project metric sets diverge.
### The flow it was wired into
Two-step: `attendance_log` POST (success) → redirect to
`/site-report/<work_log_id>/edit/` (mobile-first form, "Skip" link to
home). Read-only view at `/site-report/<work_log_id>/`. Permission:
admin, or supervisor of the WorkLog's team/project. On removal the flow
reverted to the original **redirect → home + success toast**.
## Prior thinking already on disk (mine these, then move past them)
- `docs/plans/2026-05-15-post-attendance-flow-v2-design.md` +
`-plan.md` — a *fully designed, Konrad-approved-but-never-built*
rework of this flow: replace the forced redirect with 3 explicit
buttons (Log Work → dashboard / + Site Journal / + Absences), plus a
"Save + Add Absences" button; and a Path-A display-only rename
"Site Report" → **"Site Journal"** (to free the word "Journal" for
the parked voice-notes feature). **Superseded by the removal** — the
flow it modified no longer exists. Kept on disk because the
button-hierarchy and naming-collision analysis are good raw material.
- `docs/plans/2026-05-17-site-report-removal-design.md` — the removal
design that this capture accompanies.
## How to recover the deleted implementation if you want a reference
The full original implementation is in git history. The recovery point
is **the commit immediately before `0018_delete_sitereport` landed** on
`ai-dev`. To find and read any deleted file:
```
git log --oneline -- core/site_report_schema.py # last commit is the recovery point
git show <that_sha>:core/site_report_schema.py
git show <that_sha>:core/models.py # SiteReport class
git show <that_sha>:core/forms.py # SiteReportForm
git show <that_sha>:core/views.py # site_report_edit / _detail / _can_access_site_report
git show <that_sha>:core/templates/core/site_report_edit.html
```
Nothing is lost from *code* history — only the production *table* and
its rows were dropped.
## When you rebuild (guidance, not a plan)
1. **Brainstorm first** — the new workflow (piling vs casting, etc.)
must drive the metric model. Do not start from the old metric list.
2. **Keep the JSON-blob + Python/admin-driven schema** idea — it is the
right answer to "scope may change." Decide early: fixed global
schema vs per-project `MetricTemplate`.
3. **Decide the flow deliberately** — the v2 design's "3 explicit
buttons, no forced redirect" instinct was sound; revisit it with
fresh eyes against the new workflow.
4. **Re-evaluate the model name** — "SiteReport" / "Site Journal" /
something else; mind the parked voice-notes "Journal" collision
noted in the Backburner section of `parked-work.md`.
5. New design doc + plan under `docs/plans/`, normal
brainstorm → writing-plans → subagent execution, HARD STOP before
push (it touches the daily attendance path).