diff --git a/Claude.md b/Claude.md index 73ff703..d1c23ae 100644 --- a/Claude.md +++ b/Claude.md @@ -800,6 +800,21 @@ Every route `except` block must: No bare `except:` — always `except Exception as e:`. +### QR Code Name — Locked After Creation +The QR code name **cannot be changed** after creation because it is used to generate the `qr_url` slug. +Changing the name would break all existing printed/distributed QR codes. + +- **Template (`edit_qr_code.html`):** name `` has `readonly` attribute + `cursor: not-allowed` style + lock icon in label +- **Route (`routes/qr_codes.py`):** edit POST ignores `request.form['name']` — sets `new_name = qr_code.name` (original value). Do NOT change this back to reading from the form. + +```python +# CORRECT — name locked after creation: +new_name = qr_code.name # always use existing name, never request.form['name'] + +# WRONG — never do this in the edit route: +# new_name = request.form['name'] +``` + ### Employee Autocomplete (attendance and time-attendance) - Visible text input + hidden `employee_id` field synced on numeric input - Fetches `/api/search_employees` (includes unregistered IDs from `attendance_data`, not only Employee table) @@ -919,6 +934,14 @@ Showing the most recent 1,000 records. Narrow the date range or apply additional | `templates/edit_qr_code.html` | Photo Verification toggle section added (CSS in `extra_head`, JS in `extra_scripts` with `addEventListener`) | | `tools/migration_photo_verification_toggle.py` | pymysql migration — adds column safely | +### Set 11 — QR Name Lock Restored + CSRF Fix (May 2026) +| File | Change | +|---|---| +| `templates/edit_qr_code.html` | Name field restored to `readonly` — lock icon in label, `cursor: not-allowed`, help text explaining why | +| `routes/qr_codes.py` | Edit route: `new_name = qr_code.name` (never reads from form) — prevents name change server-side | +| `templates/create_qr_code.html` | `window.qrConfig` with `csrfToken` injected in `` — fixes 403 on `/api/geocode` (standalone template, doesn't extend base) | +| `templates/base_authenticated.html` | `window.qrConfig` block moved before `{% block extra_scripts %}` — fixes token availability for all pages extending base | + --- ## 21. Infrastructure & Deployment @@ -946,4 +969,6 @@ See §20 Sets 1–8 for detailed bug fix history. Covers: initial critical fixes - Synced `base.html`, `base_authenticated.html`, `projects.html` — GOV brought to parity with LT - Added per-QR `photo_verification_enabled` toggle (DB column + model + routes + UI + migration) - Fixed migration script: replaced `urlparse` with regex parser (handles special chars in DB passwords), replaced SQLAlchemy `conn.execute(str)` with `pymysql` direct (avoids ORM loading model before column exists) -- Fixed `edit_qr_code.html` toggle bug: JS was injected into `{% block title %}` (corrupted by earlier injection) — moved CSS to `extra_head`, JS to `extra_scripts` using `addEventListener`, removed inline `onchange` attribute \ No newline at end of file +- Fixed `edit_qr_code.html` toggle bug: JS was injected into `{% block title %}` (corrupted by earlier injection) — moved CSS to `extra_head`, JS to `extra_scripts` using `addEventListener`, removed inline `onchange` attribute +- Restored QR code name lock on edit page: field is `readonly` in template; route ignores submitted name (`new_name = qr_code.name`) +- Fixed `/api/geocode` 403: `create_qr_code.html` is standalone HTML (no `{% extends %}`), so `window.qrConfig` was never injected — added direct injection in ``; also fixed ordering in `base_authenticated.html` for pages that do extend it \ No newline at end of file