|
| 1 | +# 🤖 Code Agents - DevOps ITKsites |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +**DevOps ITKsites** is an internal Symfony application for server and site |
| 6 | +registration/monitoring at ITK Dev. It receives `DetectionResults` from the |
| 7 | +[ITK sites server harvester](https://github.com/itk-dev/devops_itkServerHarvest) |
| 8 | +and processes them asynchronously to track servers, sites, domains, Docker |
| 9 | +images, packages, modules, CVEs, and git repositories. |
| 10 | + |
| 11 | +## Technology Stack |
| 12 | + |
| 13 | +- **Language**: PHP 8.4+ (Symfony 7.3) |
| 14 | +- **API**: API Platform 4.0 (REST) |
| 15 | +- **Admin UI**: EasyAdmin 4.x |
| 16 | +- **Database**: Doctrine ORM 3.x / DBAL 4.x with MariaDB |
| 17 | +- **Messaging**: Symfony Messenger (AMQP/RabbitMQ) |
| 18 | +- **Auth**: OpenID Connect (`itk-dev/openid-connect-bundle`) |
| 19 | +- **Frontend**: Webpack Encore, Stimulus.js |
| 20 | +- **Testing**: PHPUnit 11+ |
| 21 | +- **Code Quality**: PHP-CS-Fixer, PHPStan, Rector |
| 22 | + |
| 23 | +## Architecture |
| 24 | + |
| 25 | +```mermaid |
| 26 | +graph TD |
| 27 | + A[Harvester] -->|POST DetectionResult| B[API Platform REST endpoint] |
| 28 | + B --> C[Symfony Messenger] |
| 29 | + C --> D[Async Message Handlers] |
| 30 | + D --> D1[DirectoryHandler] |
| 31 | + D --> D2[DockerImageHandler] |
| 32 | + D --> D3[DrupalHandler] |
| 33 | + D --> D4[GitHandler] |
| 34 | + D --> D5[NginxHandler] |
| 35 | + D --> D6[SymfonyHandler] |
| 36 | + D1 & D2 & D3 & D4 & D5 & D6 --> E[Doctrine ORM] |
| 37 | + E --> F[MariaDB] |
| 38 | + F --> G[EasyAdmin UI] |
| 39 | +``` |
| 40 | + |
| 41 | +### Key Directories |
| 42 | + |
| 43 | +| Directory | Purpose | |
| 44 | +|---|---| |
| 45 | +| `src/Entity/` | ~20 Doctrine entities (Server, Site, Domain, Installation, Package, DockerImage, Advisory, etc.) | |
| 46 | +| `src/Handler/` | DetectionResult handlers (Directory, Docker, Drupal, Git, Nginx, Symfony) | |
| 47 | +| `src/MessageHandler/` | Async message processing (PersistDetectionResult, ProcessDetectionResult) | |
| 48 | +| `src/Admin/` | EasyAdmin CRUD controllers | |
| 49 | +| `src/ApiResource/` | API Platform resource definitions | |
| 50 | +| `src/Service/` | Factories (PackageVersion, ModuleVersion, Advisory) and export services | |
| 51 | +| `src/Repository/` | Doctrine repositories | |
| 52 | +| `config/packages/` | Bundle configurations | |
| 53 | +| `migrations/` | Doctrine migrations | |
| 54 | +| `fixtures/` | Hautelook/Alice test fixtures | |
| 55 | +| `tests/` | PHPUnit tests (Api, Controller, MessageHandler) | |
| 56 | + |
| 57 | +### Data Flow |
| 58 | + |
| 59 | +All analyzed data (sites, installations, domains, packages, etc.) can be |
| 60 | +truncated and rebuilt by replaying DetectionResults. Manually maintained data |
| 61 | +(Servers, OIDC setups, Service Certificates) is separate and must be preserved. |
| 62 | + |
| 63 | +## Development Environment |
| 64 | + |
| 65 | +```sh |
| 66 | +# Start services (MariaDB, PHP-FPM 8.4, Nginx, Mailpit) |
| 67 | +docker compose pull && docker compose up --detach |
| 68 | + |
| 69 | +# Install dependencies |
| 70 | +docker compose exec phpfpm composer install |
| 71 | + |
| 72 | +# Run migrations |
| 73 | +docker compose exec phpfpm bin/console doctrine:migrations:migrate --no-interaction |
| 74 | + |
| 75 | +# Load fixtures |
| 76 | +docker compose exec phpfpm composer fixtures |
| 77 | + |
| 78 | +# Login as admin (after fixtures) |
| 79 | +docker compose exec phpfpm bin/console itk-dev:openid-connect:login admin@example.com |
| 80 | + |
| 81 | +# Process message queues |
| 82 | +docker compose exec phpfpm composer queues |
| 83 | + |
| 84 | +# Build frontend assets |
| 85 | +docker compose run --rm node yarn install && docker compose run --rm node yarn build |
| 86 | +``` |
| 87 | + |
| 88 | +## Quality Checks |
| 89 | + |
| 90 | +All commands run inside Docker containers: |
| 91 | + |
| 92 | +```sh |
| 93 | +# PHP coding standards (PHP-CS-Fixer) |
| 94 | +docker compose exec phpfpm composer coding-standards-check |
| 95 | +docker compose exec phpfpm composer coding-standards-apply |
| 96 | + |
| 97 | +# PHPUnit tests (creates test DB, runs migrations, executes tests) |
| 98 | +docker compose exec phpfpm composer tests |
| 99 | + |
| 100 | +# Frontend coding standards |
| 101 | +docker compose run --rm node yarn coding-standards-check |
| 102 | + |
| 103 | +# API spec export (must be committed) |
| 104 | +docker compose exec phpfpm composer update-api-spec |
| 105 | +``` |
| 106 | + |
| 107 | +## CI/CD |
| 108 | + |
| 109 | +### GitHub Actions (`pr.yaml`) |
| 110 | + |
| 111 | +Pull requests run these checks: |
| 112 | + |
| 113 | +1. **Composer validation** - validates and installs (prod + dev) |
| 114 | +2. **Doctrine schema validation** - migrations + schema check against MariaDB |
| 115 | +3. **PHP-CS-Fixer** - coding standards |
| 116 | +4. **PHPUnit** - unit/integration tests with MariaDB |
| 117 | +5. **API spec validation** - ensures exported OpenAPI spec is up to date |
| 118 | +6. **Fixtures** - verifies fixtures load successfully |
| 119 | +7. **Asset build** - verifies frontend assets compile |
| 120 | +8. **Changelog** - ensures CHANGELOG.md is updated |
| 121 | + |
| 122 | +### Woodpecker CI (deployment) |
| 123 | + |
| 124 | +- `stg.yml` - Deploys to staging on push to develop |
| 125 | +- `prod.yml` - Deploys to production on release (Ansible playbook, runs migrations + transport setup) |
| 126 | + |
| 127 | +## PR Guidelines |
| 128 | + |
| 129 | +- PRs must link to a ticket |
| 130 | +- Code must pass all CI checks (tests, coding standards, static analysis) |
| 131 | +- CHANGELOG.md must be updated |
| 132 | +- UI changes require screenshots |
| 133 | +- Base branch: `develop` |
| 134 | + |
| 135 | +## Important Conventions |
| 136 | + |
| 137 | +- Entity classes extend `AbstractBaseEntity` (provides `id`, `createdAt`, `updatedAt`) |
| 138 | +- Detection handlers implement `DetectionResultHandlerInterface` |
| 139 | +- Handlers are auto-tagged and injected via tagged iterator in `services.yaml` |
| 140 | +- Async processing uses Symfony Messenger with AMQP transport |
| 141 | +- Environment-specific config goes in `.env.local` (not committed) |
| 142 | +- API specs (`public/api-spec-v1.yaml` and `.json`) must be regenerated and committed when API changes |
0 commit comments