feat: add base Assistant entity (#14)#67
Merged
Conversation
Wires up the application's first persistent identity and the login flow it gates. Installs Doctrine ORM + migrations + Symfony Security + dev-only MakerBundle and DoctrineFixturesBundle; switches doctrine.yaml to MariaDB and sets DATABASE_URL to the in-stack mariadb service. App surface: App\Entity\User (email, hashed password, roles), UserRepository with PasswordUpgraderInterface, App\Security\UserManager service that owns persistence + hashing, App\Controller\SecurityController exposing /login and /logout (form_login + declarative logout in security.yaml), Twig login form under templates/security/, and Danish translation keys under security.login.*. Two console commands sit on UserManager: app:user:create and app:user:change-password. App\DataFixtures\UserFixtures seeds alice@example.test and bob@example.test (password `password`) for local dev. Tests: 32 cases, 70 assertions, 100% coverage. UserManager unit-tested via KernelTestCase + a schema-reset trait; UserRepository's upgradePassword covered for the happy path and the foreign-user rejection; commands exercised through CommandTester; SecurityController's full /login + /logout + failed-login flow exercised through WebTestCase. Tests share tests/Support/ResetsDatabaseSchemaTrait which drops + recreates the db_test schema from ORM metadata in setUp. Docs: README gains a "Creating the first user" subsection covering migration, fixture load, and the two console commands. CHANGELOG entry under [Unreleased] / Added references #2. Closes #2. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PHPUnit's test environment uses Symfony's dbname_suffix to talk to a separate test database (db_test, optionally db_test_paratest_N). The itkdev/mariadb image only grants MYSQL_USER on MYSQL_DATABASE, so the test runner hits 'Access denied for user db@% to database db_test' on a fresh container. Mount .docker/mariadb/init/ as /docker-entrypoint-initdb.d/ so the included GRANT runs on first container initialisation. The wildcard is escaped as db\_test% so it only matches db_test... not unrelated names like dbXtest. Local devs with an already-initialised mariadb volume can either recreate the container (task compose -- down -v && task site-install) or apply the grant once manually. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds task db-prepare-test which re-applies the GRANT init SQL and ensures db_test exists. test and test-coverage depend on it so any local dev whose mariadb data volume predates the new /docker-entrypoint-initdb.d mount can run tests without first recreating the container. The grant is idempotent and only touches privileges — no data is read or written. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The earlier init script only granted privileges on db_test* but never created the database. CI runs vendor/bin/phpunit directly (not task test), so the db-prepare-test target couldn't backfill the CREATE either, and the Tests workflow failed with 'Unknown database db_test'. Folds CREATE DATABASE IF NOT EXISTS db_test into the init SQL so both fresh CI containers and the local db-prepare-test target reach the same state. The doctrine:database:create call in db-prepare-test is now redundant and removed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds doctrine:migrations:migrate as the final step of site-install so a fresh check-out's database schema lands automatically. Drops the manual 'Apply the database schema' snippet from the README's user-creation section since the schema is now in place by the time anyone reaches it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The 'Creating the first user' section doesn't need to remind readers that site-install ran migrations — that's documented in the section above. Removes the explanatory paragraph and leaves just the commands. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@symfony enables phpdoc_align with align=vertical, which padded @param and @return so columns lined up and pushed descriptions onto extra wrapped lines. Override to align=left and rewrite the verbose blurbs in the user-auth code so each tag fits on one line. Net 46 lines removed across UserManager, the two console commands, SecurityController, UserFixtures, and DevTemplateMarkerNodeVisitor (the last one fell out of the same cs-fixer pass). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
App\Entity\Assistant with the six base fields requested for now: id, title, description, languageModel, framework, and tags (a JSON list<string>). Migration creates the table. Constructor requires all non-tag fields; tags default to an empty list and array_values()-reindex on set so JSON serialises as an array, not an object. Per ADR 005, languageModel and framework are stored on the assistant as a snapshot (not a live reference through Organization) so an organisation changing its default later doesn't silently rewrite older catalogue rows. The Organization linkage itself, plus the richer #14 scope (system prompt, parameters, OpenWebUI mapping, versioning) and the tag display side of #16, are deferred to follow-on PRs. Tests: 35 cases, 86 assertions, 100% coverage. Two round-trip tests through the entity manager prove persistence + hydration of every getter/setter, plus a regression test for the tags array_values() reindex. Refs #14, #16. Depends on PR #59 (Doctrine + PHPUnit foundation). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 tasks
tuj
requested changes
Jun 15, 2026
…-assistant-base-entity
tuj
approved these changes
Jun 17, 2026
tuj
left a comment
Contributor
There was a problem hiding this comment.
Approved with a couple of comments
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
Adds the base
AssistantDoctrine entity with the six fields youasked for:
id,title,description,languageModel,framework,and
tags(a JSON list of strings). Repository + migration + a smalltest class that round-trips the entity through the entity manager to
keep us at 100 % coverage.
What this covers from existing issues
land here; the richer scope (system prompt / instructions,
parameters, OpenWebUI export field-mapping doc, file reference,
versioning) is deferred to follow-on PRs as planned.
stored as a
JSONlist on the assistant; the display + filter sidecomes later.
languageModelandframeworkarestored as snapshot strings on the assistant, matching the ADR's
snapshot-vs-live-derive decision.
Organizationis notintroduced here (you explicitly asked to skip it for now); when it
lands, the assistant gets an
organizationsM:N relation and thecreation flow can derive defaults from
user.organization.Changes
src/Entity/Assistant.php— entity with the six base fields,constructor that requires everything except tags,
array_values()reindex in
setTags()sotagsserialises as a JSON array (not anobject).
src/Repository/AssistantRepository.php— standardServiceEntityRepository<Assistant>.migrations/Version20260612120840.php— creates theassistanttable with the matching columns.
tests/Entity/AssistantTest.php— three cases:CHANGELOG.md— entry under[Unreleased] / AddedreferencingDefine assistant data model #14 and Tags and categories for assistants #16.
Test plan
task test-coverage→ 35 / 35 tests, 86 assertions, 100 %.task coding-standards-check→ green across PHP, Twig, YAML,JS, CSS, Markdown, Composer.
doctrine:migrations:migrate -napplies cleanly on a freshlocal DB.
Refs #14, #16. Depends on #59.
🤖 Generated with Claude Code