Files
unionflow-server-api/unionflow/.specify/memory/constitution.md
dahoud e8ad874015 feat: WebSocket temps réel + Finance Workflow + corrections
- Task #6: WebSocket /ws/dashboard + Kafka events (5 topics)
  * Backend: KafkaEventProducer, KafkaEventConsumer
  * Mobile: WebSocketService (reconnection, heartbeat, typed events)
  * DashboardBloc: Auto-refresh depuis WebSocket events

- Finance Workflow: approbations + budgets (backend + mobile)
  * Backend: entities, services, resources, migrations Flyway V6
  * Mobile: features finance_workflow complète avec BLoC

- Corrections DI: interfaces IRepository partout
  * IProfileRepository, IOrganizationRepository, IMembreRepository
  * GetIt configuré avec @injectable

- Spec-Kit: constitution + templates mis à jour
  * .specify/memory/constitution.md enrichie
  * Templates agent, plan, spec, tasks, checklist

- Nettoyage: fichiers temporaires supprimés

Signed-off-by: lions dev Team
2026-03-15 02:12:17 +00:00

731 lines
23 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# UnionFlow Project Constitution
> **Version:** 1.0
> **Date:** 2026-03-08
> **Status:** Active
> **Scope:** Backend (unionflow-server-impl-quarkus), API (unionflow-server-api), Mobile (unionflow-mobile-apps)
> **Référence inventaire:** `.specify/memory/inventaire-code.md` — liste exacte des packages, migrations et features (à utiliser pour ne pas halluciner). **En cas de divergence entre ce document et le code source, le code fait foi** ; linventaire et la constitution doivent être mis à jour pour refléter létat réel du dépôt.
---
## 🎯 Mission & Vision
**Mission:** Fournir une plateforme complète et sécurisée pour la gestion d'associations, clubs et organisations à but non lucratif, et **pour la gestion des mutuelles d'épargne et de financement**.
**Vision:** Architecture DDD stricte, séparation claire API/Implementation, conformité RGPD, et qualité industrielle (100% test coverage).
---
## 📐 Architecture Principles
### 1. Domain-Driven Design (DDD) - STRICT
#### 1.1 Layered Architecture
```
┌─────────────────────────────────────────┐
│ Presentation Layer (Resources/API) │ ← JAX-RS REST endpoints
├─────────────────────────────────────────┤
│ Application Layer (Services) │ ← Business logic, transactions
├─────────────────────────────────────────┤
│ Domain Layer (Entities) │ ← Rich domain models
├─────────────────────────────────────────┤
│ Infrastructure Layer (Repositories) │ ← Data persistence (Panache)
└─────────────────────────────────────────┘
```
**Rules:**
-**DO**: Resources call Services, Services use Repositories
-**DON'T**: Resources directly access Repositories
-**DON'T**: Entities contain business logic beyond validation
-**DO**: All business logic lives in Services
#### 1.2 Entity Pattern
- **Base Class**: All entities extend `BaseEntity`
```java
@MappedSuperclass
public abstract class BaseEntity {
@Id UUID id;
LocalDateTime dateCreation;
LocalDateTime dateModification;
String creePar;
String modifiePar;
Long version; // Optimistic locking
Boolean actif; // Soft delete
}
```
- **Lifecycle Hooks**: `@PrePersist`, `@PreUpdate` for audit trail
- **Immutability**: Use Lombok `@Builder` for construction
- **Validation**: Jakarta Bean Validation annotations on fields
#### 1.3 Repository Pattern
- **Technology**: Hibernate Panache `PanacheRepositoryBase<Entity, UUID>`
- **Naming**: `{Entity}Repository` (e.g., `MembreRepository`)
- **Custom Queries**: Native queries for complex business logic
- **Pagination**: Use `Page` and `Sort` from Panache
- **No Logic**: Repositories are ONLY for data access, no business rules
#### 1.4 Service Pattern
- **Naming**: `{Domain}Service` (e.g., `MembreService`, `CotisationService`)
- **Transactions**: All mutating methods MUST be `@Transactional`
- **Logging**: Use `Logger.getLogger(...)` for all service operations
- **Error Handling**: Throw domain exceptions (`NotFoundException`, `IllegalArgumentException`)
- **Security**: Inject `KeycloakService` for authorization checks
---
### 2. API/Implementation Separation - MANDATORY
#### 2.1 Module Structure
```
unionflow/
├── unionflow-server-api/ ← Pure Java 17, no dependencies
│ ├── dto/
│ │ ├── request/ ← Java records with validation
│ │ └── response/ ← Java records (immutable DTOs)
│ └── enums/ ← Rich enums with business methods
└── unionflow-server-impl-quarkus/ ← Quarkus 3.15.1 implementation
├── entity/ ← JPA entities
├── repository/ ← Panache repositories
├── service/ ← Business logic
├── resource/ ← JAX-RS endpoints
├── mapper/ ← MapStruct mappers
└── security/ ← Security config
```
#### 2.2 API Module Rules
- ✅ **DO**: Use Java `record` for all DTOs (request/response)
- ✅ **DO**: Use `@Builder` from Lombok for records
- ✅ **DO**: Validation annotations (`@NotNull`, `@Size`, `@Pattern`, etc.)
- ❌ **DON'T**: Any runtime dependencies (no Quarkus, no JPA)
- ❌ **DON'T**: Mutable DTOs (records are immutable)
**Example Request DTO:**
```java
@Builder
public record CreateMembreRequest(
@NotBlank @Size(max = 100) String nom,
@NotBlank @Size(max = 100) String prenom,
@Email String email,
@NotNull LocalDate dateNaissance
) {}
```
#### 2.3 Impl Module Rules
- ✅ **DO**: Depend on `unionflow-server-api` for DTOs
- ✅ **DO**: Use MapStruct for Entity ↔ DTO conversion
- ❌ **DON'T**: Return entities directly from Resources (always map to DTOs)
- ❌ **DON'T**: Accept entities in Resource methods (use DTOs)
---
### 3. Security - NON-NEGOTIABLE
#### 3.1 Authentication & Authorization
- **Provider**: Keycloak 23+ (OIDC/OAuth2)
- **Realm**: `unionflow`
- **Client**: `unionflow-mobile` (confidential)
- **Token Type**: JWT (signed, encrypted)
#### 3.2 JWT Validation Strategy
| Layer | Validation |
|-------|------------|
| **Mobile** | Issuer (`iss`) + Expiry (`exp`) |
| **Backend** | Signature verification + Claims extraction |
**Rationale**: Mobile cannot verify JWT signatures securely (no secret storage), so backend is authoritative for signature validation.
#### 3.3 Role-Based Access Control (RBAC)
**Defined Roles** (in `SecurityConfig.Roles`):
1. `ADMIN` - Full system access
2. `PRESIDENT` - Organization management
3. `VICE_PRESIDENT` - Deputy authority
4. `TRESORIER` - Financial operations
5. `SECRETAIRE` - Administrative operations
6. `GESTIONNAIRE_MEMBRE` - Member management
7. `ORGANISATEUR_EVENEMENT` - Event management
8. `GESTIONNAIRE_SOLIDARITE` - Solidarity aid management
9. `AUDITEUR` - Read-only audit access
10. `MEMBRE` - Basic member access
**Permission Checks**:
```java
// In Services
if (!keycloakService.hasRole("ADMIN") &&
!keycloakService.hasRole("GESTIONNAIRE_MEMBRE")) {
throw new SecurityException("Insufficient permissions");
}
// In Resources
@RolesAllowed({"ADMIN", "TRESORIER"})
@GET
public Response getFinancialData() { ... }
```
#### 3.4 RGPD Compliance
- **Audit Trail**: All entities track `creePar`, `modifiePar`, dates
- **Soft Delete**: Use `actif=false` instead of hard deletes
- **Data Minimization**: Only collect necessary fields
- **Right to be Forgotten**: Anonymization service (planned)
- **Consent Management**: Explicit opt-in for communications
#### 3.5 Transport Security
- **HTTPS Only**: All external traffic via TLS 1.3+
- **Certificate Management**: Let's Encrypt + Cert-Manager (K8s)
- **Ingress**: nginx ingress controller with SSL termination
- **Mobile**: `network_security_config.xml` blocks cleartext HTTP
---
### 4. Data Management
#### 4.1 Database Strategy
- **Production**: PostgreSQL 15+
- **Testing**: H2 in-memory
- **Schema Management**: Flyway migrations
- **Connection Pooling**: HikariCP (via Quarkus)
#### 4.2 Migration Policy
- **Versioning**: `V{major}.{minor}__{description}.sql`
- **Current**: `V2.0__create_all_37_entities.sql`
- **Rules**:
- ❌ NEVER modify existing migrations
- ✅ Always create new migration for schema changes
- ✅ Test migrations on staging before production
- ✅ Migrations must be idempotent where possible
#### 4.3 Primary Keys
- **Type**: `UUID` (UUIDv4)
- **Generation**: Database-generated (`gen_random_uuid()`)
- **Foreign Keys**: Always use UUIDs
- **Rationale**: Distributed system compatibility, no ID enumeration attacks
#### 4.4 Optimistic Locking
- **Field**: `@Version Long version` in `BaseEntity`
- **Behavior**: Automatic conflict detection on concurrent updates
- **Exception**: `OptimisticLockException` → HTTP 409 Conflict
---
### 5. Quality Assurance
#### 5.1 Test Coverage Requirements
**JaCoCo Thresholds (STRICT - NO EXCEPTIONS):**
- ✅ Instructions: **100%**
- ✅ Branches: **100%**
- ✅ Lines: **100%**
- ✅ Methods: **100%**
**Configuration:**
```xml
<rules>
<rule><limits>
<limit><counter>INSTRUCTION</counter><minimum>1.00</minimum></limit>
<limit><counter>BRANCH</counter><minimum>1.00</minimum></limit>
<limit><counter>LINE</counter><minimum>1.00</minimum></limit>
<limit><counter>METHOD</counter><minimum>1.00</minimum></limit>
</limits></rule>
</rules>
<haltOnFailure>true</haltOnFailure>
```
**Exclusions**: NONE (including mappers, generated code)
#### 5.2 Test Patterns
**Service Tests:**
```java
@QuarkusTest
class MembreServiceTest {
@Inject MembreService service;
@BeforeEach
void setup() {
// Setup via service calls (own @Transactional)
}
@Test
@TestTransaction // Rollback after test
void testMethod() { ... }
}
```
**Resource Tests:**
```java
@QuarkusTest
class MembreResourceTest {
@Test
@TestSecurity(user = "admin@test.com", roles = {"ADMIN"})
void testEndpoint() {
given()
.when().get("/api/membres")
.then().statusCode(200);
}
}
```
**Entity Tests:**
```java
class MembreTest {
@Test
void testPrePersist() {
Membre m = new Membre();
// Invoke @PrePersist via reflection
m.prePersist();
assertThat(m.getDateCreation()).isNotNull();
}
}
```
#### 5.3 Test Organization
- **Location**: `src/test/java` mirroring `src/main/java` structure
- **Naming**: `{ClassName}Test.java`
- **DisplayName**: French, descriptive (`@DisplayName("crée un membre valide")`)
- **Assertions**: AssertJ (`assertThat(...).isNotNull()`)
---
### 6. Configuration Management
#### 6.1 Environment Profiles
| Profile | Purpose | DB | Keycloak | Logs |
|---------|---------|----|----------|------|
| **dev** | Local development | H2 | localhost:8180 | Console |
| **test** | Automated tests | H2 | Mock (@TestSecurity) | Suppressed |
| **staging** | Pre-production | PostgreSQL | staging.lions.dev | File + Console |
| **prod** | Production | PostgreSQL | security.lions.dev | File only |
#### 6.2 Configuration Hierarchy
```
1. application.properties (defaults)
2. application-{profile}.properties (overrides)
3. Environment variables (highest priority)
```
**Example:**
```properties
# application.properties
quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/unionflow
# application-prod.properties
quarkus.datasource.jdbc.url=jdbc:postgresql://postgresql-service.postgresql.svc.cluster.local:5432/unionflow
# Environment variable (highest priority)
QUARKUS_DATASOURCE_JDBC_URL=jdbc:postgresql://custom-host:5432/unionflow
```
#### 6.3 Secrets Management
- ❌ **NEVER** commit secrets to git
- ✅ Use environment variables for production secrets
- ✅ Use Kubernetes Secrets in K8s deployments
- ✅ Use `.env` files locally (in `.gitignore`)
**Example Kubernetes Secret:**
```yaml
apiVersion: v1
kind: Secret
metadata:
name: unionflow-secrets
type: Opaque
data:
keycloak-client-secret: <base64>
database-password: <base64>
```
---
### 7. Logging & Monitoring
#### 7.1 Logging Standards
**Levels:**
- `ERROR`: System failures requiring immediate attention
- `WARN`: Recoverable errors, deprecated usage
- `INFO`: Business events (user login, payment, etc.)
- `DEBUG`: Detailed diagnostic info (dev/staging only)
- `TRACE`: Ultra-verbose (never in production)
**Format:**
```java
LOG.infof("Membre créé: ID=%s, Email=%s", membre.getId(), membre.getEmail());
LOG.warnf("Tentative d'accès non autorisé: User=%s, Resource=%s", user, resource);
LOG.error("Erreur connexion base de données", exception);
```
#### 7.2 Production Logging
- **File**: `/var/log/unionflow/app.log` (rotated daily)
- **Console**: Disabled in production
- **JSON Format**: For log aggregation (ELK stack)
- **Sensitive Data**: NEVER log passwords, tokens, personal data
#### 7.3 Metrics & Health
- **Endpoints**:
- `/q/health` - Health check
- `/q/health/live` - Liveness probe
- `/q/health/ready` - Readiness probe
- `/q/metrics` - Prometheus metrics
- **K8s Probes**: Configured for all 3 health endpoints
---
### 8. API Design
#### 8.1 RESTful Conventions
| Method | Path | Purpose | Status |
|--------|------|---------|--------|
| `GET` | `/api/membres` | List all | 200 |
| `GET` | `/api/membres/{id}` | Get one | 200 / 404 |
| `POST` | `/api/membres` | Create | 201 |
| `PUT` | `/api/membres/{id}` | Full update | 200 / 404 |
| `PATCH` | `/api/membres/{id}` | Partial update | 200 / 404 |
| `DELETE` | `/api/membres/{id}` | Soft delete | 204 / 404 |
#### 8.2 Response Formats
**Success (200/201):**
```json
{
"id": "uuid",
"nom": "Dupont",
"prenom": "Jean",
"email": "jean.dupont@example.com"
}
```
**Error (4xx/5xx):**
```json
{
"timestamp": "2026-02-27T10:30:00Z",
"status": 404,
"error": "Not Found",
"message": "Membre non trouvé avec l'ID: {id}",
"path": "/api/membres/{id}"
}
```
#### 8.3 Pagination
```
GET /api/membres?page=0&size=20&sort=nom,asc
```
**Response Headers:**
```
X-Total-Count: 150
Link: </api/membres?page=1&size=20>; rel="next"
```
#### 8.4 Versioning
- **Strategy**: URL versioning (future)
- **Current**: No versioning (v1 implicit)
- **Future**: `/api/v2/membres` for breaking changes
---
### 9. Deployment & DevOps
#### 9.1 Container Strategy
- **Base Image**: `registry.access.redhat.com/ubi9/openjdk-17-runtime:1.20`
- **Multi-stage Build**: Maven build → JVM runtime
- **Port**: 8080 (internal), 443 (external via ingress)
- **Healthcheck**: `/q/health/live` every 30s
#### 9.2 Kubernetes Deployment
**Namespace Strategy:**
- `applications` - User-facing apps (unionflow-server, lions-user-manager)
- `infrastructure` - Supporting services (postgresql, keycloak)
- `monitoring` - Observability (prometheus, grafana)
**Resource Limits:**
```yaml
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "1000m"
```
#### 9.3 Deployment Pipeline (lionsctl)
```bash
lionsctl pipeline \
-u https://git.lions.dev/lionsdev/unionflow-server-impl-quarkus \
-b main \
-j 17 \
-e production \
-c k1 \
-p prod
```
**Steps:**
1. Clone from Gitea
2. `mvn clean package -Pprod`
3. `docker build -t registry.lions.dev/lionsdev/unionflow-server:{tag}`
4. `docker push registry.lions.dev/lionsdev/unionflow-server:{tag}`
5. `kubectl apply -f k8s/deployment.yaml`
6. Health check validation
7. Email notification
#### 9.4 Rollback Strategy
- **Version Tags**: Every build tagged with git commit SHA
- **Immutable Images**: Never overwrite existing tags
- **Rollback**: `kubectl rollout undo deployment/unionflow-server`
---
### 10. Code Conventions
#### 10.1 Naming Conventions
| Type | Convention | Example |
|------|------------|---------|
| **Packages** | `dev.lions.unionflow.server.{layer}` | `dev.lions.unionflow.server.service` |
| **Classes** | PascalCase, singular | `MembreService`, `Cotisation` |
| **Interfaces** | No `I` prefix | `Repository`, not `IRepository` |
| **Methods** | camelCase, verb-first | `creerMembre()`, `trouverParId()` |
| **Constants** | UPPER_SNAKE_CASE | `MAX_RETRY_ATTEMPTS` |
| **Variables** | camelCase | `membre`, `listeMembres` |
#### 10.2 Language
- **Code**: English for technical terms (class names, method names)
- **Business Domain**: French (`Membre`, `Cotisation`, `Adhesion`)
- **Comments/Javadoc**: French
- **Logs**: French
- **Git Commits**: French
**Rationale**: Business domain in French for client alignment, technical terms in English for global compatibility.
#### 10.3 Lombok Usage
**Allowed:**
- `@Data` (entities)
- `@Builder` (DTOs, entities)
- `@Getter` / `@Setter`
- `@NoArgsConstructor` / `@AllArgsConstructor`
- `@Slf4j` (AVOID - use standard logger)
**Forbidden:**
- `@SneakyThrows` (hides exceptions)
- `@Cleanup` (use try-with-resources)
- `@val` (use explicit types)
#### 10.4 Code Formatting
- **Indentation**: 2 spaces (NOT tabs)
- **Line Length**: 120 characters max
- **Braces**: Always use braces, even for single-line if/for
- **Import Order**: java.*, javax.*, jakarta.*, org.*, dev.lions.*, (blank), static imports
---
### 11. Error Handling
#### 11.1 Exception Hierarchy
```
RuntimeException
├── IllegalArgumentException (400 Bad Request)
├── NotFoundException (404 Not Found)
├── SecurityException (403 Forbidden)
├── IllegalStateException (409 Conflict)
└── UnsupportedOperationException (501 Not Implemented)
```
#### 11.2 Exception Mapping
```java
@Provider
public class GlobalExceptionMapper implements ExceptionMapper<Exception> {
@Override
public Response toResponse(Exception e) {
if (e instanceof NotFoundException) {
return Response.status(404).entity(error(e)).build();
}
// ... autres cas
return Response.status(500).entity(error(e)).build();
}
}
```
#### 11.3 Validation Errors
```java
@POST
public Response create(@Valid CreateMembreRequest request) {
// Validation automatique par Jakarta Bean Validation
// 400 Bad Request si validation échoue
}
```
---
### 12. Performance
#### 12.1 Database Performance
- **Indexes**: On all foreign keys, frequently queried columns
- **N+1 Queries**: Use `@EntityGraph` or JOIN FETCH
- **Pagination**: ALWAYS paginate large result sets
- **Connection Pool**: Min 5, Max 20 connections
#### 12.2 Caching Strategy
- **Level 1 Cache**: Hibernate session cache (automatic)
- **Level 2 Cache**: Disabled (stateless REST API)
- **Application Cache**: Caffeine for frequently accessed data (ex: roles, permissions)
- **HTTP Cache**: `Cache-Control` headers for static resources
#### 12.3 Query Optimization
```java
// ❌ BAD - N+1 queries
List<Membre> membres = membreRepository.findAll();
membres.forEach(m -> m.getCotisations().size()); // Lazy load
// ✅ GOOD - Single query with JOIN FETCH
@Query("SELECT m FROM Membre m LEFT JOIN FETCH m.cotisations")
List<Membre> findAllWithCotisations();
```
---
### 13. Mobile Integration
#### 13.1 Mobile App Configuration
**Flutter Environment:** Configuration centralisée dans `unionflow-mobile-apps/lib/core/config/environment.dart`. `AppConfig.initialize()` appelé dans `main()` ; `Environment` (dev, staging, prod) ; propriétés : `apiBaseUrl`, `keycloakBaseUrl`, `wsBaseUrl`, `enableLogging`, `keycloakRealmUrl`, `keycloakTokenUrl`, `wsDashboardUrl`. Valeurs par défaut selon lenvironnement (dev : localhost:8085 / 8180, prod : api.lions.dev / security.lions.dev).
**Build Command:**
```bash
flutter build apk \
--dart-define=ENV=prod \
--dart-define=API_URL=https://api.lions.dev \
--dart-define=KEYCLOAK_URL=https://security.lions.dev
```
#### 13.2 OAuth2 Flow (Mobile)
```
1. App → Keycloak: Authorization request
2. User authenticates in browser
3. Keycloak → App: Authorization code (via deep link)
4. App → Backend: Exchange code for tokens
5. Backend validates, returns JWT
6. App stores JWT securely (flutter_secure_storage)
```
#### 13.3 Deep Link Configuration
- **Scheme**: `dev.lions.unionflow-mobile://`
- **Callback**: `dev.lions.unionflow-mobile://callback`
- **Android**: Handled via `network_security_config.xml`
- **iOS**: Handled via `Info.plist`
---
### 14. Change Management
#### 14.1 Git Workflow
- **Branches**: `main` (production), `develop` (integration), `feature/*`, `fix/*`
- **Commits**: Conventional Commits format
```
type(scope): description
[optional body]
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
```
- **Types**: `feat`, `fix`, `docs`, `refactor`, `test`, `chore`
- **PR Required**: All merges to `main` require PR + review
#### 14.2 Database Migrations
**Process:**
1. Create migration: `V{version}__{description}.sql`
2. Test locally on H2
3. Test on staging PostgreSQL
4. Include in PR for review
5. Deploy to production with rollback plan
#### 14.3 Breaking Changes
**Definition**: Changes that break existing API contracts
- ❌ Removing fields from DTOs
- ❌ Changing field types
- ❌ Removing endpoints
- ❌ Changing authentication flow
**Mitigation:**
1. Version the API (`/api/v2/...`)
2. Deprecate old version with 6-month sunset
3. Communicate to mobile team 3 months in advance
---
### 15. Documentation
#### 15.1 Required Documentation
- ✅ **OpenAPI/Swagger**: Auto-generated from JAX-RS annotations
- ✅ **Javadoc**: All public methods in Services
- ✅ **README.md**: Per-module setup instructions
- ✅ **CONSTITUTION.md**: This document
- ✅ **CHANGELOG.md**: Release notes
#### 15.2 API Documentation
**Access**: `https://api.lions.dev/unionflow/q/swagger-ui`
**Annotations:**
```java
@Path("/membres")
@Tag(name = "Membres", description = "Gestion des membres")
public class MembreResource {
@GET
@Operation(summary = "Liste tous les membres")
@APIResponse(responseCode = "200", description = "Succès")
public Response list() { ... }
}
```
---
### 16. Compliance & Governance
#### 16.1 RGPD Requirements
- **Data Minimization**: Only collect necessary data
- **Purpose Limitation**: Use data only for stated purposes
- **Storage Limitation**: Delete data after retention period
- **Accuracy**: Allow users to update their data
- **Integrity**: Encrypt data at rest and in transit
- **Confidentiality**: Role-based access control
#### 16.2 Audit Trail
**Tracked Fields:**
- `creePar` - User who created the record
- `modifiePar` - User who last modified
- `dateCreation` - Creation timestamp
- `dateModification` - Last modification timestamp
**Retention**: 7 years minimum (legal requirement for associations)
#### 16.3 Data Retention Policy
| Data Type | Retention Period | Action After |
|-----------|------------------|--------------|
| **Member Data** | Active + 2 years | Anonymize |
| **Financial Records** | 10 years | Archive |
| **Audit Logs** | 7 years | Archive |
| **Session Tokens** | 24 hours | Delete |
---
## 🔄 Amendment Process
This constitution is a living document. Amendments require:
1. **Proposal**: Submit PR with changes to `CONSTITUTION.md`
2. **Discussion**: Team review (minimum 3 business days)
3. **Approval**: Unanimous approval from tech leads
4. **Implementation**: Update dependent documentation
5. **Communication**: Announce changes to all teams
**Version History:**
- v1.0 (2026-02-27): Initial constitution
---
## 📞 Contacts & Resources
- **Tech Lead**: [À définir]
- **Repository**: `https://git.lions.dev/lionsdev/unionflow-server-impl-quarkus`
- **Documentation**: `https://docs.lions.dev/unionflow`
- **Deployment Tool**: `lionsctl` (`lions-infrastructure-2025/lionsctl/`)
- **Support**: `support@lions.dev`
---
**Last Updated**: 2026-02-27
**Next Review**: 2026-05-27 (quarterly review)