feat: base assistant detail page (#20)#68
Open
martinydeAI wants to merge 5 commits into
Open
Conversation
Adds App\Controller\AssistantController with a single show action mapped at GET /assistant/{id}. Symfony's MapEntity converter resolves the route id to an Assistant (404 on unknown id). The Twig template renders the base fields the entity currently carries: title, description, framework + language model in a runtime box, and tags in a tag box when non-empty. Uses the existing Eyebrow / Box components and the Danish translation file (security pattern: keys under assistant.detail.*).
Out of scope per the entity's current shape: export entry point (#22), system prompt preview, parameters, organisation / author display, back-link to a real catalogue (#15) — back currently points at the frontpage. These hook in as the underlying data lands.
Tests: 38 cases, 100 assertions, 100% coverage. WebTestCase exercises the happy path with tags, the no-tags variant (asserts the tags section is omitted), and the 404 path. Depends on PR #67 (base Assistant entity) which depends on PR #59.
Refs #20, #16.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Controllers stay thin per project conventions — the type signatures, attribute, and route name already describe what the action does. The descriptive blurb belonged on the (still-thin) service layer if anywhere; with no service yet, deleting reads cleaner than keeping placeholder docs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds an explicit paragraph under 'Controllers stay thin' so the convention demonstrated by stripping AssistantController's docblocks doesn't get re-added by a future session. The class name, route attribute, types, and return all carry the same information a class- or method-level docblock would — explanatory prose belongs on the service the controller delegates to. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
AssistantFixtures loads twenty assistants per doctrine:fixtures:load. Five are hand-written entries lifted from the AI Bibliotek prototype (Borgerservice-vejviser, Mødereferent, Journaliseringsassistent, Skole- og dagtilbudssvar, Tilsynsrapport-assistent) with detailed Danish descriptions and authentic kommune attribution in the description text. The remaining fifteen are generated from a fixed cartesian product of seven topics × ten kommuner × five language models, indexed by loop counter modulo each dimension — no randomness, so the same seed produces the same catalogue every run. Per ADR 005 the kommune attribution is woven into the description for now; it migrates to the Organization relation when that lands. Tests: 40 cases, 136 assertions, 100% coverage. Verifies the count, that the first five are the named authentic entries, that every generated row has a unique (title, description) signature and carries the kommune in the title, that the language model rotation reaches all five values, and that a second run on a fresh schema produces byte-for-byte identical titles. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
FrontpageController drops its SAMPLE_ASSISTANTS const and injects AssistantRepository. The rail iterates the five most-recently created Assistant rows (id DESC) and each card now links to /assistant/{id}. Stats: Assistanter and Sprogmodeller are computed via repository queries (count(\*), count distinct languageModel via a new repository helper); Kommuner stays a placeholder constant 10 until ADR 005 / #65's Organization entity lands. PHPDoc removed from the controller per the project convention.
Template: the existing CardRail:Card props (kommune / model / name / summary) are mapped to the Assistant entity's framework / languageModel / title / description for now; the kommune slot returns to a real organisation name once Organization lands.
Tests: 42 cases, 149 assertions, 100% coverage. FrontpageControllerTest now uses the schema-reset trait and covers three paths: empty DB still renders (with no card links), persisted assistants are linked by id and newest-first order is preserved, and the Assistanter + Sprogmodeller stats reflect the catalogue's actual count and distinct-LM cardinality.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Base assistant detail page at
GET /assistant/{id}. Renders thefields the entity actually carries today; the remainder of #20's
scope hooks in as the underlying data lands.
Built on top of PR #67
(base Assistant entity), which is itself on top of
PR #59 (Doctrine +
PHPUnit). Tagged
do-not-mergeaccordingly.What lands
App\Controller\AssistantController::show— single action, routeapp_assistant_show. Symfony'sMapEntityconverter resolves{id}→Assistantand 404s on a missing row.templates/assistant/show.html.twig— extendsbase.html.twig,uses the existing
Eyebrow/Boxcomponents, and reads from theassistant.detail.*translation keys added under the existingsecuritypattern intranslations/messages.da.yaml.tests/Controller/AssistantControllerTest.php— three cases:happy path with tags, no-tags variant (asserts the tags box is
omitted), and 404 for unknown id.
What this covers from #20
#20 wants name, description, organisation/author, tags, model,
parameters, system prompt, and an export entry point. PR #67's
entity only carries six base fields, so this PR delivers the
name + description + tags + model + framework half. Deferred for
follow-on PRs as the data appears:
(richer scope)
#65
currently links back to the frontpage as a placeholder.
Test plan
task test-coverage→ 38 tests, 100 assertions, 100 %.task coding-standards-check→ green across PHP, Twig, YAML,JS, CSS, Markdown, Composer.
/assistant/{id}renders title, description, runtime box(framework + model), and tags box when non-empty.
/assistant/{unknown_id}returns 404.Refs #20, #16. Depends on #67 (which depends on #59).
🤖 Generated with Claude Code