Changelog

v2.1.2 — 2026/05/18

Fix Prefix admin

The admin route now accepts the provided prefix, routes are no longer hardcoded to /admin, for surcharge template a key {{ admin_prefix }} is necessary. For moment user /admin to prefix

Fix Admin bulk JS — checkboxes

`admin-bulk.js` now listens to `htmx:afterSwap` on `#list-content` and re-attaches all checkbox listeners (`#bulk-check-all` and `.bulk-check`). Previously, pagination and filter navigation via HTMX recreated DOM elements without event listeners, breaking the select-all checkbox.

Fix Admin middleware

now redirects to `{prefix}/login` using the configured prefix from `AdminState`. Unmatched routes pass through without triggering the redirect. * **`admin_prefix` missing from all admin template contexts:** `inject_admin_prefix` was not called in `inject_context` (shared handler entry point), causing `Variable admin_prefix not found` in templates. Now injected centrally so every admin view has access to it. * **`AdminRoutes` struct added:** `admins::routes(prefix)` now returns `AdminRoutes { router, prefix }` instead of a bare `axum::Router`, so the staging layer can propagate the prefix to `AdminConfig` automatically without a separate `.prefix()` call.

Fix FK resolution in admin list_display

New optional third element in list_display DSL: ["menu_id", "Menu", "menus.titre"] // column label table.target_column When provided, the generated list_fn automatically resolves FK integer IDs to human-readable labels in the list view. A single SELECT ... WHERE id IN (...) is issued per FK column, post-processed in memory via HashMap. Compatible with i32, i64 and UUID primary keys — uses CAST(id AS TEXT) on the SQL side and HashMap on the Rust side to be type-agnostic. FK columns are excluded from full-text search (searching a raw FK ID is meaningless). Files changed: runique/src/admin/daemon/parser.rs — FkDisplay struct, parse_list_display with optional third element runique/src/admin/daemon/generator.rs — FK resolution blocks in write_list_fn, updated write_search_conditions and build_display_chain

Fix derive_form

Time/Date/Datetime fields not saved in `partial_update`:** a `return None` arm at the top of the match in `generate_partial_update` was silently discarding all temporal fields before reaching the correct chrono-parsing arms added in 2.0.2 — those arms were unreachable dead code. The blocking arm is removed; `NaiveTime`, `NaiveDate`, `NaiveDateTime`, and `DateTime` now persist correctly via `admin_partial_update`.

Fix DSL `bulk_create: field

multi-record creation from a single form submit:** when `bulk_create: field_name` is declared on a resource in `admin!{}`, the generated `create_fn` splits `data[field_name]` by comma and inserts one record per value. Designed for `CheckboxField` multi-select (e.g. selecting multiple days of the week to create one `horaire` row per day).

Fix unique_together

`unique_together` generates `.unique_key()` — not found on `IndexCreateStatement`:** sea-query rc.27+ renamed `IndexCreateStatement::unique_key()` to `unique()`. The call in `generators.rs` is updated; `.unique_key()` on `ColumnDef` is unaffected. * **Enum tuple syntax `Variant = ("db_value", "Display")` ignored in migrations:** `parser_builder.rs` only handled `syn::Lit` directly after `=`. When the value was a tuple `(...)`, parsing failed and fell back to the Rust variant name (e.g. `'Entree'` instead of `'entree'`), causing SeaORM deserialization failures. Fixed with a `parenthesized!` branch that extracts the first string from the tuple.

Fix Fix Migration

`EihwazSessionsMigration`:** `ensure_admin_migration_positioned()` now inserts `EihwazSessionsMigration` between `EihwazUsersMigration` and `AdminTableMigration` in the generated `lib.rs`. The duplicate-filter and `FRAMEWORK_TABLE_PATTERNS` are updated accordingly. This table is use for persistance session after reload server

Fix Limitation extend!{}

For moment building the struct required for Sea-ORM is not yet supported, the search macro does not work either as it wraps Sea-ORM. Necessary a manual sql request. a table is create normaly to db but not for sea-orm

Fix Migration

`AdminTableMigration`:** `create_eihwaz_sessions_table()` is now called inside `AdminTableMigration::up()` (between `eihwaz_users_groupes` and `eihwaz_history`). The corresponding `DROP` is added to `down()`. New projects no longer need to add this migration manually.

Fix Open Redirect Vulnerability Fix

the flaw will be patched via a global middleware returning a 404 if used maliciously

Fix makemigrations

prompt befor DROP COLUMN, change type, nullable→NOT NULL

Fix parse_multipart

create_dir_all lazy if file existe

Ajouté Request` query/path helpers

four new methods on `runique::context::Request`: * `get_path(key) -> Option<&str>` — raw path parameter. * `get_path_as::(key) -> Option` — typed path parameter (parses via `FromStr`). * `get_query(key) -> Option<&str>` — raw query string parameter (replaces `from_url`). * `query::() -> Option` — deserializes the full query string into a struct via `serde_qs`; `raw_query` is now stored on `Request` at extraction time.

Ajouté CORS — with_cors() sur MiddlewareStaging

Add middleware CORS

Ajouté Trusted proxies

with_trusted_proxies(), injection ClientIp

Ajouté Permissions-Policy header

with_permissions_policy()

Ajouté QueryBuilder

order_by_random() , order_by_expr(expr, order), :one()

Ajouté macro , extend model

you can extend a runique table but not use for moment a macro search ! , must use a manual sql

Ajouté field phone

add a field phone on macro ,, generated

Ajouté m2m admin

on admin.rs , you can declared m2m

Ajouté PasswordResetConfig

you can modifis a runique template for reset password