Imported from sumocoders/Framework-User-Implementation-Example (
AGENTS.md). Install upstream withnpx skills add sumocoders/Framework-User-Implementation-Example. Copyright stays with the author.
Reference repository: https://github.com/sumocoders/Framework-User-Implementation-Example.git
All commands and paths in these steps assume the current working directory is the project root.
-
Ask the user which optional features to remove:
- No profile page: skip
src/Controller/User/ProfileController.php,templates/user/profile.html.twig, and drop the profile navigation entry intemplates/user/_profile_navigation.html.twig; skip theuser_profileaccess_control route in step 5. - No registration: skip
src/Controller/User/RegisterController.php,src/Message/User/RegisterUser.php,src/MessageHandler/User/RegisterUserHandler.php,templates/user/register.html.twig. Apply these exclusions in every later step that copies or references the affected files/routes.
- No profile page: skip
-
Install packages:
symfony composer require 2fa scheb/2fa-backup-code scheb/2fa-totp scheb/2fa-trusted-device endroid/qr-code- If
Scheb\TwoFactorBundle\SchebTwoFactorBundle::classis missing fromconfig/bundles.php, add it:Scheb\TwoFactorBundle\SchebTwoFactorBundle::class => ['all' => true]
- If
-
Copy from
./tempinto the project, preserving paths (skip files excluded in step 2):config/packages/scheb_2fa.yamlconfig/routes/scheb_2fa.yamlconfig/reference.phptranslations/(Dutch translation files used by the User/2FA templates)
-
Check
config/packages/security.yaml:- If it already has a firewall with a proper user provider (not just
in_memory), add inside that firewall definition:
- If it already has a firewall with a proper user provider (not just
two_factor:
auth_form_path: 2fa_login
check_path: 2fa_login_check
trusted_parameter_name: _trusted
- If there is no suitable firewall (e.g. only an
in_memoryprovider, or no user provider at all), replace the firewall/provider config entirely with the reference project's full expected block from./temp/config/packages/security.yaml, adapted to this project's User entity, then add thetwo_factorblock above. - Add to
access_control(omit routes tied to features excluded in step 2):
- { route: '2fa_login', roles: IS_AUTHENTICATED_2FA_IN_PROGRESS }
- { route: '2fa_login_check', roles: IS_AUTHENTICATED_2FA_IN_PROGRESS }
- { route: 'user_2fa', roles: ROLE_USER }
- { route: 'user_2fa_qrcode', roles: ROLE_USER }
- { route: 'user_password', roles: ROLE_USER }
- { route: 'user_profile', roles: ROLE_USER }
-
Copy from
./temp, preserving directory structure (skip files/dirs excluded in step 2):src/Command/Usersrc/Controller/Usersrc/DataTransferObject/Usersrc/Entity/Usersrc/Exception/Usersrc/Form/Usersrc/Message/Usersrc/MessageHandler/Usersrc/Repository/Usersrc/Validator/Usersrc/ValueObject/Usersrc/Securitytemplates/usertests/Entity/Usertests/MessageHandler/Usertests/Repository/Usertests/Validator/Usertests/ValueObject/User
-
Copy
src/EventListenerfrom./tempinto the project'ssrc/directory. -
Before touching migrations, check whether this project already has a
Userentity, ausertable, or an existing migration that touches either. If so, stop and ask the user how to proceed (reset the test/dev database, merge the migrations manually, or abort) instead of migrating blindly. -
Determine this project's real migrations path and namespace from
config/packages/doctrine.yaml(e.g.migrations/with namespaceDoctrineMigrations, not necessarilysrc/Migrations/with namespaceMigrations). Copy the files from./temp/src/Migrations/into that path, adjusting the namespace declaration in each copied migration to match. Then run:symfony console doctrine:migrations:migrate -
From the project root, remove the temp folder:
rm -rf ./temp -
Run
symfony php vendor/bin/phpstan analyse,vendor/bin/mago lint,vendor/bin/mago analyse, and the project's test suite. Fix issues surfaced by the integration, including known ones:- Paginator usages missing their generic type annotation (
@var Paginator<User>or equivalent). - An orphaned
RegisterTypeleft behind if registration was excluded in step 2.
- Paginator usages missing their generic type annotation (