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

3.3 KiB

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:
    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:

#[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.
}