Compare commits

..

1 Commits

Author SHA1 Message Date
gitea-actions
68c1c98b27 chore: bump version to v0.1.2
Some checks failed
Build & Push Docker Image / build (push) Failing after 7s
2026-04-07 09:26:56 +00:00
16 changed files with 34 additions and 13171 deletions

View File

@@ -13,7 +13,7 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
token: ${{ secrets.REGISTRY_TOKEN }} token: ${{ secrets.RELEASE_TOKEN || gitea.token }}
persist-credentials: true persist-credentials: true
- name: Create next tag from config/version.yaml - name: Create next tag from config/version.yaml

1
.nvmrc
View File

@@ -1 +0,0 @@
24

116
CLAUDE.md
View File

@@ -1,69 +1,6 @@
# Coltura # Coltura
CRM/ERP. Monorepo Symfony 8 (API Platform 4) + Nuxt 4. **Architecture DDD (Domain-Driven Design).** CRM/ERP. Monorepo Symfony 8 (API Platform 4) + Nuxt 4.
## Architecture DDD
Le projet suit une architecture DDD cote backend ET frontend. Le code est organise par **domaine metier** (Bounded Context), pas par type technique.
### Backend — Organisation par domaine
```
src/
Domain/ # Couche domaine (logique metier pure, aucune dependance framework)
{BoundedContext}/ # Ex: Customer, Sales, Catalog, Invoice...
Entity/ # Entites et Aggregates du domaine
ValueObject/ # Value Objects (Money, Address, Email...)
Repository/ # Interfaces des repositories (ports)
Service/ # Services domaine (logique metier)
Event/ # Domain Events
Exception/ # Exceptions metier
Application/ # Couche application (cas d'usage, orchestration)
{BoundedContext}/
Command/ # Commands (write) + Handlers
Query/ # Queries (read) + Handlers
DTO/ # Data Transfer Objects
Infrastructure/ # Couche infrastructure (implementations techniques)
{BoundedContext}/
Repository/ # Implementations Doctrine des repositories
Persistence/ # Mapping Doctrine (si XML/YAML)
Shared/ # Services techniques partages (mail, storage, etc.)
Api/ # Couche API (exposition HTTP)
{BoundedContext}/
Resource/ # ApiResource API Platform
State/ # Providers & Processors API Platform
```
**Regles DDD backend :**
- Le domaine (`Domain/`) ne depend de RIEN (pas de Doctrine, pas de Symfony, pas d'API Platform)
- Les repositories dans `Domain/` sont des **interfaces** ; les implementations Doctrine sont dans `Infrastructure/`
- Les entites API Platform (`Api/Resource/`) sont decouples des entites domaine si necessaire
- Chaque Bounded Context est autonome — pas d'import croise entre contextes (communiquer via events ou services application)
- `User` et `Auth` restent dans `src/` (hors DDD) car c'est du framework pur (Security Bundle)
### Frontend — Organisation par domaine
```
frontend/
domains/ # Modules metier
{bounded-context}/ # Ex: customer, sales, catalog, invoice...
components/ # Composants Vue specifiques au domaine
composables/ # Composables specifiques au domaine
services/ # Services API du domaine
dto/ # Types TypeScript du domaine
pages/ # Pages du domaine (optionnel, ou dans pages/)
stores/ # Store Pinia du domaine (si necessaire)
components/ # Composants UI partages (non lies a un domaine)
composables/ # Composables partages (useApi, useAppVersion)
stores/ # Stores globaux (auth, ui)
services/ # Services partages
```
**Regles DDD frontend :**
- Chaque domaine est un dossier autonome dans `frontend/domains/`
- Un domaine ne doit pas importer depuis un autre domaine — utiliser les composables/stores partages
- Les composants, services et types partages restent a la racine (`components/`, `composables/`, etc.)
- Les pages peuvent etre dans `frontend/pages/` (routing Nuxt) et importer les composants du domaine
## Stack ## Stack
@@ -75,37 +12,26 @@ frontend/
## Structure ## Structure
``` ```
src/ src/Entity/ # Entites Doctrine (User)
Domain/{Context}/Entity/ # Entites domaine src/ApiResource/ # Ressources API Platform decouples (AppVersion)
Domain/{Context}/ValueObject/ # Value Objects src/State/ # Providers et Processors API Platform (MeProvider, AppVersionProvider, UserPasswordHasherProcessor)
Domain/{Context}/Repository/ # Interfaces repositories src/Service/ # Services metier
Domain/{Context}/Service/ # Services domaine src/Repository/ # Repositories Doctrine
Domain/{Context}/Event/ # Domain Events src/DataFixtures/ # Fixtures
Application/{Context}/Command/ # Commands + Handlers config/ # Config Symfony (security, api_platform, lexik_jwt, nelmio_cors, doctrine)
Application/{Context}/Query/ # Queries + Handlers config/jwt/ # Cles JWT (private.pem, public.pem)
Application/{Context}/DTO/ # Data Transfer Objects migrations/ # Migrations Doctrine
Infrastructure/{Context}/Repository/ # Implementations Doctrine infra/dev/ # Config Docker dev (Dockerfile, nginx, php.ini, xdebug)
Api/{Context}/Resource/ # ApiResource API Platform infra/prod/ # Config Docker prod (Dockerfile multi-stage, nginx, php-prod.ini)
Api/{Context}/State/ # Providers & Processors frontend/ # App Nuxt 4
Entity/ # Entites framework (User) frontend/pages/ # Pages (index, login)
DataFixtures/ # Fixtures frontend/layouts/ # Layouts (default)
config/ # Config Symfony frontend/components/ # Composants Vue
config/jwt/ # Cles JWT frontend/composables/# Composables (useApi, useAppVersion)
migrations/ # Migrations Doctrine frontend/stores/ # Stores Pinia (auth, ui)
infra/dev/ # Docker dev frontend/services/ # Services API (auth)
infra/prod/ # Docker prod (multi-stage) frontend/services/dto/ # Types TypeScript
frontend/ frontend/i18n/locales/ # Fichiers de traduction
domains/{context}/components/ # Composants du domaine
domains/{context}/composables/ # Composables du domaine
domains/{context}/services/ # Services API du domaine
domains/{context}/dto/ # Types TS du domaine
domains/{context}/stores/ # Store Pinia du domaine
components/ # Composants UI partages
composables/ # Composables partages (useApi, useAppVersion)
stores/ # Stores globaux (auth, ui)
pages/ # Pages (routing Nuxt)
layouts/ # Layouts
i18n/locales/ # Traductions
``` ```
## Commandes ## Commandes

11149
composer.lock generated

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,2 +1,2 @@
parameters: parameters:
app.version: '0.1.9' app.version: '0.1.2'

View File

@@ -74,13 +74,13 @@ RUN cd frontend && npm ci && npm run build:dist && rm -rf node_modules
RUN chown -R www-data:www-data /var/www/html/var /var/www/html/frontend/dist RUN chown -R www-data:www-data /var/www/html/var /var/www/html/frontend/dist
# PHP prod config # PHP prod config
COPY infra/prod/php-prod.ini /usr/local/etc/php/php.ini COPY infra/deploy/php-prod.ini /usr/local/etc/php/php.ini
EXPOSE 9000 EXPOSE 9000
# ── Nginx stage ── # ── Nginx stage ──
FROM nginx:1.27-alpine AS nginx FROM nginx:1.27-alpine AS nginx
COPY infra/prod/nginx.conf /etc/nginx/conf.d/default.conf COPY infra/deploy/nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=php-base /var/www/html/public /var/www/html/public COPY --from=php-base /var/www/html/public /var/www/html/public
COPY --from=php-base /var/www/html/frontend/dist /var/www/html/frontend/dist COPY --from=php-base /var/www/html/frontend/dist /var/www/html/frontend/dist

View File

@@ -2,11 +2,11 @@
declare(strict_types=1); declare(strict_types=1);
namespace App\Api\Shared\Resource; namespace App\ApiResource;
use ApiPlatform\Metadata\ApiResource; use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get; use ApiPlatform\Metadata\Get;
use App\Api\Shared\State\AppVersionProvider; use App\State\AppVersionProvider;
#[ApiResource( #[ApiResource(
operations: [ operations: [

View File

View File

@@ -10,9 +10,9 @@ use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection; use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post; use ApiPlatform\Metadata\Post;
use App\Api\Auth\State\MeProvider;
use App\Api\Auth\State\UserPasswordHasherProcessor;
use App\Repository\UserRepository; use App\Repository\UserRepository;
use App\State\MeProvider;
use App\State\UserPasswordHasherProcessor;
use DateTimeImmutable; use DateTimeImmutable;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;

View File

@@ -2,11 +2,10 @@
declare(strict_types=1); declare(strict_types=1);
namespace App\Api\Shared\State; namespace App\State;
use ApiPlatform\Metadata\Operation; use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface; use ApiPlatform\State\ProviderInterface;
use App\Api\Shared\Resource\AppVersion;
use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\DependencyInjection\Attribute\Autowire;
/** /**
@@ -21,6 +20,6 @@ class AppVersionProvider implements ProviderInterface
public function provide(Operation $operation, array $uriVariables = [], array $context = []): object public function provide(Operation $operation, array $uriVariables = [], array $context = []): object
{ {
return new AppVersion($this->appVersion); return new \App\ApiResource\AppVersion($this->appVersion);
} }
} }

View File

@@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace App\Api\Auth\State; namespace App\State;
use ApiPlatform\Metadata\Operation; use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface; use ApiPlatform\State\ProviderInterface;

View File

@@ -2,12 +2,11 @@
declare(strict_types=1); declare(strict_types=1);
namespace App\Api\Auth\State; namespace App\State;
use ApiPlatform\Metadata\Operation; use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProcessorInterface; use ApiPlatform\State\ProcessorInterface;
use App\Entity\User; use App\Entity\User;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
/** /**
@@ -16,7 +15,7 @@ use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
class UserPasswordHasherProcessor implements ProcessorInterface class UserPasswordHasherProcessor implements ProcessorInterface
{ {
public function __construct( public function __construct(
#[Autowire(service: 'api_platform.doctrine.orm.state.persist_processor')] /** @var ProcessorInterface<User, User> */
private readonly ProcessorInterface $persistProcessor, private readonly ProcessorInterface $persistProcessor,
private readonly UserPasswordHasherInterface $passwordHasher, private readonly UserPasswordHasherInterface $passwordHasher,
) {} ) {}