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>
200 lines
8.7 KiB
Markdown
200 lines
8.7 KiB
Markdown
# Parked / deferred work
|
|
|
|
> 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.
|
|
|
|
---
|
|
|
|
## ⚠ Needs operator action (production)
|
|
|
|
### Production deploy of SiteReport + Absences (pending Konrad)
|
|
|
|
**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:
|
|
|
|
```
|
|
ProgrammingError: (1146, "Table 'app_38686.core_sitereport' doesn't exist")
|
|
```
|
|
|
|
**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.
|
|
|
|
**The fix (~2 minutes total):**
|
|
|
|
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.
|
|
|
|
**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.
|
|
|
|
---
|
|
|
|
## 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
|
|
|
|
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:
|
|
|
|
- **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)
|
|
|
|
- **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. `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.
|