Upgrade symfony8#147
Merged
Merged
Conversation
Complete modernization of Intaro Pinboard: Framework & runtime: - Silex → Symfony 8 (PHP 8.5, Doctrine DBAL 4, Twig 3, Symfony Console) - MySQL 5.x → MySQL 8.0 / 8.4 LTS (Pinba engine ported by XOlegator/pinba_engine) - pnpm + Webpack Encore for frontend assets Architecture: - Doctrine migrations replace legacy schema management - DB-based and file-based user authentication (APP_AUTH_USER_SOURCE) - 12-step aggregation pipeline via `php bin/console aggregate` - Email notifications and per-server thresholds Docker: - Public single-container image: xolegator/pinboard (nginx + php-fpm + supercronic) - docker-compose.public.yml for quick-start via Docker Hub - Dev stack via Makefile (make up / make up84 / make up80) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Restore CHANGELOG with v2.0 entry summarising the Symfony 8 rewrite - Restore LICENSE (MIT, 2014–2026) - composer.json: add name, description, homepage, authors, support, license - security.yaml: fix critical auth bug — access_control had ROLE_USER rule commented out, allowing unauthenticated access to the entire application - migrations 124237/124315/124434: replace debug InnoDB engine with correct ENGINE=PINBA and remove temporary commented-out code left from development - migration 20260309173000: make idempotent — skip if tables already have PINBA engine (new installs with fixed migrations don't need the repair step) - docs/: translate all Russian docs to English (configuration, deployment, standards, testing, README index) - README.md: fix APP_AUTH_USER_SOURCE default value, add upgrade-from-1.x section, correct license reference to MIT - Remove MailerController test skeleton (not needed in production) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Old loginAction() method (with Russian comments) duplicated app_login. Also removes the unused Request import. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Login template now extends base.html.twig instead of being standalone - Form is rendered in a centered card (max-width 400px on desktop, full-width with side padding on mobile) using Bootstrap card + flex layout - Added .login-page and .login-card CSS rules to app.scss - base_url is now a Twig global via twig.yaml (APP_BASE_URL env var) so SecurityController no longer needs to pass it explicitly; also fixes any other future controller that might forget to pass it Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ig files parameters.yml.dist is the committed template for file-based auth; parameters.yml (with real password hashes) stays gitignored. Removed parameters.yml.dist from gitignore — it was incorrectly excluded by the Symfony default .gitignore. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Redis connection string (potentially with password) goes in .env.local; adapter choice stays in cache.yaml as commented examples. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… env Symfony DI compiles service references statically; env vars cannot select a cache adapter. REDIS_URL (connection string) stays in env as intended. Document this constraint inline so deployers know editing cache.yaml is correct. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The `hosts` field in parameters.yml was loaded into FileUser but never enforced — all authenticated users could see all servers. Restored filtering in three places: - BeforeController: server list in the navigation menu - IpmReportByServerNameRepository / MainController: server index page - ServerController: 403 guard on every server action (overview, timers, statuses, req-time, mem-usage, cpu-usage, live) DB users (APP_AUTH_USER_SOURCE=db) are unrestricted as before — the User entity has no hosts field. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…oreController BeforeController is instantiated manually via `new` (not via DI), so $this->getUser() / $this->container are never initialized — causing "must not be accessed before initialization" on every page. Fix: callers (ServerController, MainController) resolve the regexp from their own properly-injected $this->getUser() and pass it to actionBefore(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously hosts filtering only worked for file-based auth (FileUser). DB users (User entity) always saw all servers. Changes: - User entity: add nullable `hosts` VARCHAR(500) column - Migration Version20260524190059: ALTER TABLE user ADD hosts - AddUserCommand: save hosts argument for DB users (was ignored before) - Utils::getUserHostsRegexp(): handle both FileUser and DB User - docs/configuration.md: document hosts argument for both auth modes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add UtilsAccessTest: 12 cases covering getUserHostsRegexp() and userCanAccessServer() for null user, FileUser, DB User, wildcard, alternation patterns - SwitchableUserProviderTest: createMock → createStub for repository stubs without expectations (fixes PHPUnit 13 notices) - Migrate phpunit.xml.dist to current schema (removes deprecation warning) - CS Fixer: sort imports in ServerController Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Restore HAVING cnt > 10: was temporarily removed for local testing
(comment said "убрал для теста"), now back as intended production behaviour
- Remove commented-out route #[Route('/before')] with "Не в том месте" note
- Remove commented-out old SQL variant (superseded by restored query)
- Remove speculative caching TODO comment
- Remove commented-out Silex-era $app['menu'] assignment
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New users were confused because: - README said "data appears after 15 min" — true for the main dashboard - Navigation menu requires 10 aggregation cycles (~2.5 h) due to HAVING cnt > 10 filter, which was not documented anywhere Added a clear table in README.md (Quick start), docs/deployment.md (new "Data visibility timeline" section), and a cross-reference in docs/docker.md. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
base_url is already a Twig global (APP_BASE_URL env var, set in twig.yaml). Passing it as a template variable overrides the global with a hardcoded '/' — defeating the purpose of APP_BASE_URL entirely. The same pattern exists in ServerController and TimerController and will be cleaned up there too. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…in TimerController - Remove all 'base_url' => '/' overrides (ServerController ×7, TimerController ×1) that shadowed the APP_BASE_URL Twig global - Fix TimerController::buildMenu() missing hostsRegexp — users with restricted hosts were seeing all servers in the nav menu on timer pages - Drop unused 'date' param from getRequestById req_time branch (active SQL never used :date; only the commented-out variant did) - Remove Silex-era commented fetchAll/executeQuery lines from ServerController (getHosts, getStatusesReview, getRequestPerSecReview, getRequestReview) - Simplify getReqTimeBorder signature ($app param unused since Silex removal) - Fix loose != to !== in getErrorPagesCount - Remove 'пока для теста' / 'Нужно переосмыслить' placeholder comments Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Delete AppFixtures.php — auto-generated empty stub that only called flush() with no persisted objects; provides no value - Inject UserPasswordHasherInterface into UserFixtures and hash the password at load time instead of storing a hardcoded bcrypt hash (fragile, algo-tied) - Set ROLE_ADMIN so the fixture user can actually use the admin panel - Use admin@example.com (consistent with project docs) and remove the auto-generated '// $product = new Product()' comment noise Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Display the current user's identifier (email / username) as a dropdown toggle on the right side of the top navigation bar. The dropdown contains a single 'Sign out' link pointing to the existing app_logout route. The block is guarded by `app.user is not null` so it does not appear on the login page or any unauthenticated context. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…om all repos Every repository file was missing declare(strict_types=1). Additionally, all auto-generated findByExampleField / findOneBySomeField placeholder stubs (produced by make:entity) were left in — these reference a fictional 'exampleField' and are pure boilerplate noise. None of them were ever wired to actual use in controllers or commands. Removed stubs from 21 files; added strict_types declaration to all 22 repository files (including the one fixed in the prior commit for IpmCpuUsageDetails). Custom methods in IpmReportByServerNameRepository (findAllServers) and UserRepository (upgradePassword) are untouched. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…attern
**Real improvements, not annotation noise:**
ServerController / TimerController — \$conn parameter removal:
All data-fetching methods took \$conn as first arg (always \$this->entityManager,
a Silex-era pattern). Removed the param, use \$this->entityManager directly,
made all internal data methods private. 91 of 142 level-6 errors came from
this one pattern.
AggregateCommand:
- isNotIgnore(\$host) → isNotIgnore(string \$host) — was genuinely untyped
- getBorderOutValues(\$db, \$servers) → fully typed with Connection + array types
- envCsv() return type narrowed to list<string>
- All notification-sending methods annotated with precise array shapes
Security layer:
- FileUser roles array: list<string> throughout (constructor, getRoles, setRoles)
- FileUserStorage loadUsers/replaceUsers/upsertUser/loadRawConfig/saveRawConfig
all annotated with array<string, mixed> / list<string>
- SwitchableUserProvider: @implements UserProviderInterface<FileUser|User>
Stopwatch:
- \$initTags and both tag-array parameters: array<string, string>
Utils::parseRequestTags:
- array|bool narrowed to array<string, mixed>|false (more accurate)
Controllers return types:
- actionLive(): Response (was missing)
- actionTimer(): parameters string-typed
- All SQL-result-returning methods annotated with list<array<string, mixed>>
or more specific shapes (getStatusesReview, getRequestPerSecReview, getTimersList)
PHPStan level: 5 → 6 (0 errors)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove Silex-era $conn parameters from all data methods (ServerController, TimerController) — methods are now private and use $this->entityManager directly - Add precise PHPDoc return types to all data methods in both controllers - Fix strtotime()|false → (int) cast for date() calls - Fix parseRequestTags() false-return handling in foreach loops - Fix getLivePages() list continuity after unset() via array_values() - Fix findGroupingTags() list return type via array_values() after unset() - Narrow FileUser::$identifier to non-empty-string via @param annotation; remove now-dead empty-string guard from constructor - Narrow SwitchableUserProvider::loadUserByIdentifier() — validate empty identifier at entry, skip empty array keys in fallback search loop - Add (string) casts in LoginFormAuthenticator for request->get() results - Add @var array<string,string> and (string) casts in Stopwatch::$initTags Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This was referenced May 27, 2026
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.
Complete modernization of Intaro Pinboard:
Framework & runtime:
Architecture:
php bin/console aggregateDocker: