saufen/docs/development-guidelines.md
2025-05-31 21:43:13 +02:00

103 lines
3.3 KiB
Markdown

# Development Guidelines
This document outlines the development workflow and guidelines for the Drinks Inventory System.
## Development Environment Setup
### Requirements
- PHP 8.4 or higher
- Composer
- SQLite
- Git
### General
- Use classes for entities, repositories, services and controllers
- Use Doctrine ORM for database interactions
- Use twig for templates
- Register services in the container and use dependency injection
- Write unit as well as feature tests
- Always use DateTimeImmutable unless there is a good reason not to
- Leverage modern php features such as enums, property promotion, and property hooks
### PHP Constructor Property Promotion and Readonly Properties
- Use constructor property promotion for all properties that are initialized in the constructor
- Use readonly properties for properties that should not be modified after initialization
- Only use readonly for properties that don't have setter methods
- Example:
```php
class Example
{
private ?int $id = null;
public function __construct(
private string $name,
private readonly DateTimeImmutable $createdAt = new DateTimeImmutable(),
private DateTimeImmutable $updatedAt = new DateTimeImmutable()
) {
}
// Getter for readonly property
public function getCreatedAt(): DateTimeImmutable
{
return $this->createdAt;
}
// Getter and setter for non-readonly property
public function getName(): string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
$this->updateTimestamp();
return $this;
}
private function updateTimestamp(): void
{
$this->updatedAt = new DateTimeImmutable();
}
}
### Doctrine ORM Guidelines
- Use PHP 8 attributes for entity mapping (not annotations or XML)
- Place all entity classes in the `src/Entity` directory
- Place all repository classes in the `src/Repository` directory
- Use the naming convention `EntityNameRepository` for repository classes
- Define relationships between entities using appropriate Doctrine annotations (`OneToMany`, `ManyToOne`, etc.)
- Use `readonly` for properties that should not change after entity creation (like `createdAt`)
- Always include `created_at` and `updated_at` fields in all entities
- Implement an `updateTimestamp()` method to update the `updated_at` field when an entity is modified
- Use the repository pattern for database operations, not direct entity manager operations in services
- Define custom finder methods in repository classes for specific query needs
- Use Doctrine's query builder for complex queries
- Always validate entity data before persisting to the database
Example entity with Doctrine attributes:
```php
#[ORM\Entity(repositoryClass: ExampleRepository::class)]
#[ORM\Table(name: 'example')]
class Example
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private ?int $id = null;
#[ORM\Column(type: 'string', length: 255)]
private string $name;
#[ORM\Column(type: 'datetime_immutable')]
private readonly DateTimeImmutable $createdAt;
#[ORM\Column(type: 'datetime_immutable')]
private DateTimeImmutable $updatedAt;
// Constructor, getters, setters, etc.
}
```