Files
oxspeak_server/.junie/plans/formalize-permission-event-payloads.md
T
2026-07-25 08:55:36 +02:00

90 lines
6.6 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.
---
sessionId: session-260713-161459-1v9e
---
# Requirements
### Objectif
Créer dans `src/domain/` les payloads explicites correspondant à **tous les événements actuellement émis par `src/repositories/`**, afin quils soient réutilisables par plusieurs endpoints et consommateurs sans dépendre des modèles SeaORM, des repositories ou des DTO Gateway.
### Inclus
- Remplacer les payloads implicites des 20 émissions recensées dans `category.rs`, `channel.rs`, `group.rs`, `message.rs`, `server.rs` et `user.rs` par des contrats de domaine dédiés.
- Couvrir les événements de création, mise à jour, suppression et changement utilisateur/serveur existants.
- Prévoir des payloads dédiés pour les données complètes des créations/mises à jour et pour les identifiants nécessaires aux suppressions ; ne pas utiliser de tuple anonyme.
- Conserver les contrats de permissions déjà demandés : `ServerUserChanged`, `RoleUserChanged`, `ServerRolePermissionChanged`, `ServerUserPermissionChanged`, `ChannelRolePermissionChanged` et `ChannelUserPermissionChanged`.
- Ajouter les contrats CRUD pour les ressources `Category`, `Channel`, `Group`, `Message`, `Server` et `User`, ainsi que les payloads didentifiants de suppression et le payload `UserChanged` si nécessaire pour `user_changed`.
- Utiliser `Uuid` et des noms explicites (`category_id`, `channel_id`, `group_id`/`role_id`, `message_id`, `server_id`, `user_id`) plutôt que `id` lorsque le domaine est connu.
- Dériver `Clone` et `Debug` sur chaque struct, avec une composition compatible avec `Send + Sync + 'static`.
- Exposer les contrats depuis `crate::domain` pour une utilisation multi-endpoint.
### Exclus
- Aucun branchement des nouveaux types dans les repositories et aucune modification de `Repositories`.
- Aucun changement de nom de topic, de logique CRUD, dordre mutation puis émission ou de comportement de suppression.
- Aucun abonnement ou traitement dans `src/core/permission_sync.rs`.
- Aucun pont avec les événements ou DTO de `src/routes/gateway/mod.rs`.
- Aucun partage direct des modèles SeaORM comme contrat de domaine.
# Technical Design
### Contexte actuel
- Les 20 appels `EventBus::emit` sont répartis entre six repositories ; `computed_permission.rs` ne produit actuellement aucun événement.
- Les créations et mises à jour transmettent des modèles SeaORM, tandis que les suppressions transmettent généralement un `Uuid`; `server_user_created` transmet un tuple `(server_id, user_id)`.
- `message_deleted` et `user_deleted` vérifient déjà `rows_affected` avant émission, alors que dautres suppressions devront conserver leur comportement actuel dans cette étape.
- `src/routes/gateway/mod.rs` consomme certains événements de canal avec ses propres modèles ; les contrats de domaine resteront indépendants.
### Organisation proposée
- Ajouter `src/domain/mod.rs` et un sous-module par famille émettrice :
- `category.rs`, `channel.rs`, `group.rs`, `message.rs`, `server.rs` et `user.rs` pour les événements CRUD et les changements de relation.
- `server_role_permission.rs`, `server_user_permission.rs`, `channel_role_permission.rs` et `channel_user_permission.rs` pour les contrats de permissions.
- Définir dans chaque module les payloads spécifiques nécessaires aux topics de sa famille, par exemple `CategoryChanged`/`CategoryDeleted`, `ChannelChanged`/`ChannelDeleted`, `MessageChanged`/`MessageDeleted`, `ServerChanged`/`ServerDeleted` et `UserChanged`/`UserDeleted`.
- Utiliser des structs distinctes lorsque les événements de création/mise à jour transportent plusieurs propriétés et lorsquune suppression ne nécessite que lidentifiant ; le contenu exact doit refléter les informations actuellement véhiculées par les modèles, sans importer SeaORM dans `domain`.
- Conserver `ServerUserChanged` et `RoleUserChanged` comme contrats relationnels identifiés, avec les champs `server_id`, `role_id` et `user_id`.
- Réexporter sélectivement tous les contrats depuis `crate::domain`; ajouter `pub mod domain;` dans `src/lib.rs`.
- Ne modifier ni `src/repositories/mod.rs`, ni `src/core/permission_sync.rs`, ni les routes Gateway.
### Contrats de données
Tous les contrats suivent ce style :
```rust
use uuid::Uuid;
#[derive(Clone, Debug)]
pub struct ServerUserChanged {
pub server_id: Uuid,
pub user_id: Uuid,
}
#[derive(Clone, Debug)]
pub struct ChannelDeleted {
pub channel_id: Uuid,
}
```
Les payloads de ressource complète reprennent explicitement les champs utiles du modèle courant ; les payloads de suppression reprennent lidentifiant nommé de la ressource. Les six contrats de permissions utilisent respectivement `server_id`, `role_id`, `channel_id` et `user_id` selon leur responsabilité, sans bitmask implicite ni modèle persisté.
### Risques et garde-fous
- Les contrats CRUD devront être suffisamment complets pour ne pas perdre dinformation lors du futur branchement des repositories ; la liste de champs sera vérifiée contre `src/models/*.rs`.
- Le changement ultérieur des payloads de topics de canal pourra nécessiter une adaptation du Gateway ; cette intégration est explicitement exclue.
- Les payloads ne doivent pas être centralisés dans `repositories` ni dépendre de SeaORM, afin de rester utilisables par plusieurs endpoints.
# Testing
### Validation
- Ajouter des assertions ou tests de compilation pour instancier chaque contrat public et accéder à tous ses champs.
- Vérifier les familles couvrant chaque émission : `category_*`, `channel_*`, `group_*`, `message_*`, `server_*` et `user_*`, y compris les suppressions et `server_user_created`.
- Vérifier `Clone`, `Debug`, `Send`, `Sync` et `'static` pour tous les payloads.
- Vérifier les imports via `crate::domain::{...}` et exécuter `cargo check` ainsi que les tests ciblés.
### Limites de validation
Les émissions réelles, les changements de topics, la consommation par `PermissionSyncService`, les recalculs de permissions et lintégration Gateway restent hors périmètre ; le demandeur réalisera leur branchement ultérieurement.
### ✓ Step 1: Recenser les émissions et les modèles
- Vérifier les topics et les champs actuellement transmis par chaque repository.
- Vérifier les modèles correspondants pour définir les contrats complets.
### ✓ Step 2: Créer les modules et payloads de domaine
- Ajouter les modules `src/domain/` et les structs CRUD, relationnelles et de permissions.
- Exposer les contrats depuis `crate::domain` sans modifier les repositories.
### ✓ Step 3: Ajouter la validation des contrats
- Ajouter des assertions de compilation couvrant les structs et leurs champs.
- Exécuter `cargo check` et les tests ciblés.