MVP 2 — Complex properties & fine-grained customization
Property-based testing harness (BlackBox) Proposed
| Existing. | Example-driven tests only (integration fixtures + E2E declarative assertions). The BlackBox references (innmind.org/BlackBox) are recorded in @contexts/e2e.md as the future property-based testing basis. |
|---|---|
| Expected. | BlackBox wired as the property-based testing harness: deterministic runner (fixed seed), shrinking of failing cases, integrated into the Makefile and CI — probing the Collect & Computed pipeline (facts → formatter → render) and the CRUD write path with a rich generated dataset. |
| Prerequisites. | MVP 1 — CRUD lane operational (forms, delete): the harness varies data over the stabilized write + read paths, which requires the facts carried by PropertyMetadata (the Collect & Computed foundation) and the WidgetResolver (form mapping). |
| Analysis. | Opens MVP 2 deliberately: once the CRUD is operational is exactly when a rich data game puts the bundle to the test — invariants over the Collect & Computed pipeline (facts → deductions, render never throws, values round-trip) that example-driven tests cannot probe exhaustively. Deterministic by design (fixed seed), shrinks failures (BlackBox), and lands in CI + local make per the deterministic-tooling principle — never a one-shot check. The E2E assertion patterns already built are its base. |
Complex properties Proposed
| Existing. | Index/show already cover simple scalars and read-only associations; an embedded-fields metadata base is in place. |
|---|---|
| Expected. | Arrays, objects and all Doctrine association types handled in forms and display; embedded fields deepened. |
| Prerequisites. | MVP 1 — CRUD lane (type detection rework, WidgetResolver form mapping, forms, delete action). |
Fine-grained form customization Proposed
| Expected. | Per-property form customization (widget, constraints, labels), configurable like the formatters. |
|---|---|
| Prerequisites. | MVP 1 — Collect & Computed foundation and WidgetResolver (facts carried by PropertyMetadata). |
Richer formatters Proposed
| Expected. | Four small stories: address-to-map, color picker, calendar, multi-select. |
|---|---|
| Prerequisites. | MVP 1 — Minimal design decision: they require JS, blocked by the design lane. |
JSON output Proposed
| Existing. | HTML via the twig responders; the headless JSON rendering is already an interface in germ. |
|---|---|
| Expected. | JSON endpoints — scope (endpoints, shape, media-type) and timing to decide. |
| Prerequisites. | MVP 1 — CRUD lane. |
Navigation between related entities Proposed
| Expected. | Navigate from one entity to its related ones (UX open: breadcrumbs? linked pages?). |
|---|---|
| Prerequisites. | MVP 1 — CRUD lane. |
In-admin documentation Proposed
| Expected. | Developer help embedded in the admin pages. |
|---|---|
| Prerequisites. | Coupled to the design lane — to decide. |
Pagination Proposed
| Existing. | Index::__invoke() appelle $repository->findAll() — toutes les entités sont chargées en mémoire, sans limite ni offset. Pas de paramètre de page dans l'URL, pas de contrôle de la taille de page. |
|---|---|
| Expected. | La page index affiche les entités par pages. La taille de page est configurable par entité (config karross) avec une valeur par défaut raisonnable (25). L'état de la page courante est dans l'URL (?page=2 ou /page/2) — bookmarkable, partageable. Le repository utilise Query::setMaxResults()/setFirstResult() au lieu de findAll(). Les liens previous/next sont rendus dans le template. |
| Prerequisites. | None. |
| Plan. |
|
Property visibility & ordering Proposed
| Existing. | Toutes les propriétés Doctrine (champs + associations) sont toujours affichées, dans l'ordre de ClassMetadata::getFieldNames() puis getAssociationNames(). Pas de mécanisme pour masquer une propriété, en afficher certaines uniquement en index ou en show, ou changer l'ordre des colonnes. Les templates itèrent entityMetadata.getProperties() sans filtre. |
|---|---|
| Expected. | Par entité, contrôle des propriétés affichées en index et en show, et de leur ordre. Le défaut raisonnable reste « tout afficher dans l'ordre Doctrine » — l'override est optionnel. La config porte un tableau ordonné de noms de propriétés ; seules les propriétés listées sont rendues, dans l'ordre donné. Un écran « password » ou « hashedToken » peut être masqué de l'index tout en restant présent en show. |
| Prerequisites. | None. |
| Plan. |
|
Database sort Proposed
| Existing. | Aucun tri — les entités sont rendues dans l'ordre de findAll() (ordre d'insertion/ID par défaut Doctrine). Pas de liens de tri dans les en-têtes de colonne, pas de paramètre de tri dans l'URL. |
|---|---|
| Expected. | Tri par colonne en index, au niveau DB via Doctrine QueryBuilder (pas en mémoire). L'état du tri est dans l'URL (query string : ?sort=title&direction=asc) — bookmarkable. Les en-têtes de colonne sont des liens cliquables qui basculent asc/desc. Tri sur les champs scalaires ; les associations et les colonnes composées restent non triables par défaut. |
| Prerequisites. | Pagination (le tri est architecturalement coupled au paginated query). |
| Plan. |
|
Per-property filters Proposed
| Existing. | Aucun filtre — l'index affiche toutes les entités sans mechanisme de sélection. Pas de FilterResolver, pas de chaîne de résolution pour les filtres comme il en existe pour les formatters et les templates. |
|---|---|
| Expected. | Filtres par propriété en index, avec un FilterResolver en 3e chaîne parallèle (après FormatterResolver + PropertyTemplateResolver). Chaque type Doctrine sait produire un filtre : boolean → select Oui/Non/Tous ; string → texte ; integer/decimal → plage ; datetime → plage de dates ; enum → select des cases. L'état des filtres est dans l'URL (query string) — bookmarkable. Les filtres sont combinés avec AND. La config peut restreindre les propriétés filtrables par entité. |
| Prerequisites. | Pagination + Collect & Computed (les faits portés par PropertyMetadata pilotent la résolution du filtre). |
| Plan. |
|
Reference documentation — update Proposed
| Existing. | The reference page created in MVP 1 covers the base configuration surface (routes, formatters, type overrides, template overrides). |
|---|---|
| Expected. | Extend the reference with the MVP-2 surface: per-property form customization, widget renderers, richer formatters, JSON output, pagination, visibility, sort, filters. |
| Prerequisites. | This MVP's Fine-grained form customization + Richer formatters: the reference documents the config surface once it stabilizes. |