52 changes:
- A select and a pager that need no form around them
- Four legacy input classes become one
- One search box over many entities
- A model save cost 1358 milliseconds
- Two flags that keep a migration honest
- reset() left the page where the next request would find it
- The form field now uses the controls
- Nine readers of a stream that can only be read once
- An API endpoint's status code was untestable
- A flash that worked once per process
- A permanent cache entry was deleted by the next sweep
- The dashboard's JSON endpoints returned a web page too
- The backup codes a user saved were never the stored ones
- Adding a member to an organization was impossible
- Any signed-in account could rewrite the system settings
- The lockout settings configured nothing
- The tailwind scaffold theme is a daisyUI theme
- A view directory you half-own rendered a page shell
- An argument a method does not declare is dropped silently
- The datatable search that could not be slowed down, and the columns that were all searched the same way
- Every page after a sign-in page lost its header
- Seventy-nine queries had lost the table prefix
- The Redis cache listing read a key nothing writes
- Vendored assets that were still remote
- A page could not call its own API
- One palette, every UI system
- The administration area has its own directory
- Six filings from one project, all small and all silent
- The palette moves under app/themes/
- Two guides that had become their own history
- A generated screen the vanilla stacks could not reach
- Every breadcrumb in the area pointed at /adminusers
- URL is the administration area, sURL is the site
- Organizations had no way to look at one
- A column filter per column, on the lists that need one
- What a usertype means, and how an application changes it
- Row actions are icons, and the row is a link
- The log viewer's own endpoints 404'd inside its iframe
- Everything the framework knows about a user, on the user's screen
- Per-user settings, and permissions edited where the user is
- A screen for the message templates the framework already had
- New-sign-in alerts got a site policy
- A login left the previous session's token valid for a month
- One definition of the guard every admin screen opens with
- What each usertype may do, written down and on a screen
- A correct password was refused, and bcrypt had been dropping characters
- No language was ever selected
- The administration area may be in another language than the site
- A second factor that needs nothing set up in advance
- A new device can be made to prove something, not just reported
- A second factor an application can bring its own of
- Seven account-security switches, every one off until asked for
15 changes:
- Wrote 1 path(s), and every word of it was true
- The JSON renderer decided every response was fine
- A failed list query killed the request
- The controller a model needs costs 1.5 microseconds
- The one place a shared layout could not be
- A comparison table is a claim too
- The redirect the guide promised
- The cache category was accepted and discarded
- A marker nothing flipped
- The HTML document could not say what page it was
- getData() and the columns it never returned
- An alarm that stays rare
- A column that described data nobody wrote
- Fourteen tabs do not fit
- Two things that did not complain
6 changes:
- Five rolled-up views were frozen on every database without TimescaleDB
- A model may give
load() whatever parameters it needs
- Five developer panels had been empty for years, and nothing said why
- The rate limiter counted the proxy, and counted it badly
- A human check that prices spam instead of pretending to detect it
getInstance() is a factory, and two call sites forgot
16 changes:
pramnos init checks both Docker ports before proposing one
init scaffolds a working SPA — Svelte + daisyUI, Vite, Vitest and Docker
- Files the container writes now belong to you, not to root
- SPA follow-ups: the dev server, the site root, and the docs generator
- The FK migration stops assuming the schema of tables it does not own
- The scaffolded SPA now actually talks to the API
create:crud builds the SPA half too
- A debug bar a SPA can actually use — and a guide for testing the front end
- Generated CRUD gets real authorisation — and
delete gets any at all
- A SPA project gets an administration screen
cache:clear no longer wipes every installation sharing the backend
- Signing in works, screens have URLs, and the SPA wears the project's colours
Permissions answers from whichever store the installation has
- One permission system, available to every project with users
timescale:ensure — repairing hypertables on a database that got TimescaleDB late
- The GDPR endpoints queried a table that does not exist
2 changes:
- Per-column search works again on server-side DataTables
- Serving init-less apps: migrations, capability accessors, test DB, daemon status
8 changes:
- Column comments are now applied when altering a table
- Partial indexes and column ordering in the schema builder
- Native enum types in the schema builder
- Attribute-routed controller actions now dispatch
- Auth controller tests no longer drop the shared
users table
- The test suite no longer leaves an
app/ directory in the repo
- Realtime: pluggable SSE + WebSocket backplane
- Cross-cutting improvements: flat-key cache, log output modes, media alpha fix