Files
oxspeak_server/.junie/plans/migrate-seaorm-2-model-relations.md
T
2026-07-13 09:27:07 +02:00

8.9 KiB
Raw Blame History

sessionId
sessionId
session-260713-090509-126z

Requirements

Objectif

Migrer les entités SeaORM de src/models du format Relation/DeriveRelation/Related vers le format SeaORM 2.x basé sur #[sea_orm::model], avec les relations HasOne et HasMany, sans modifier le schéma SQL ni les contrats applicatifs.

Périmètre inclus

  • Migrer les quatre modèles pilotes attachment, category, channel et message.
  • Migrer ensuite les autres entités présentes sous src/models : server, user, role, server_user, role_user, channel_user, channel_user_permission, channel_role_permission, server_user_permission, server_role_permission et computed_permission.
  • Préserver les noms de tables/colonnes, les types nullable, les clés primaires et les comportements Cascade, SetNull et NoAction.
  • Conserver les implémentations ActiveModelBehavior et leurs valeurs par défaut (Uuid::new_v4/Uuid::now_v7, is_default, etc.).
  • Utiliser la syntaxe effectivement supportée par sea-orm 2.0.0-rc.42.

Hors périmètre

  • Aucun changement dans src/repositories, src/routes, DTO, réponses HTTP ou frontend.
  • Aucun changement dans migration/src/m20220101_000001_create_table.rs ou dans le schéma SQL.
  • Aucun ajout de tests spécifiques demandé dans cette étape.
  • Aucun mapping ORM artificiel pour computed_permission.resource_id, qui reste polymorphe entre serveur, catégorie et channel.

Critères dacceptation

  • Chaque entité migrée utilise un seul format SeaORM 2.x, sans ancien enum Relation ou impl Related résiduel inutile.
  • Les relations pilotes compilent avec la release candidate déclarée.
  • La relation auto-référente de Message expose un parent optionnel et plusieurs réponses, avec SetNull à la suppression du parent.
  • Les champs relationnels ne deviennent pas des colonnes dActiveModel.
  • Les commandes de compilation intermédiaires et finales réussissent, sans exiger à ce stade ladaptation des repositories.

Technical Design

État actuel

  • Cargo.toml déclare sea-orm = 2.0.0-rc.42 avec les backends SQLite/Postgres/MySQL et schema-sync; le workspace utilise Rust édition 2024.
  • Les fichiers src/models/attachment.rs, category.rs, channel.rs et message.rs utilisent actuellement DeriveEntityModel, un enum Relation avec DeriveRelation, puis des impl Related<...>.
  • message.rs contient déjà les cas particuliers reply_to_id: Option<Uuid>, ReplyTo auto-référent avec SetNull et Replies via via_rel.
  • channel.rs combine relations vers des champs nullable (server_id, category_id), une relation HasMany vers les messages et lenum SQL ChannelType.
  • Les autres entités suivent le même patron généré; leurs relations existantes doivent être transposées sans élargir le périmètre fonctionnel.
  • src/repositories/server.rs utilise category::Entity::find().find_with_related(channel::Entity). Cet usage est explicitement laissé inchangé pour cette étape; la compatibilité de compilation sera constatée, et son adaptation fera lobjet dune étape ultérieure si nécessaire.

Décisions

  • Migration incrémentale : commencer par attachment, category, channel, message, lancer cargo check, puis migrer les entités restantes par groupes dépendants.
  • Relations dans Model : représenter les relations parent/enfant avec les types SeaORM 2.x validés par la release candidate (HasOne/HasMany ou leur forme exacte requise), en conservant les cardinalités et actions SQL.
  • Schéma inchangé : les attributs de relation refléteront les migrations existantes; aucune migration SQL ne sera ajoutée.
  • Polymorphisme explicite : ne pas déclarer de relation sur computed_permission.resource_id.
  • ActiveModel séparé : vérifier que les champs de relation sont ignorés par les insertions/mises à jour et que les constructeurs new() restent inchangés.

Modifications proposées

  • Dans chaque fichier src/models/*.rs, ajouter lattribut de modèle SeaORM 2.x et déplacer les relations du bloc Relation vers les champs relationnels de Model.
  • Remplacer les impl Related et les enums Relation devenus inutiles, sans modifier les champs scalaires ni les dérivations nécessaires aux DTO/OpenAPI.
  • Pour message.rs, représenter channel, user, reply_to, attachments et replies; préserver la relation inverse auto-référente et laction on_delete = SetNull.
  • Pour channel.rs, conserver Category, Server, Message et ChannelUser, avec les relations optionnelles cohérentes avec category_id et server_id.
  • Pour server.rs, user.rs, role.rs et les tables de jonction/permissions, transposer les relations présentes dans leurs enums actuels et vérifier les colonnes source/cible contre la migration.
  • Ne pas modifier src/models/mod.rs ou prelude.rs sauf si la syntaxe SeaORM 2.x lexige pour résoudre les types dentités.

Fichiers concernés

  • Pilote : src/models/attachment.rs, src/models/category.rs, src/models/channel.rs, src/models/message.rs.
  • Lots suivants : src/models/server.rs, user.rs, role.rs, server_user.rs, role_user.rs, channel_user.rs, channel_user_permission.rs, channel_role_permission.rs, server_user_permission.rs, server_role_permission.rs, computed_permission.rs.
  • Référence en lecture seule : migration/src/m20220101_000001_create_table.rs.
  • Explicitement non modifiés : src/repositories/**, src/routes/**, frontend/** et les migrations.

Risques et garde-fous

  • La syntaxe de #[sea_orm::model] et des relations auto-référentes peut différer entre la documentation stable et rc.42; valider la version verrouillée avant d’écrire les modèles.
  • Les relations inverses et les relations multiples vers la même entité peuvent provoquer des ambiguïtés de nommage; utiliser des noms de champs distincts et compiler après chaque groupe.
  • Une compilation peut révéler que find_with_related nécessite encore lancien trait Related; ne pas corriger les repositories dans cette étape, mais documenter précisément le blocage pour la suite.
  • Comparer chaque relation avec la migration pour éviter de transformer une colonne polymorphe ou nullable en relation incorrecte.

Testing

Validation autorisée

La validation est volontairement limitée à la compilation, conformément au périmètre demandé.

  • Après le groupe pilote, exécuter cargo check.
  • Après chaque groupe dentités restant, exécuter cargo check.
  • En fin de migration, exécuter cargo fmt --all -- --check puis cargo check.
  • Vérifier par recherche statique que les entités migrées ne contiennent plus dancien enum Relation ou dimpl Related inutile.
  • Vérifier manuellement que les repositories et routes nont pas été modifiés; leurs adaptations et tests relationnels sont reportés.

Delivery Steps

✓ Step 1: Migrer les quatre modèles pilotes

Les entités pilotes utilisent le format SeaORM 2.x et compilent avec la release candidate verrouillée.

  • Adapter src/models/attachment.rs, category.rs, channel.rs et message.rs.
  • Déclarer les relations dans Model avec les types et la syntaxe exacts supportés par sea-orm 2.0.0-rc.42.
  • Préserver ChannelType, les champs optionnels et les actions Cascade, SetNull et NoAction.
  • Représenter dans message.rs le parent reply_to et les replies sans relation sur une colonne polymorphe.
  • Exécuter cargo check immédiatement après ce pilote.

✓ Step 2: Migrer les entités de base et de jonction

Les modèles de serveurs, utilisateurs, rôles et tables de jonction sont convertis sans changement de colonnes SQL.

  • Migrer server.rs, user.rs, role.rs, server_user.rs, role_user.rs et channel_user.rs.
  • Migrer les entités de permissions channel_user_permission.rs, channel_role_permission.rs, server_user_permission.rs et server_role_permission.rs.
  • Transposer chaque relation existante avec ses colonnes source/cible et sa cardinalité.
  • Conserver les implémentations ActiveModelBehavior et les valeurs par défaut propres à chaque modèle.
  • Exécuter cargo check après ce groupe.

✓ Step 3: Finaliser le modèle polymorphe et nettoyer les anciens patrons

Toutes les entités de src/models utilisent exclusivement le format SeaORM 2.x, tandis que computed_permission conserve son champ polymorphe sans faux lien ORM.

  • Migrer src/models/computed_permission.rs en conservant resource_id comme simple colonne.
  • Supprimer dans les entités migrées les enums Relation, dérivations et impl Related devenus inutiles.
  • Vérifier que les relations ne sont pas incluses dans les colonnes dActiveModel.
  • Contrôler les noms de champs relationnels et les éventuelles ambiguïtés de relations multiples.
  • Exécuter cargo fmt --all -- --check puis cargo check.
  • Ne modifier ni repositories, ni routes, ni migrations; relever séparément toute incompatibilité de find_with_related pour une future étape.