pyvelm v0.14.0¶
Release date: 2026-05-27
UX pass on the page shell and error surface, plus a development-only "nuke the database and re-run everything" command.
Highlights¶
Filament-style heading¶
The page title now renders as a prominent <h1> directly under the
breadcrumbs in the main column — the same shape Filament panels use.
The sidebar brand area shows only the logo + app name; the per-page
subtitle that used to sit there is gone.
┌───────────┬─────────────────────────────────────────┐
│ pyvelm │ Settings ▸ Workflows ▸ Email templates │
│ │ Email templates │ ← h1
│ Nav │ ──────────────────────────────────────│
│ … │ [list / form / kanban here] │
└───────────┴─────────────────────────────────────────┘
Pages override the title with {% block page_title %}…{% endblock %}
as before; the layout's default page_heading block emits the h1 +
optional subtitle. The handful of templates that overrode
page_heading themselves (none currently in-tree) are unaffected.
No record-count subtitle on list / kanban¶
The pager footer already shows the record total, so the heading
region no longer renders 5 records underneath the title. List views
pass subtitle="" and the OOB #pv-count-label swap in
list_rows.html / kanban_cards.html is gone. Pivot
(R rows × C columns) and graph (N groups) subtitles stay — they
describe the visualisation's structure, not a record count.
Styled error pages¶
Every 4xx / 5xx that hits a browser navigation now renders the same shaped card:
- One template
pyvelm/templates/error.html(centered card, status code badge, title, message, optional Retry-After countdown, Back / Home buttons). render_error_page(env, *, status_code, …)with per-status defaults for 400, 401, 403, 404, 405, 422, 429, 500, 501, 502, 503, 504. Unlisted codes roll up to a generic 4xx / 5xx flavour.- Two global FastAPI handlers in
pyvelm/web.py:@app.exception_handler(StarletteHTTPException)for raisedHTTPExceptions (including router 404s); a last-resort@app.exception_handler(Exception)for uncaught errors that becomes a styled 500 (with the traceback logged server-side). - The login throttle's 429 now returns the styled card with a live
countdown instead of
text/plain.
API / JSON / HTMX callers still get the same status code plus a
short text body (with Retry-After etc. preserved) — only browser
GETs under /web/... swap to HTML.
pyvelm db nuke — development-only reset¶
PYVELM_ENV=development \
PYVELM_DSN=postgresql://user:pass@localhost/dev \
pyvelm db nuke # interactive
pyvelm db nuke --yes # scripted
pyvelm db nuke --schema my_schema --yes
- Refuses to run when
PYVELM_ENV=production(pyvelm db nuke is disabled in production. Aborting.). - Prints the plan (DSN, schema, modules), prompts
Type nuke to continue:— anything else aborts.--yesskips the prompt. DROP SCHEMA public CASCADE; CREATE SCHEMA public;(override with--schema X) + re-grant onCURRENT_USERandPUBLIC.- Runs the same install pass as
pyvelm db migrateso every module's0_x_to_0_y.pymigration re-executes from scratch.
Use it on local dev databases, not anything you care about. There is no undo.
Upgrade¶
No schema or migration changes. After pip install -U:
- Hard-refresh your browser — the page heading shape changed and the layout template needs a fresh load.
- If you have a project that overrode
{% block page_heading %}, review it. The default now renders the h1 itself; you may want to drop your duplicate.
Also in this release¶
- The
dbsubparser help mentionsnukein its summary sopyvelm db --helpdiscoverability is correct. pyvelm/cli.pydocstring lists the new command alongsidemigrateandmigrate-fresh.docs/cli.mdships a dedicated paragraph ondb nukewith the full warning and a sample invocation.
Docs¶
- Email composer (unchanged)
- CLI reference:
pyvelm db nuke