Skip to content

feat: base assistant detail page (#20)#68

Open
martinydeAI wants to merge 5 commits into
feature/issue-14-assistant-base-entityfrom
feature/issue-20-assistant-details
Open

feat: base assistant detail page (#20)#68
martinydeAI wants to merge 5 commits into
feature/issue-14-assistant-base-entityfrom
feature/issue-20-assistant-details

Conversation

@martinydeAI

Copy link
Copy Markdown
Collaborator

Summary

Base assistant detail page at GET /assistant/{id}. Renders the
fields 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-merge accordingly.

What lands

  • App\Controller\AssistantController::show — single action, route
    app_assistant_show. Symfony's MapEntity converter resolves
    {id}Assistant and 404s on a missing row.
  • templates/assistant/show.html.twig — extends base.html.twig,
    uses the existing Eyebrow / Box components, and reads from the
    assistant.detail.* translation keys added under the existing
    security pattern in translations/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:

  • Export entry point → #22
  • System prompt + parameters → #14
    (richer scope)
  • Organisation / author display → ADR 005 +
    #65
  • Back-link to a real catalogue → #15;
    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

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>
@martinydeAI martinydeAI added the do-not-merge Block merging until external dependency lands label Jun 15, 2026
martinydeAI and others added 4 commits June 15, 2026 08:45
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do-not-merge Block merging until external dependency lands

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant