mirror of
				https://gitlab.com/Chill-Projet/chill-bundles.git
				synced 2025-10-31 17:28:23 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			392 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			392 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # Project Guidelines for Junie
 | |
| 
 | |
| ## Project Overview
 | |
| 
 | |
| Chill is a comprehensive web application built as a set of Symfony bundles. It is a case management system, for social work. The project consists of multiple specialized bundles that provide different functionalities:
 | |
| 
 | |
| - **ChillMainBundle**: Core bundles that provide the foundation of the application
 | |
| - **ChillPersonBundle**: Core bundles that provide the foundation of the bundles associated to person (which is the case for all other bundles)
 | |
| - **ChillCalendarBundle**: Calendar and scheduling functionality
 | |
| - **ChillDocStoreBundle** and **ChillDocGeneratorBundle**: Document management and generation
 | |
| - **ChillActivityBundle**, **ChillEventBundle**, **ChillTaskBundle**: Activity and task tracking
 | |
| - **ChillBudgetBundle**: Financial management
 | |
| - **ChillThirdPartyBundle**: Integration with external systems
 | |
| - **ChillCustomFieldsBundle**: Extensibility through custom fields
 | |
| - **ChillReportBundle**: Save arbitrary reports about persons
 | |
| - **ChillTicketBundle**: Record and track issues about persons
 | |
| 
 | |
| - And several other specialized bundles
 | |
| 
 | |
| ## Technology Stack
 | |
| 
 | |
| - **Backend**: PHP 8.3+, Symfony 5.4
 | |
| - **Frontend**: JavaScript/TypeScript, Vue.js 3, Bootstrap 5
 | |
| - **Build Tools**: Webpack Encore, Yarn
 | |
| - **Database**: PostgreSQL with materialized views. We do not support other databases.
 | |
| - **Other Services**: Redis, AMQP (RabbitMQ), SMTP
 | |
| 
 | |
| ## Project Structure
 | |
| 
 | |
| Note: This is a project that's existed for a long time, and throughout the years we've used multiple structures inside each bundle. When having the choice, the developers should choose the new structure.
 | |
| 
 | |
| The project follows a standard Symfony bundle structure:
 | |
| - `/src/Bundle/`: Contains all the Chill bundles. The code is either at the root of the bundle directory, or within a `src/` directory (preferred). See psr4 mapping at the root's `composer.json`.
 | |
| - each bundle comes with its own tests, either in the `Tests` directory (when the code is directly within the bundle directory (for instance `src/Bundle/ChillMainBundle/Tests`, `src/Bundle/ChillPersonBundle/Tests`)), or inside the `tests` directory, alongside the `src/` sub-directory (example: `src/Bundle/ChillWopiBundle/tests`) (this is the preferred way).
 | |
| - `/docs/`: Contains project documentation
 | |
| 
 | |
| Each bundle typically has the following structure:
 | |
| 
 | |
| - `Controller/`: Contains controllers
 | |
| - `Entity/`: Contains Doctrine entities
 | |
| - `Repository/`: Contains Doctrine repositories
 | |
| - `Resources/`: Contains views, translations, and public assets
 | |
| - `DependencyInjection/`: Contains service configuration
 | |
| - `Export/`: Contains services related to exports
 | |
| - `Security/`: Contains services related to security. Most of the time, those are new voters, and so on.
 | |
| 
 | |
| ### A special word about TicketBundle
 | |
| 
 | |
| The ticket bundle is developed using a kind of "Command" pattern. The controller fills a "Command," and a "CommandHandler" handles this command. They are saved in the `src/Bundle/ChillTicketBundle/src/Action` directory.
 | |
| 
 | |
| ## Development Guidelines
 | |
| 
 | |
| ### Building and Configuration Instructions
 | |
| 
 | |
| All the commands should be run through the `symfony` command, which will configure the required variables.
 | |
| 
 | |
| For assets, we must ensure that we use node at version `^20.0.0`. This is done using `nvm use 20`.
 | |
| 
 | |
| #### Initial Setup
 | |
| 
 | |
| 1. **Clone the Repository**:
 | |
|    ```bash
 | |
|    git clone <repository-url>
 | |
|    cd chill-bundles
 | |
|    ```
 | |
| 
 | |
| 2. **Install PHP Dependencies**:
 | |
|    ```bash
 | |
|    composer install
 | |
|    ```
 | |
| 
 | |
| 3. **Install JavaScript Dependencies**:
 | |
|    ```bash
 | |
|    nvm use 20
 | |
|    yarn install
 | |
|    ```
 | |
| 
 | |
| 4. **Configure Environment Variables**:
 | |
| 
 | |
|    - Create a `.env.local` file with minimal configuration
 | |
|    ```bash
 | |
|    echo "APP_ENV=dev" >> .env.local
 | |
|    ```
 | |
| 
 | |
| 5. Start the associated services (database, and so on):
 | |
|    ```bash
 | |
|    docker compose up -d
 | |
|    ```
 | |
| 
 | |
| 6. **Set Up the Database**:
 | |
|    ```bash
 | |
|    # Create the database
 | |
|    symfony console doctrine:database:create
 | |
| 
 | |
|    # Run migrations
 | |
|    symfony console doctrine:migrations:migrate
 | |
| 
 | |
|    # Load fixtures (optional)
 | |
|    symfony console doctrine:fixtures:load
 | |
|    ```
 | |
| 
 | |
| 7. **Build Assets**:
 | |
|    ```bash
 | |
|    nvm use 20
 | |
|    yarn run encore dev
 | |
|    ```
 | |
| 
 | |
| 8. **Start the Development Server**:
 | |
|    ```bash
 | |
|    symfony server:start -d
 | |
|    ```
 | |
| 
 | |
| #### Docker Setup
 | |
| 
 | |
| The project includes a Docker configuration for easier development:
 | |
| 
 | |
| 1. **Start Docker Services**:
 | |
|    ```bash
 | |
|    docker-compose up -d
 | |
|    ```
 | |
| 
 | |
| 2. **Access the Application**:
 | |
|    - The application will be available at `http://localhost:8000`
 | |
|    - PostgreSQL will be available at `localhost:5432`
 | |
|    - Redis will be available at `localhost:6379`
 | |
| 
 | |
| #### Building Assets
 | |
| 
 | |
| Before submitting any changes, you should build the project to ensure that all assets are properly compiled:
 | |
| 
 | |
| ```bash
 | |
| # For production
 | |
| yarn run encore production
 | |
| 
 | |
| # For development with hot-reloading
 | |
| yarn run encore dev --watch
 | |
| 
 | |
| # for development
 | |
| yarn run encore dev
 | |
| ```
 | |
| 
 | |
| #### Configuration Files
 | |
| 
 | |
| Key configuration files:
 | |
| 
 | |
| - `config/packages/*.yaml`: Symfony bundle configurations
 | |
| - `webpack.config.js`: Webpack Encore configuration
 | |
| - `composer.json`: PHP dependencies and scripts
 | |
| - `package.json`: JavaScript dependencies and scripts
 | |
| - `.env`: Default environment variables. Must usually not be updated: use `.env.local` instead.
 | |
| 
 | |
| ### Database migrations
 | |
| 
 | |
| Each time a doctrine entity is created, we generate migration to adapt the database.
 | |
| 
 | |
| The migration is created using the command `symfony console doctrine:migrations:diff --no-interaction --namespace <namespace>`, where the namespace is the relevant namespace for migration. As this is a bash script, remember to quote the `\` (`\` must become `\\` in your command).
 | |
| 
 | |
| Each bundle has his own namespace for migration (always ask me to confirm that command with a list of updated / created entities so that I can confirm to you that it is ok):
 | |
| 
 | |
| - `Chill\Bundle\ActivityBundle` writes migrations to `Chill\Migrations\Activity`;
 | |
| - `Chill\Bundle\BudgetBundle` writes migrations to `Chill\Migrations\Budget`;
 | |
| - `Chill\Bundle\CustomFieldsBundle` writes migrations to `Chill\Migrations\CustomFields`;
 | |
| - `Chill\Bundle\DocGeneratorBundle` writes migrations to `Chill\Migrations\DocGenerator`;
 | |
| - `Chill\Bundle\DocStoreBundle` writes migrations to `Chill\Migrations\DocStore`;
 | |
| - `Chill\Bundle\EventBundle` writes migrations to `Chill\Migrations\Event`;
 | |
| - `Chill\Bundle\CalendarBundle` writes migrations to `Chill\Migrations\Calendar`;
 | |
| - `Chill\Bundle\FamilyMembersBundle` writes migrations to `Chill\Migrations\FamilyMembers`;
 | |
| - `Chill\Bundle\FranceTravailApiBundle` writes migrations to `Chill\Migrations\FranceTravailApi`;
 | |
| - `Chill\Bundle\JobBundle` writes migrations to `Chill\Migrations\Job`;
 | |
| - `Chill\Bundle\MainBundle` writes migrations to `Chill\Migrations\Main`;
 | |
| - `Chill\Bundle\PersonBundle` writes migrations to `Chill\Migrations\Person`;
 | |
| - `Chill\Bundle\ReportBundle` writes migrations to `Chill\Migrations\Report`;
 | |
| - `Chill\Bundle\TaskBundle` writes migrations to `Chill\Migrations\Task`;
 | |
| - `Chill\Bundle\ThirdPartyBundle` writes migrations to `Chill\Migrations\ThirdParty`;
 | |
| - `Chill\Bundle\TicketBundle` writes migrations to `Chill\Migrations\Ticket`;
 | |
| - `Chill\Bundle\WopiBundle` writes migrations to `Chill\Migrations\Wopi`;
 | |
| 
 | |
| Once created the, comment's classes should be removed and a description of the changes made to the entities should be added to the migrations, using the `getDescription` method. The migration should not be cleaned by any artificial intelligence, as modifying this migration is error prone.
 | |
| 
 | |
| ### Guidelines related to code structure and requirements
 | |
| 
 | |
| #### Usage of clock
 | |
| 
 | |
| When we need to use a DateTime or DateTimeImmutable that need to express "now", we prefer the usage of
 | |
| `Symfony\Component\Clock\ClockInterface`, where possible. This is usually not possible in doctrine entities,
 | |
| where injection does not work when restoring an entity from a database, but usually possible in services.
 | |
| 
 | |
| In test, we use `\Symfony\Component\Clock\MockClock` which is an implementation of `Symfony\Component\Clock\ClockInterface`
 | |
| where we have full and easy control of the date.
 | |
| 
 | |
| ### Testing Information
 | |
| 
 | |
| The project uses PHPUnit for testing. Each bundle has its own test suite, and there's also a global test suite at the root level.
 | |
| 
 | |
| #### Use of mock in tests
 | |
| 
 | |
| ##### General mocking
 | |
| 
 | |
| For creating mock, we prefer using prophecy (library phpspec/prophecy).
 | |
| 
 | |
| ##### Useful helpers and tips that avoid creating a mock
 | |
| 
 | |
| Some notable implementations that are test helpers and avoid creating a mock:
 | |
| 
 | |
| - `\Psr\Log\NullLogger`, an implementation of `\Psr\Log\LoggerInterface`;
 | |
| - `\Symfony\Component\Clock\MockClock`, an implementation of `Symfony\Component\Clock\ClockInterface` (already mentioned above);
 | |
| - `\Symfony\Component\HttpClient\MockHttpClient`, an implementation of `\Symfony\Contracts\HttpClient\HttpClientInterface`;
 | |
| - When using `\Symfony\Component\Mailer\MailerInterface`, we can create the mock with "InMemoryTransport":
 | |
| 
 | |
|     ```php
 | |
|     use Symfony\Component\Mailer\Transport\InMemoryTransport;
 | |
|     use \Symfony\Component\Mailer\Mailer;
 | |
| 
 | |
|     $transport = new InMemoryTransport();
 | |
|     $mailer = new Mailer($transport);
 | |
| 
 | |
|     // After sending:
 | |
|     $messages = $transport->getSent(); // array of SentMessage
 | |
|     ```
 | |
| - When using `\Symfony\Contracts\EventDispatcher\EventDispatcherInterface`, we can use directly an instance of `\Symfony\Component\EventDispatcher\EventDispatcher`;
 | |
| 
 | |
| ##### When we prefer not creating a mock
 | |
| 
 | |
| - When we use Doctrine Entities related to the project, we prefer not to use a mock: we instantiate them directly (unless it requires too much code to write);
 | |
| 
 | |
| ##### Mocking final and readonly classes
 | |
| 
 | |
| Classes marked as final can't be mocked. To avoid that, either:
 | |
| 
 | |
| - we remove the `final` keyword from the class;
 | |
| - we extract an interface from the final class.
 | |
| 
 | |
| This must be a decision made by a human, not by an AI. Every AI task must abort with an explicit message in that case.
 | |
| 
 | |
| #### Running Tests
 | |
| 
 | |
| The tests are run from the project's root (not from the bundle's root).
 | |
| 
 | |
| ```bash
 | |
| # Run all tests
 | |
| vendor/bin/phpunit
 | |
| 
 | |
| # Run a specific test file
 | |
| vendor/bin/phpunit path/to/TestFile.php
 | |
| 
 | |
| # Run a specific test method
 | |
| vendor/bin/phpunit --filter methodName path/to/TestFile.php
 | |
| ```
 | |
| 
 | |
| When writing tests, only test specific files. Do not run all tests or the full
 | |
| test suite.
 | |
| 
 | |
| #### Test Structure
 | |
| 
 | |
| Tests are organized by bundle and follow the same structure as the bundle itself:
 | |
| 
 | |
| - Unit tests: Test individual components in isolation
 | |
| - Integration tests: Test components working together
 | |
| - Functional tests: Test the application from the user's perspective
 | |
| 
 | |
| #### Writing Tests
 | |
| 
 | |
| Tests should be placed in the appropriate bundle's test directory. For example, tests for the TicketBundle should be placed in `src/Bundle/ChillTicketBundle/tests/`.
 | |
| 
 | |
| Here's an example of a simple entity test:
 | |
| 
 | |
| ```php
 | |
| <?php
 | |
| 
 | |
| namespace Chill\TicketBundle\Tests\Entity;
 | |
| 
 | |
| use Chill\TicketBundle\Entity\Ticket;
 | |
| use PHPUnit\Framework\TestCase;
 | |
| 
 | |
| class TicketTest extends TestCase
 | |
| {
 | |
|     public function testGetAndSetExternalRef(): void
 | |
|     {
 | |
|         $ticket = new Ticket();
 | |
|         $externalRef = 'REF-123';
 | |
| 
 | |
|         // Set the external reference
 | |
|         $ticket->setExternalRef($externalRef);
 | |
| 
 | |
|         // Verify that getExternalRef returns the correct value
 | |
|         self::assertSame($externalRef, $ticket->getExternalRef());
 | |
| 
 | |
|         // Change the external reference
 | |
|         $newExternalRef = 'REF-456';
 | |
|         $ticket->setExternalRef($newExternalRef);
 | |
| 
 | |
|         // Verify that getExternalRef returns the updated value
 | |
|         self::assertSame($newExternalRef, $ticket->getExternalRef());
 | |
|     }
 | |
| }
 | |
| ```
 | |
| 
 | |
| #### Test Database
 | |
| 
 | |
| For tests that require a database, the project uses a postgresql database filled with fixtures (usage of doctrine-fixtures). You can configure a different database for testing in the `.env.test` file.
 | |
| 
 | |
| ### Code Quality Tools
 | |
| 
 | |
| The project uses several tools to maintain code quality:
 | |
| 
 | |
| #### PHP Code Style
 | |
| 
 | |
| The project uses PHP-CS-Fixer for code style. You can run it with:
 | |
| 
 | |
| ```bash
 | |
| # Using the composer script
 | |
| composer php-cs-fixer
 | |
| 
 | |
| # Or directly
 | |
| php-cs-fixer fix --config=./.php-cs-fixer.dist.php
 | |
| ```
 | |
| 
 | |
| #### Static Analysis
 | |
| 
 | |
| The project uses PHPStan for static analysis. You can run it with:
 | |
| 
 | |
| ```bash
 | |
| # Using the composer script
 | |
| composer phpstan
 | |
| 
 | |
| # Or directly
 | |
| vendor/bin/phpstan analyse
 | |
| ```
 | |
| 
 | |
| #### Automated Refactoring
 | |
| 
 | |
| The project uses Rector for automated refactoring. You can run it with:
 | |
| 
 | |
| ```bash
 | |
| # Using the composer script
 | |
| composer rector
 | |
| 
 | |
| # Or directly
 | |
| vendor/bin/rector
 | |
| ```
 | |
| 
 | |
| #### JavaScript/TypeScript Linting
 | |
| 
 | |
| The project uses ESLint for JavaScript/TypeScript code quality. You can run it with:
 | |
| 
 | |
| ```bash
 | |
| yarn run eslint
 | |
| ```
 | |
| 
 | |
| ## Deployment
 | |
| 
 | |
| The project can be deployed in a production environment following Symfony's deployment guidelines. The documentation provides detailed instructions for setting up a production environment.
 | |
| 
 | |
| ### Production Deployment Checklist
 | |
| 
 | |
| 1. Set environment variables for production
 | |
| 2. Optimize Composer autoloader: `composer install --no-dev --optimize-autoloader`
 | |
| 3. Compile assets for production: `yarn run encore production`
 | |
| 4. Clear and warm up the cache: `php bin/console cache:clear --env=prod`
 | |
| 5. Run database migrations: `php bin/console doctrine:migrations:migrate --env=prod`
 | |
| 
 | |
| ## Documentation
 | |
| 
 | |
| Comprehensive documentation is available in the `/docs/` directory, including installation instructions, configuration guides, and operational procedures.
 | |
| 
 | |
| ## Development Workflow
 | |
| 
 | |
| 1. **Create a Feature Branch**: Always create a new branch for your feature or bugfix
 | |
| 2. **Write Tests**: Write tests for your changes before implementing them
 | |
| 3. **Implement Changes**: Implement your changes following the project's coding standards
 | |
| 4. **Run Tests**: Make sure all tests pass
 | |
| 5. **Run Code Quality Tools**: Make sure your code passes all code quality checks
 | |
| 6. **Submit a Pull Request**: Submit a pull request for review
 | |
| 
 | |
| ## Debugging
 | |
| 
 | |
| The project includes several tools for debugging:
 | |
| 
 | |
| - **Symfony Profiler**: Available in development mode at `/_profiler`
 | |
| - **Xdebug**: Configure your IDE to use Xdebug for step-by-step debugging
 | |
| - **Symfony Debug Toolbar**: Available at the bottom of the page in development mode
 | |
| 
 | |
| ## Conclusion
 | |
| 
 | |
| When working with this project, Junie should:
 | |
| 
 | |
| 1. Understand the modular bundle structure and how the different components interact
 | |
| 2. Build the project before submitting changes to ensure assets are properly compiled
 | |
| 3. Run relevant tests to ensure changes don't break existing functionality
 | |
| 4. Follow the established code style and patterns
 | |
| 5. Use the provided tools for debugging and code quality
 |