@volontariapp/domain-event 3.6.13 → 3.6.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +132 -0
  3. package/package.json +10 -10
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.6.14
4
+
5
+ ### Patch Changes
6
+
7
+ - README bump
8
+
9
+ - Updated dependencies []:
10
+ - @volontariapp/contracts@4.3.2
11
+ - @volontariapp/database@3.4.4
12
+ - @volontariapp/errors@0.6.1
13
+ - @volontariapp/errors-nest@0.13.1
14
+ - @volontariapp/logger@0.2.6
15
+ - @volontariapp/messaging@2.10.1
16
+ - @volontariapp/outbox@0.9.41
17
+ - @volontariapp/shared@0.8.1
18
+
3
19
  ## 3.6.13
4
20
 
5
21
  ### Patch Changes
package/README.md ADDED
@@ -0,0 +1,132 @@
1
+ # @volontariapp/domain-event
2
+
3
+ ## Overview & Domain Driven Design (DDD)
4
+
5
+ Le package `domain-event` encapsule la **logique métier centrale absolue** relative aux **Événements** (Events) de la plateforme Volontariapp.
6
+ Conçu selon les principes stricts de la **Clean Architecture** et du **Domain-Driven Design (DDD)**, ce domaine est complètement **agnostique de l'infrastructure**. Il ne connaît ni NestJS, ni TypeORM, ni gRPC.
7
+
8
+ Ce package est partagé transversalement (DRY) entre :
9
+ - Le microservice métier (`ms-event`)
10
+ - Les Workers asynchrones
11
+ - Les Post-Processors
12
+
13
+ > [!TIP]
14
+ > **Pourquoi cette isolation ?**
15
+ > Si l'API HTTP/gRPC tombe en panne, ou si le framework change, les Workers et le domaine continuent de fonctionner de manière totalement autonome grâce à cette isolation stricte de la logique métier.
16
+
17
+ ## Architecture du Domaine
18
+
19
+ ```mermaid
20
+ classDiagram
21
+ direction TB
22
+
23
+ namespace DomainLayer {
24
+ class EventService {
25
+ <<Domain Service>>
26
+ +createEvent(params)
27
+ +validateParticipation()
28
+ }
29
+ class EventEntity {
30
+ <<Entity>>
31
+ +id: Uuid
32
+ +title: string
33
+ +location: EventLocation
34
+ +status: EventStatus
35
+ +publish()
36
+ }
37
+ class EventLocation {
38
+ <<Value Object>>
39
+ -latitude: number
40
+ -longitude: number
41
+ +isValid()
42
+ }
43
+ class IEventRepository {
44
+ <<Interface>>
45
+ +save(EventEntity)
46
+ +findById(Uuid)
47
+ }
48
+ }
49
+
50
+ namespace InfraLayer {
51
+ class PostgresEventRepository {
52
+ <<Implementation>>
53
+ -typeOrmRepository
54
+ }
55
+ }
56
+
57
+ EventService --> EventEntity : Orchestre
58
+ EventEntity *-- EventLocation : Contient
59
+ EventService --> IEventRepository : Utilise (DIP)
60
+ PostgresEventRepository ..|> IEventRepository : Implémente
61
+ ```
62
+
63
+ ## Structure des Dossiers
64
+
65
+ ```text
66
+ src/
67
+ ├── entities/ # Entités mutables du domaine (ex: EventEntity, TagEntity)
68
+ ├── value-objects/ # Objets immuables validant des règles précises (ex: EventLocation)
69
+ ├── services/ # Domain Services pour la logique impliquant plusieurs entités
70
+ ├── repositories/ # Interfaces des Repositories (Contrats) et implémentations Infra
71
+ ├── models/ # Modèles DTOs / Mappers
72
+ ├── database/ # Définition des triggers ou logiques SQL pures (si applicables)
73
+ └── test/ # Factories et mocks du domaine
74
+ ```
75
+
76
+ ## Exemples d'Implémentation
77
+
78
+ ### 1. Value Object & Entity
79
+ L'utilisation de Value Objects empêche le passage de types primitifs (Primitive Obsession) et garantit que seules des données valides existent en mémoire.
80
+
81
+ ```typescript
82
+ // value-objects/event-location.value-object.ts
83
+ export class EventLocation {
84
+ constructor(
85
+ public readonly latitude: number,
86
+ public readonly longitude: number
87
+ ) {
88
+ if (latitude < -90 || latitude > 90) throw new DomainError('Invalid latitude');
89
+ if (longitude < -180 || longitude > 180) throw new DomainError('Invalid longitude');
90
+ }
91
+ }
92
+
93
+ // entities/event.entity.ts
94
+ export class EventEntity {
95
+ constructor(
96
+ public readonly id: string,
97
+ public title: string,
98
+ public location: EventLocation // Typage fort, impossible d'avoir une string
99
+ ) {}
100
+
101
+ public relocate(newLocation: EventLocation): void {
102
+ // Logique métier encapsulée dans l'entité
103
+ this.location = newLocation;
104
+ }
105
+ }
106
+ ```
107
+
108
+ ### 2. Domain Service
109
+ Le service de domaine orchestre les règles qui ne rentrent pas dans une seule entité, en utilisant des abstractions (Inversion de Dépendance).
110
+
111
+ ```typescript
112
+ // services/event-creation.service.ts
113
+ export class EventCreationService {
114
+ constructor(
115
+ private readonly eventRepo: IEventRepository,
116
+ private readonly userSvc: IUserServiceStub
117
+ ) {}
118
+
119
+ async create(userId: string, payload: CreateEventPayload): Promise<EventEntity> {
120
+ const user = await this.userSvc.getUserStatus(userId);
121
+ if (!user.isVerified) {
122
+ throw new DomainError('USER_NOT_VERIFIED', 'Unverified users cannot create events');
123
+ }
124
+
125
+ const location = new EventLocation(payload.lat, payload.lng);
126
+ const event = new EventEntity(uuidv4(), payload.title, location);
127
+
128
+ await this.eventRepo.save(event);
129
+ return event;
130
+ }
131
+ }
132
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volontariapp/domain-event",
3
- "version": "3.6.13",
3
+ "version": "3.6.14",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "provenance": true
@@ -44,7 +44,7 @@
44
44
  "@nestjs/typeorm": "^11.0.1",
45
45
  "@types/jest": "^30.0.0",
46
46
  "@types/node": "^22.10.7",
47
- "@volontariapp/testing": "1.0.1",
47
+ "@volontariapp/testing": "1.0.2",
48
48
  "jest": "^30.3.0",
49
49
  "pg": "^8.20.0",
50
50
  "reflect-metadata": "^0.2.2",
@@ -55,14 +55,14 @@
55
55
  },
56
56
  "dependencies": {
57
57
  "@nestjs/common": "^11.0.1",
58
- "@volontariapp/contracts": "4.3.1",
59
- "@volontariapp/database": "3.4.3",
60
- "@volontariapp/errors": "0.6.0",
61
- "@volontariapp/errors-nest": "0.13.0",
62
- "@volontariapp/logger": "0.2.5",
63
- "@volontariapp/messaging": "2.10.0",
64
- "@volontariapp/outbox": "0.9.40",
65
- "@volontariapp/shared": "0.8.0",
58
+ "@volontariapp/contracts": "4.3.2",
59
+ "@volontariapp/database": "3.4.4",
60
+ "@volontariapp/errors": "0.6.1",
61
+ "@volontariapp/errors-nest": "0.13.1",
62
+ "@volontariapp/logger": "0.2.6",
63
+ "@volontariapp/messaging": "2.10.1",
64
+ "@volontariapp/outbox": "0.9.41",
65
+ "@volontariapp/shared": "0.8.1",
66
66
  "class-transformer": "^0.5.1"
67
67
  }
68
68
  }