From 843dad8d793fe989123ebc0778df97b929e0fed2 Mon Sep 17 00:00:00 2001 From: Nell Date: Mon, 13 Jul 2026 09:27:07 +0200 Subject: [PATCH] init --- .../plans/migrate-seaorm-2-model-relations.md | 106 ++++++++++++++ Cargo.lock | 4 +- Cargo.toml | 2 +- src/models/attachment.rs | 81 +++++------ src/models/category.rs | 29 +--- src/models/channel.rs | 53 ++----- src/models/channel_role_permission.rs | 34 ++--- src/models/channel_user.rs | 101 ++++++------- src/models/channel_user_permission.rs | 34 ++--- src/models/computed_permission.rs | 19 +-- src/models/message.rs | 137 ++++++++---------- src/models/role.rs | 29 +--- src/models/role_user.rs | 33 ++--- src/models/server.rs | 35 +---- src/models/server_role_permission.rs | 34 ++--- src/models/server_user.rs | 103 ++++++------- src/models/server_user_permission.rs | 34 ++--- src/models/user.rs | 122 +++++++--------- 18 files changed, 427 insertions(+), 563 deletions(-) create mode 100644 .junie/plans/migrate-seaorm-2-model-relations.md diff --git a/.junie/plans/migrate-seaorm-2-model-relations.md b/.junie/plans/migrate-seaorm-2-model-relations.md new file mode 100644 index 0000000..5b3090c --- /dev/null +++ b/.junie/plans/migrate-seaorm-2-model-relations.md @@ -0,0 +1,106 @@ +--- +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 d’acceptation +- 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 d’`ActiveModel`. +- Les commandes de compilation intermédiaires et finales réussissent, sans exiger à ce stade l’adaptation 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`, `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 l’enum 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 l’objet d’une é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 l’attribut 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 l’action `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 l’exige pour résoudre les types d’entité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 l’ancien 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 d’entité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 d’ancien enum `Relation` ou d’`impl Related` inutile. +- Vérifier manuellement que les repositories et routes n’ont 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 d’`ActiveModel`. +- 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. \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 10a6c6b..ff67ddf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4215,9 +4215,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.23.4" +version = "1.23.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" +checksum = "ea5fab0d6c3c01ae70085a09cb03d4c7a1d6314e2b3e075392783396d724ca0a" dependencies = [ "getrandom 0.4.3", "js-sys", diff --git a/Cargo.toml b/Cargo.toml index 07c0d55..76b57cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ parking_lot = "0.12.5" serde = "1.0.228" serde_json = "1.0.150" toml = "1.1.2" -uuid = { version = "1.23.4", features = ["v4", "v7", "fast-rng", "serde"] } +uuid = { version = "1.23.5", features = ["v4", "v7", "fast-rng", "serde"] } tracing = "0.1.44" tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt", "time"] } thiserror = "2" diff --git a/src/models/attachment.rs b/src/models/attachment.rs index 2a534a9..6ffe5ac 100644 --- a/src/models/attachment.rs +++ b/src/models/attachment.rs @@ -1,45 +1,36 @@ -//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.19 - -use sea_orm::entity::prelude::*; -use sea_orm::prelude::async_trait::async_trait; -use sea_orm::Set; - -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] -#[sea_orm(table_name = "attachment")] -pub struct Model { - #[sea_orm(primary_key, auto_increment = false)] - pub id: Uuid, - pub message_id: Uuid, - pub filename: String, - pub file_size: i32, - pub mime_type: String, - pub created_at: DateTimeUtc, -} - -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation { - #[sea_orm( - belongs_to = "super::message::Entity", - from = "Column::MessageId", - to = "super::message::Column::Id", - on_update = "NoAction", - on_delete = "Cascade" - )] - Message, -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Message.def() - } -} - -#[async_trait] -impl ActiveModelBehavior for ActiveModel { - fn new() -> Self { - Self { - id: Set(Uuid::new_v4()), - ..ActiveModelTrait::default() - } - } -} +//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.19 + +use sea_orm::entity::prelude::*; +use sea_orm::prelude::async_trait::async_trait; +use sea_orm::Set; + +#[sea_orm::model] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "attachment")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: Uuid, + pub message_id: Uuid, + pub filename: String, + pub file_size: i32, + pub mime_type: String, + pub created_at: DateTimeUtc, + #[sea_orm( + belongs_to, + from = "message_id", + to = "id", + on_update = "NoAction", + on_delete = "Cascade" + )] + pub message: HasOne, +} + +#[async_trait] +impl ActiveModelBehavior for ActiveModel { + fn new() -> Self { + Self { + id: Set(Uuid::new_v4()), + ..ActiveModelTrait::default() + } + } +} diff --git a/src/models/category.rs b/src/models/category.rs index 12ffbd9..d40ed7b 100644 --- a/src/models/category.rs +++ b/src/models/category.rs @@ -4,6 +4,7 @@ use sea_orm::entity::prelude::*; use sea_orm::prelude::async_trait::async_trait; use sea_orm::Set; +#[sea_orm::model] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] #[sea_orm(table_name = "category")] pub struct Model { @@ -14,32 +15,16 @@ pub struct Model { pub position: i32, pub created_at: DateTimeUtc, pub updated_at: DateTimeUtc, -} - -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation { - #[sea_orm(has_many = "super::channel::Entity")] - Channel, + #[sea_orm(has_many)] + pub channels: HasMany, #[sea_orm( - belongs_to = "super::server::Entity", - from = "Column::ServerId", - to = "super::server::Column::Id", + belongs_to, + from = "server_id", + to = "id", on_update = "Cascade", on_delete = "Cascade" )] - Server, -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Channel.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Server.def() - } + pub server: HasOne, } #[async_trait] diff --git a/src/models/channel.rs b/src/models/channel.rs index 063391c..04f6bae 100644 --- a/src/models/channel.rs +++ b/src/models/channel.rs @@ -20,6 +20,7 @@ pub enum ChannelType { DM, } +#[sea_orm::model] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] #[sea_orm(table_name = "channel")] pub struct Model { @@ -32,54 +33,26 @@ pub struct Model { pub name: Option, pub created_at: DateTimeUtc, pub updated_at: DateTimeUtc, -} - -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation { #[sea_orm( - belongs_to = "super::category::Entity", - from = "Column::CategoryId", - to = "super::category::Column::Id", + belongs_to, + from = "category_id", + to = "id", on_update = "NoAction", on_delete = "SetNull" )] - Category, - #[sea_orm(has_many = "super::channel_user::Entity")] - ChannelUser, - #[sea_orm(has_many = "super::message::Entity")] - Message, + pub category: HasOne, + #[sea_orm(has_many)] + pub channel_users: HasMany, + #[sea_orm(has_many)] + pub messages: HasMany, #[sea_orm( - belongs_to = "super::server::Entity", - from = "Column::ServerId", - to = "super::server::Column::Id", + belongs_to, + from = "server_id", + to = "id", on_update = "NoAction", on_delete = "Cascade" )] - Server, -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Category.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::ChannelUser.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Message.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Server.def() - } + pub server: HasOne, } #[async_trait] diff --git a/src/models/channel_role_permission.rs b/src/models/channel_role_permission.rs index 1e31c7c..ff95d27 100644 --- a/src/models/channel_role_permission.rs +++ b/src/models/channel_role_permission.rs @@ -5,6 +5,7 @@ use sea_orm::entity::prelude::*; use sea_orm::prelude::async_trait::async_trait; use sea_orm::{NotSet, Set}; +#[sea_orm::model] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] #[sea_orm(table_name = "channel_role_permission")] pub struct Model { @@ -17,39 +18,22 @@ pub struct Model { /// Bitmask des permissions accordées au rôle dans ce canal. pub permission: i64, -} - -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation { #[sea_orm( - belongs_to = "super::channel::Entity", - from = "Column::ChannelId", - to = "super::channel::Column::Id", + belongs_to, + from = "channel_id", + to = "id", on_update = "NoAction", on_delete = "Cascade" )] - Channel, - + pub channel: HasOne, #[sea_orm( - belongs_to = "super::role::Entity", - from = "Column::RoleId", - to = "super::role::Column::Id", + belongs_to, + from = "role_id", + to = "id", on_update = "NoAction", on_delete = "Cascade" )] - Role, -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Channel.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Role.def() - } + pub role: HasOne, } #[async_trait] diff --git a/src/models/channel_user.rs b/src/models/channel_user.rs index 22a44da..d3b6d94 100644 --- a/src/models/channel_user.rs +++ b/src/models/channel_user.rs @@ -1,58 +1,43 @@ -//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.19 - -use sea_orm::entity::prelude::*; -use sea_orm::prelude::async_trait::async_trait; -use sea_orm::Set; - -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] -#[sea_orm(table_name = "channel_user")] -pub struct Model { - #[sea_orm(primary_key, auto_increment = false)] - pub id: Uuid, - pub channel_id: Uuid, - pub user_id: Uuid, - pub role: String, - pub joined_at: DateTimeUtc, -} - -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation { - #[sea_orm( - belongs_to = "super::channel::Entity", - from = "Column::ChannelId", - to = "super::channel::Column::Id", - on_update = "NoAction", - on_delete = "Cascade" - )] - Channel, - #[sea_orm( - belongs_to = "super::user::Entity", - from = "Column::UserId", - to = "super::user::Column::Id", - on_update = "NoAction", - on_delete = "Cascade" - )] - User, -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Channel.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::User.def() - } -} - -#[async_trait] -impl ActiveModelBehavior for ActiveModel { - fn new() -> Self { - Self { - id: Set(Uuid::new_v4()), - ..ActiveModelTrait::default() - } - } -} +//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.19 + +use sea_orm::entity::prelude::*; +use sea_orm::prelude::async_trait::async_trait; +use sea_orm::Set; + +#[sea_orm::model] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "channel_user")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: Uuid, + pub channel_id: Uuid, + pub user_id: Uuid, + pub role: String, + pub joined_at: DateTimeUtc, + #[sea_orm( + belongs_to, + from = "channel_id", + to = "id", + on_update = "NoAction", + on_delete = "Cascade" + )] + pub channel: HasOne, + #[sea_orm( + belongs_to, + from = "user_id", + to = "id", + on_update = "NoAction", + on_delete = "Cascade" + )] + pub user: HasOne, +} + +#[async_trait] +impl ActiveModelBehavior for ActiveModel { + fn new() -> Self { + Self { + id: Set(Uuid::new_v4()), + ..ActiveModelTrait::default() + } + } +} diff --git a/src/models/channel_user_permission.rs b/src/models/channel_user_permission.rs index 0838676..6ad4e9b 100644 --- a/src/models/channel_user_permission.rs +++ b/src/models/channel_user_permission.rs @@ -5,6 +5,7 @@ use sea_orm::entity::prelude::*; use sea_orm::prelude::async_trait::async_trait; use sea_orm::{NotSet, Set}; +#[sea_orm::model] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] #[sea_orm(table_name = "channel_user_permission")] pub struct Model { @@ -17,39 +18,22 @@ pub struct Model { /// Bitmask des permissions accordées directement à l'utilisateur dans ce canal. pub permission: i64, -} - -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation { #[sea_orm( - belongs_to = "super::channel::Entity", - from = "Column::ChannelId", - to = "super::channel::Column::Id", + belongs_to, + from = "channel_id", + to = "id", on_update = "NoAction", on_delete = "Cascade" )] - Channel, - + pub channel: HasOne, #[sea_orm( - belongs_to = "super::user::Entity", - from = "Column::UserId", - to = "super::user::Column::Id", + belongs_to, + from = "user_id", + to = "id", on_update = "NoAction", on_delete = "Cascade" )] - User, -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Channel.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::User.def() - } + pub user: HasOne, } #[async_trait] diff --git a/src/models/computed_permission.rs b/src/models/computed_permission.rs index 128bb4f..82c5f6d 100644 --- a/src/models/computed_permission.rs +++ b/src/models/computed_permission.rs @@ -20,6 +20,7 @@ pub enum PermissionScopeType { Channel, } +#[sea_orm::model] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] #[sea_orm(table_name = "computed_permission")] pub struct Model { @@ -39,24 +40,14 @@ pub struct Model { /// Cache des permissions serveur (stocké en i64 pour SQL, utilisé en u64) pub server_permissions: i64, pub channel_permissions: i64, -} - -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation { #[sea_orm( - belongs_to = "super::user::Entity", - from = "Column::UserId", - to = "super::user::Column::Id", + belongs_to, + from = "user_id", + to = "id", on_update = "NoAction", on_delete = "Cascade" )] - User, -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::User.def() - } + pub user: HasOne, } #[async_trait] diff --git a/src/models/message.rs b/src/models/message.rs index 2811b3e..030ff14 100644 --- a/src/models/message.rs +++ b/src/models/message.rs @@ -1,77 +1,60 @@ -//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.19 - -use sea_orm::entity::prelude::*; -use sea_orm::prelude::async_trait::async_trait; -use sea_orm::Set; - -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] -#[sea_orm(table_name = "message")] -pub struct Model { - #[sea_orm(primary_key, auto_increment = false)] - pub id: Uuid, - pub channel_id: Uuid, - pub user_id: Uuid, - #[sea_orm(column_type = "Text")] - pub content: String, - pub created_at: DateTimeUtc, - pub updated_at: Option, - pub reply_to_id: Option, -} - -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation { - #[sea_orm(has_many = "super::attachment::Entity")] - Attachment, - #[sea_orm( - belongs_to = "super::channel::Entity", - from = "Column::ChannelId", - to = "super::channel::Column::Id", - on_update = "NoAction", - on_delete = "Cascade" - )] - Channel, - #[sea_orm( - belongs_to = "Entity", - from = "Column::ReplyToId", - to = "Column::Id", - on_update = "NoAction", - on_delete = "SetNull" - )] - SelfRef, - #[sea_orm( - belongs_to = "super::user::Entity", - from = "Column::UserId", - to = "super::user::Column::Id", - on_update = "NoAction", - on_delete = "Cascade" - )] - User, -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Attachment.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Channel.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::User.def() - } -} - -#[async_trait] -impl ActiveModelBehavior for ActiveModel { - fn new() -> Self { - Self { - id: Set(Uuid::now_v7()), - ..ActiveModelTrait::default() - } - } -} +//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.19 + +use sea_orm::entity::prelude::*; +use sea_orm::prelude::async_trait::async_trait; +use sea_orm::Set; + +#[sea_orm::model] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "message")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: Uuid, + pub channel_id: Uuid, + pub user_id: Uuid, + #[sea_orm(column_type = "Text")] + pub content: String, + pub created_at: DateTimeUtc, + pub updated_at: Option, + pub reply_to_id: Option, + #[sea_orm(has_many)] + pub attachments: HasMany, + #[sea_orm( + belongs_to, + from = "channel_id", + to = "id", + on_update = "NoAction", + on_delete = "Cascade" + )] + pub channel: HasOne, + #[sea_orm( + self_ref, + relation_enum = "ReplyTo", + relation_reverse = "Replies", + from = "reply_to_id", + to = "id", + on_update = "NoAction", + on_delete = "SetNull" + )] + pub reply_to: HasOne, + #[sea_orm(self_ref, relation_enum = "Replies", relation_reverse = "ReplyTo")] + pub replies: HasMany, + #[sea_orm( + belongs_to, + from = "user_id", + to = "id", + on_update = "NoAction", + on_delete = "Cascade" + )] + pub user: HasOne, +} + +#[async_trait] +impl ActiveModelBehavior for ActiveModel { + fn new() -> Self { + Self { + id: Set(Uuid::now_v7()), + ..ActiveModelTrait::default() + } + } +} diff --git a/src/models/role.rs b/src/models/role.rs index 7b5c684..c7ad6a7 100644 --- a/src/models/role.rs +++ b/src/models/role.rs @@ -4,6 +4,7 @@ use sea_orm::entity::prelude::*; use sea_orm::prelude::async_trait::async_trait; use sea_orm::Set; +#[sea_orm::model] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] #[sea_orm(table_name = "role")] pub struct Model { @@ -13,32 +14,16 @@ pub struct Model { pub name: String, pub is_default: bool, pub created_at: DateTimeUtc, -} - -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation { #[sea_orm( - belongs_to = "super::server::Entity", - from = "Column::ServerId", - to = "super::server::Column::Id", + belongs_to, + from = "server_id", + to = "id", on_update = "NoAction", on_delete = "Cascade" )] - Server, - #[sea_orm(has_many = "super::role_user::Entity")] - RoleUser, -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Server.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::RoleUser.def() - } + pub server: HasOne, + #[sea_orm(has_many)] + pub role_users: HasMany, } #[async_trait] diff --git a/src/models/role_user.rs b/src/models/role_user.rs index 4e80efc..b174dba 100644 --- a/src/models/role_user.rs +++ b/src/models/role_user.rs @@ -2,6 +2,7 @@ use sea_orm::entity::prelude::*; +#[sea_orm::model] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] #[sea_orm(table_name = "role_user")] pub struct Model { @@ -9,38 +10,22 @@ pub struct Model { pub role_id: Uuid, #[sea_orm(primary_key, auto_increment = false)] pub user_id: Uuid, -} - -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation { #[sea_orm( - belongs_to = "super::role::Entity", - from = "Column::RoleId", - to = "super::role::Column::Id", + belongs_to, + from = "role_id", + to = "id", on_update = "NoAction", on_delete = "Cascade" )] - Group, + pub role: HasOne, #[sea_orm( - belongs_to = "super::user::Entity", - from = "Column::UserId", - to = "super::user::Column::Id", + belongs_to, + from = "user_id", + to = "id", on_update = "NoAction", on_delete = "Cascade" )] - User, -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Group.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::User.def() - } + pub user: HasOne, } impl ActiveModelBehavior for ActiveModel {} diff --git a/src/models/server.rs b/src/models/server.rs index b5fdacc..1e19bfd 100644 --- a/src/models/server.rs +++ b/src/models/server.rs @@ -4,6 +4,7 @@ use sea_orm::entity::prelude::*; use sea_orm::prelude::async_trait::async_trait; use sea_orm::Set; +#[sea_orm::model] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] #[sea_orm(table_name = "server")] pub struct Model { @@ -15,34 +16,12 @@ pub struct Model { pub updated_at: DateTimeUtc, pub is_default: bool, pub owner_id: Option, -} - -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation { - #[sea_orm(has_many = "super::category::Entity")] - Category, - #[sea_orm(has_many = "super::channel::Entity")] - Channel, - #[sea_orm(has_many = "super::server_user::Entity")] - ServerUser, -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Category.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Channel.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::ServerUser.def() - } + #[sea_orm(has_many)] + pub categories: HasMany, + #[sea_orm(has_many)] + pub channels: HasMany, + #[sea_orm(has_many)] + pub server_users: HasMany, } #[async_trait] diff --git a/src/models/server_role_permission.rs b/src/models/server_role_permission.rs index 2294e1c..e6a436d 100644 --- a/src/models/server_role_permission.rs +++ b/src/models/server_role_permission.rs @@ -3,6 +3,7 @@ use sea_orm::entity::prelude::*; use sea_orm::prelude::async_trait::async_trait; use sea_orm::{NotSet, Set}; +#[sea_orm::model] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] #[sea_orm(table_name = "server_group_permission")] pub struct Model { @@ -17,39 +18,22 @@ pub struct Model { /// Bitmask des permissions accordées directement à l'utilisateur. pub permission: i64, -} - -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation { #[sea_orm( - belongs_to = "super::server::Entity", - from = "Column::ServerId", - to = "super::server::Column::Id", + belongs_to, + from = "server_id", + to = "id", on_update = "NoAction", on_delete = "Cascade" )] - Server, - + pub server: HasOne, #[sea_orm( - belongs_to = "super::role::Entity", - from = "Column::RoleId", - to = "super::role::Column::Id", + belongs_to, + from = "role_id", + to = "id", on_update = "NoAction", on_delete = "Cascade" )] - Role, -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Server.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Role.def() - } + pub role: HasOne, } #[async_trait] diff --git a/src/models/server_user.rs b/src/models/server_user.rs index cd6b194..ad3f603 100644 --- a/src/models/server_user.rs +++ b/src/models/server_user.rs @@ -1,59 +1,44 @@ -//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.19 - -use sea_orm::entity::prelude::*; -use sea_orm::prelude::async_trait::async_trait; -use sea_orm::Set; - -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] -#[sea_orm(table_name = "server_user")] -pub struct Model { - #[sea_orm(primary_key, auto_increment = false)] - pub id: Uuid, - pub server_id: Uuid, - pub user_id: Uuid, - pub username: Option, - pub joined_at: DateTimeUtc, - pub updated_at: DateTimeUtc, -} - -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation { - #[sea_orm( - belongs_to = "super::server::Entity", - from = "Column::ServerId", - to = "super::server::Column::Id", - on_update = "NoAction", - on_delete = "Cascade" - )] - Server, - #[sea_orm( - belongs_to = "super::user::Entity", - from = "Column::UserId", - to = "super::user::Column::Id", - on_update = "NoAction", - on_delete = "Cascade" - )] - User, -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Server.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::User.def() - } -} - -#[async_trait] -impl ActiveModelBehavior for ActiveModel { - fn new() -> Self { - Self { - id: Set(Uuid::new_v4()), - ..ActiveModelTrait::default() - } - } -} +//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.19 + +use sea_orm::entity::prelude::*; +use sea_orm::prelude::async_trait::async_trait; +use sea_orm::Set; + +#[sea_orm::model] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "server_user")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: Uuid, + pub server_id: Uuid, + pub user_id: Uuid, + pub username: Option, + pub joined_at: DateTimeUtc, + pub updated_at: DateTimeUtc, + #[sea_orm( + belongs_to, + from = "server_id", + to = "id", + on_update = "NoAction", + on_delete = "Cascade" + )] + pub server: HasOne, + #[sea_orm( + belongs_to, + from = "user_id", + to = "id", + on_update = "NoAction", + on_delete = "Cascade" + )] + pub user: HasOne, +} + +#[async_trait] +impl ActiveModelBehavior for ActiveModel { + fn new() -> Self { + Self { + id: Set(Uuid::new_v4()), + ..ActiveModelTrait::default() + } + } +} diff --git a/src/models/server_user_permission.rs b/src/models/server_user_permission.rs index e39438c..fa19e51 100644 --- a/src/models/server_user_permission.rs +++ b/src/models/server_user_permission.rs @@ -3,6 +3,7 @@ use sea_orm::entity::prelude::*; use sea_orm::prelude::async_trait::async_trait; use sea_orm::{NotSet, Set}; +#[sea_orm::model] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] #[sea_orm(table_name = "server_user_permission")] pub struct Model { @@ -17,39 +18,22 @@ pub struct Model { /// Bitmask des permissions accordées directement à l'utilisateur. pub permission: i64, -} - -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation { #[sea_orm( - belongs_to = "super::server::Entity", - from = "Column::ServerId", - to = "super::server::Column::Id", + belongs_to, + from = "server_id", + to = "id", on_update = "NoAction", on_delete = "Cascade" )] - Server, - + pub server: HasOne, #[sea_orm( - belongs_to = "super::user::Entity", - from = "Column::UserId", - to = "super::user::Column::Id", + belongs_to, + from = "user_id", + to = "id", on_update = "NoAction", on_delete = "Cascade" )] - User, -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Server.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::User.def() - } + pub user: HasOne, } #[async_trait] diff --git a/src/models/user.rs b/src/models/user.rs index f2a04c2..49b8ca1 100644 --- a/src/models/user.rs +++ b/src/models/user.rs @@ -1,71 +1,51 @@ -//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.19 - -use sea_orm::entity::prelude::*; -use sea_orm::prelude::async_trait::async_trait; -use sea_orm::Set; - -#[derive(Clone, PartialEq, DeriveEntityModel, Eq)] -#[sea_orm(table_name = "user")] -pub struct Model { - #[sea_orm(primary_key, auto_increment = false)] - pub id: Uuid, - pub username: String, - pub password: String, - #[sea_orm(column_type = "Text", unique, nullable)] - pub pub_key: Option, - pub created_at: DateTimeUtc, - pub updated_at: DateTimeUtc, - pub is_superuser: bool, -} - -impl std::fmt::Debug for Model { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("User") - .field("id", &self.id) - .field("username", &self.username) - .field("password", &"") - .field("pub_key", &self.pub_key) - .field("created_at", &self.created_at) - .field("updated_at", &self.updated_at) - .field("is_superuser", &self.is_superuser) - .finish() - } -} - -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation { - #[sea_orm(has_many = "super::channel_user::Entity")] - ChannelUser, - #[sea_orm(has_many = "super::message::Entity")] - Message, - #[sea_orm(has_many = "super::server_user::Entity")] - ServerUser, -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::ChannelUser.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Message.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::ServerUser.def() - } -} - -#[async_trait] -impl ActiveModelBehavior for ActiveModel { - fn new() -> Self { - Self { - id: Set(Uuid::new_v4()), - ..ActiveModelTrait::default() - } - } -} +//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.19 + +use sea_orm::entity::prelude::*; +use sea_orm::prelude::async_trait::async_trait; +use sea_orm::Set; + +#[sea_orm::model] +#[sea_orm(model_ex_attrs(derive(Debug)))] +#[derive(Clone, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "user")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: Uuid, + pub username: String, + pub password: String, + #[sea_orm(column_type = "Text", unique, nullable)] + pub pub_key: Option, + pub created_at: DateTimeUtc, + pub updated_at: DateTimeUtc, + pub is_superuser: bool, + #[sea_orm(has_many)] + pub channel_users: HasMany, + #[sea_orm(has_many)] + pub messages: HasMany, + #[sea_orm(has_many)] + pub server_users: HasMany, +} + +impl std::fmt::Debug for Model { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("User") + .field("id", &self.id) + .field("username", &self.username) + .field("password", &"") + .field("pub_key", &self.pub_key) + .field("created_at", &self.created_at) + .field("updated_at", &self.updated_at) + .field("is_superuser", &self.is_superuser) + .finish() + } +} + +#[async_trait] +impl ActiveModelBehavior for ActiveModel { + fn new() -> Self { + Self { + id: Set(Uuid::new_v4()), + ..ActiveModelTrait::default() + } + } +}