Commit graph

19 commits

Author SHA1 Message Date
mwiegand
653e3212b9
tests: harden refresh-hidden-during-build with positive assertion 2026-05-11 23:13:39 +02:00
mwiegand
25b38e633d
overlay_detail: add 'Refresh from Steam' button for workshop overlays
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 23:10:27 +02:00
mwiegand
e75f379dcb
auth: reject sessions older than user.password_changed_at
load_current_user now treats a session whose pw_changed_at marker
is missing, malformed, or older than the user's current
password_changed_at as logged-out. Same shape as the existing
user.active check.

Forced fan-out updates to every test fixture that forges a session
via session_transaction(): each now stamps a current pw_changed_at
marker. test_deactivated_user_existing_session_invalidated keeps
its meaning — the deactivation still flips the user to inactive,
and load_current_user rejects the session via the user.active
branch before reaching the freshness branch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 21:54:13 +02:00
mwiegand
fa686f11e3
feat(l4d2-web): server + overlay detail — live-refresh via HTMX, restructured
Vendors HTMX 2.0.4 (the prior file was a 1-line stub) and uses it to poll
two new partials on a 2s tick while a job is in flight:

- /servers/<id>/actions → state badge, filtered action buttons,
  last-job sentence, live job log (SSE) while a Start/Stop/Reset job
  is running. When the job is terminal the partial re-renders without
  hx-trigger and polling stops.
- /overlays/<id>/build-status → build state badge, last-build
  sentence, live job log while a build_overlay job is running. Same
  terminal-state stop behavior.

Server detail restructure:
- Editable name moves out of the page body into a Rename modal
  triggered from a link next to Delete in the page footer.
- Compact dl with Port (linked as steam://run/550//+connect <host>:<port>)
  and Blueprint.
- Actions row: state badge + state-filtered buttons (start/stop, reset)
  + last-job sentence. Drift warning when desired ≠ actual.
- Recent Jobs table removed.

Overlay detail restructure:
- Single panel, dl Type/Scope, no separate Last build row, no Builds
  section.
- Script form gets two compound submits: "Save and build" and
  "Save, reset and rebuild". Standalone Rebuild/Wipe gone.
- Build status state badge + last-build sentence under the editor;
  action buttons hide while a build is in flight.
- Rename modal in the page footer next to Delete.

sse.js binds on htmx:load (covers initial document and post-swap inserts)
and closes EventSources on htmx:beforeCleanupElement to avoid leaking
streams across swaps.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 01:27:30 +02:00
mwiegand
a4e9f6cd26
feat(l4d2-web): blueprint overlay picker — drag-list + add-dropdown
Replace the per-row checkbox + numeric Order table on the blueprint
detail page with a drag-to-reorder list of selected overlays plus a
native <select> for adding more. Removing uses an × button per row;
the option sorted-inserts back into the dropdown alphabetically.

Native HTML5 drag-and-drop, no library, no JS-disabled fallback.
Server contract is unchanged: each list row owns one hidden
<input name="overlay_ids">, DOM order = submission order, and the
existing fallback_position branch in ordered_overlay_ids_from_form
absorbs the now-omitted overlay_position_<id> fields.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 21:37:11 +02:00
mwiegand
fb3c6be052
feat(l4d2-web): per-overlay job list + redirect to job after build-triggering edits
Saving a script overlay or adding/removing workshop items now redirects to the
enqueued build job's detail page so logs are immediately visible. Added a new
/overlays/<id>/jobs page (linked as "all builds →" from the overlay detail
page) for browsing the full build history. Renamed the script "Save" button to
"Save and build" to make the side effect explicit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 17:44:22 +02:00
mwiegand
5e2c771276
chore(l4d2-web): remove orphaned 'Global map overlays' admin section
The route /admin/global-overlays/refresh was removed with the script-overlays
rewrite (migration 0005 dropped the global_overlay_* tables; the systemd
refresh units were deleted from deploy/). The admin-page form was left
behind and would 404 on submit. Drop the section and lock it out with an
assertion in the existing admin-pages test.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 17:25:15 +02:00
mwiegand
d351bcbee5
feat(l4d2-web): script overlay UI
Adds the script type to the create-overlay modal (with an admin-only
system-wide checkbox) and a script-section to the detail page: textarea
for the bash body, Save / Rebuild / Wipe buttons, last_build_status
badge, latest-build-job link, and a Wipe confirm modal. Removes the
GlobalOverlaySource block.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 15:50:36 +02:00
mwiegand
879c54cbda
refactor(l4d2-web): drop refresh_global_overlays from scheduler
GLOBAL_OPERATIONS becomes {"install", "refresh_workshop_items"}.
Removes refresh_global_overlays_running from SchedulerState and the
_run_refresh_global_overlays dispatch. Drops dead test cases and pins
GLOBAL_OPERATIONS contents.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 15:45:34 +02:00
mwiegand
92d6ebbe82
feat(l4d2-web): managed global map overlays with daily refresh
Adds two managed system overlays (l4d2center-maps, cedapug-maps) that
fetch curated map archives from upstream sources and reconcile addons
symlinks for non-Steam maps. A daily systemd timer enqueues a coalesced
refresh_global_overlays worker job; downloads, extraction, and rebuilds
run in the existing job worker and surface in the job log UI.

Schema: GlobalOverlaySource / GlobalOverlayItem / GlobalOverlayItemFile
plus nullable Job.user_id so system jobs render as "system" in the UI.
The new builder reconciles symlinks against the per-source vpk cache
and leaves foreign symlinks untouched. Initialize-time guard refuses
to mount a partial overlay if any expected vpk is missing from cache.

Refresh service uses shutil.move to handle EXDEV when /tmp and the
cache live on different filesystems.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 08:05:14 +02:00
mwiegand
ee144fad96
feat(l4d2-web): add server creation form 2026-05-06 19:41:04 +02:00
mwiegand
a347829608
feat(l4d2-web): add job pages and cancellation 2026-05-06 15:05:13 +02:00
mwiegand
91d042cf33
feat(l4d2-web): execute queued lifecycle jobs 2026-05-06 14:08:18 +02:00
mwiegand
0aca36506f
feat(l4d2-web): add login page and safe redirects 2026-05-06 12:52:22 +02:00
mwiegand
4b326736fe
feat(l4d2-web): add admin landing and system pages 2026-05-06 12:09:36 +02:00
mwiegand
feab09db07
feat(l4d2-web): add form-based blueprint editor 2026-05-06 12:09:08 +02:00
mwiegand
71004a9deb
feat(l4d2-web): add server pages and lifecycle forms 2026-05-06 12:08:19 +02:00
mwiegand
881b6635f9
feat(l4d2-web): add neutral shell and theme tokens 2026-05-06 12:06:23 +02:00
mwiegand
288eda7c37
chore(l4d2): flatten component layout 2026-05-05 23:47:06 +02:00
Renamed from components/l4d2-web-app/tests/test_pages.py (Browse further)