From af930b79bb94a6c42288b26ac5b18ee5162ef4a4 Mon Sep 17 00:00:00 2001 From: Priec Date: Tue, 16 Jun 2026 23:40:53 +0200 Subject: [PATCH] loco straucture --- src/account/models/mod.rs | 1 - src/admin/models/mod.rs | 1 - src/app.rs | 24 ++++++++++++------- src/checkout/models/mod.rs | 3 --- .../admin_categories.rs} | 10 ++++---- .../mod.rs => controllers/admin_dashboard.rs} | 13 ++-------- .../form.rs => controllers/admin_form.rs} | 2 +- .../login.rs => controllers/admin_login.rs} | 5 ++-- .../orders.rs => controllers/admin_orders.rs} | 8 +++---- .../admin_products.rs} | 14 +++++------ .../admin_shipping.rs} | 4 ++-- src/{account/mod.rs => controllers/auth.rs} | 7 ++---- src/{cart/mod.rs => controllers/cart.rs} | 2 +- .../mod.rs => controllers/checkout.rs} | 16 ++++--------- src/{home/mod.rs => controllers/home.rs} | 2 +- src/{i18n/mod.rs => controllers/i18n.rs} | 0 src/{media/mod.rs => controllers/media.rs} | 0 src/controllers/mod.rs | 14 +++++++++++ src/{shop/mod.rs => controllers/shop.rs} | 8 +++---- src/initializers/admin_seeder.rs | 2 +- src/lib.rs | 20 ++++------------ src/mailers/auth.rs | 2 +- src/{admin => }/models/audit_logs.rs | 0 src/{shop => }/models/categories.rs | 0 src/models/mod.rs | 21 ++++++++++++---- src/{checkout => }/models/order_items.rs | 0 src/{checkout => }/models/orders.rs | 0 src/{shop => }/models/product_images.rs | 0 src/{shop => }/models/product_product_tags.rs | 0 src/{shop => }/models/product_tags.rs | 0 src/{shop => }/models/products.rs | 0 src/{checkout => }/models/shipping_methods.rs | 0 src/{account => }/models/users.rs | 0 src/shared/guard.rs | 4 ++-- src/shop/models/mod.rs | 5 ---- src/{account/view.rs => views/auth.rs} | 0 src/{checkout/view.rs => views/checkout.rs} | 0 src/views/mod.rs | 5 ++++ src/{shop/view.rs => views/shop.rs} | 0 tests/models/users.rs | 2 +- tests/requests/auth.rs | 2 +- tests/requests/prepare_data.rs | 2 +- 42 files changed, 97 insertions(+), 102 deletions(-) delete mode 100644 src/account/models/mod.rs delete mode 100644 src/admin/models/mod.rs delete mode 100644 src/checkout/models/mod.rs rename src/{admin/categories.rs => controllers/admin_categories.rs} (97%) rename src/{admin/mod.rs => controllers/admin_dashboard.rs} (81%) rename src/{admin/form.rs => controllers/admin_form.rs} (96%) rename src/{admin/login.rs => controllers/admin_login.rs} (94%) rename src/{admin/orders.rs => controllers/admin_orders.rs} (96%) rename src/{admin/products.rs => controllers/admin_products.rs} (97%) rename src/{admin/shipping.rs => controllers/admin_shipping.rs} (96%) rename src/{account/mod.rs => controllers/auth.rs} (98%) rename src/{cart/mod.rs => controllers/cart.rs} (98%) rename src/{checkout/mod.rs => controllers/checkout.rs} (96%) rename src/{home/mod.rs => controllers/home.rs} (88%) rename src/{i18n/mod.rs => controllers/i18n.rs} (100%) rename src/{media/mod.rs => controllers/media.rs} (100%) create mode 100644 src/controllers/mod.rs rename src/{shop/mod.rs => controllers/shop.rs} (97%) rename src/{admin => }/models/audit_logs.rs (100%) rename src/{shop => }/models/categories.rs (100%) rename src/{checkout => }/models/order_items.rs (100%) rename src/{checkout => }/models/orders.rs (100%) rename src/{shop => }/models/product_images.rs (100%) rename src/{shop => }/models/product_product_tags.rs (100%) rename src/{shop => }/models/product_tags.rs (100%) rename src/{shop => }/models/products.rs (100%) rename src/{checkout => }/models/shipping_methods.rs (100%) rename src/{account => }/models/users.rs (100%) delete mode 100644 src/shop/models/mod.rs rename src/{account/view.rs => views/auth.rs} (100%) rename src/{checkout/view.rs => views/checkout.rs} (100%) create mode 100644 src/views/mod.rs rename src/{shop/view.rs => views/shop.rs} (100%) diff --git a/src/account/models/mod.rs b/src/account/models/mod.rs deleted file mode 100644 index 913bd46..0000000 --- a/src/account/models/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod users; diff --git a/src/admin/models/mod.rs b/src/admin/models/mod.rs deleted file mode 100644 index 45b0b44..0000000 --- a/src/admin/models/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod audit_logs; diff --git a/src/app.rs b/src/app.rs index df645df..fd84398 100644 --- a/src/app.rs +++ b/src/app.rs @@ -16,8 +16,14 @@ use std::{path::Path, sync::Arc}; #[allow(unused_imports)] use crate::{ - account, admin, cart, checkout, home, i18n, initializers, media, - models::_entities::users, shop, tasks, workers::downloader::DownloadWorker, + controllers::{ + admin_categories, admin_dashboard, admin_form, admin_login, admin_orders, + admin_products, admin_shipping, auth, cart, checkout, home, i18n, media, shop, + }, + initializers, + models::_entities::users, + tasks, + workers::downloader::DownloadWorker, }; pub struct App; @@ -66,16 +72,16 @@ impl Hooks for App { .add_route(cart::routes()) .add_route(checkout::routes()) // cross-cutting - .add_route(account::routes()) + .add_route(auth::routes()) .add_route(i18n::routes()) .add_route(media::routes()) // admin - .add_route(admin::routes()) - .add_route(admin::login::routes()) - .add_route(admin::products::routes()) - .add_route(admin::categories::routes()) - .add_route(admin::orders::routes()) - .add_route(admin::shipping::routes()) + .add_route(admin_dashboard::routes()) + .add_route(admin_login::routes()) + .add_route(admin_products::routes()) + .add_route(admin_categories::routes()) + .add_route(admin_orders::routes()) + .add_route(admin_shipping::routes()) } async fn after_context(ctx: AppContext) -> Result { diff --git a/src/checkout/models/mod.rs b/src/checkout/models/mod.rs deleted file mode 100644 index 6048c01..0000000 --- a/src/checkout/models/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod order_items; -pub mod orders; -pub mod shipping_methods; diff --git a/src/admin/categories.rs b/src/controllers/admin_categories.rs similarity index 97% rename from src/admin/categories.rs rename to src/controllers/admin_categories.rs index 4186ee1..8d11121 100644 --- a/src/admin/categories.rs +++ b/src/controllers/admin_categories.rs @@ -11,14 +11,16 @@ use sea_orm::{ use serde_json::json; use crate::{ - admin::form::{read_multipart_form, store_image, MultipartForm}, - i18n::current_lang, - media::IMAGE_MAX_BYTES, + controllers::{ + admin_form::{read_multipart_form, store_image, MultipartForm}, + i18n::current_lang, + media::IMAGE_MAX_BYTES, + }, shared::{ guard, slug::{slugify, unique_slug}, }, - shop::models::{categories, products}, + models::{categories, products}, }; async fn category_by_id(ctx: &AppContext, id: i32) -> Result { diff --git a/src/admin/mod.rs b/src/controllers/admin_dashboard.rs similarity index 81% rename from src/admin/mod.rs rename to src/controllers/admin_dashboard.rs index 27c2cbc..994aec8 100644 --- a/src/admin/mod.rs +++ b/src/controllers/admin_dashboard.rs @@ -1,13 +1,4 @@ -//! Admin area. Each surface lives in its own submodule; this module holds the -//! dashboard (HTML home + JSON stats) and is the entry point for admin routes. - -pub mod categories; -pub mod form; -pub mod login; -pub mod models; -pub mod orders; -pub mod products; -pub mod shipping; +//! Admin dashboard (HTML home + JSON stats). use axum_extra::extract::cookie::CookieJar; use loco_rs::prelude::*; @@ -15,7 +6,7 @@ use sea_orm::{EntityTrait, PaginatorTrait}; use serde::Serialize; use serde_json::json; -use crate::{i18n::current_lang, models::_entities, shared::guard}; +use crate::{controllers::i18n::current_lang, models::_entities, shared::guard}; #[derive(Debug, Serialize)] struct DashboardResponse { diff --git a/src/admin/form.rs b/src/controllers/admin_form.rs similarity index 96% rename from src/admin/form.rs rename to src/controllers/admin_form.rs index 2b8c3e1..20acdd0 100644 --- a/src/admin/form.rs +++ b/src/controllers/admin_form.rs @@ -9,7 +9,7 @@ use std::collections::HashMap; use axum::extract::Multipart; use loco_rs::prelude::*; -use crate::media::{detect_image_extension, store_upload, IMAGE_MAX_BYTES, IMAGE_STORAGE_DIR}; +use crate::controllers::media::{detect_image_extension, store_upload, IMAGE_MAX_BYTES, IMAGE_STORAGE_DIR}; fn normalize_empty(value: Option) -> Option { value.and_then(|value| { diff --git a/src/admin/login.rs b/src/controllers/admin_login.rs similarity index 94% rename from src/admin/login.rs rename to src/controllers/admin_login.rs index c9438a7..6c49bcb 100644 --- a/src/admin/login.rs +++ b/src/controllers/admin_login.rs @@ -6,8 +6,9 @@ use loco_rs::prelude::*; use serde_json::json; use crate::{ - account::{self as auth_controller, models::users::{self, LoginParams}}, - i18n::current_lang, + controllers::auth as auth_controller, + models::users::{self, LoginParams}, + controllers::i18n::current_lang, shared::guard, }; diff --git a/src/admin/orders.rs b/src/controllers/admin_orders.rs similarity index 96% rename from src/admin/orders.rs rename to src/controllers/admin_orders.rs index acbd91e..9259b3a 100644 --- a/src/admin/orders.rs +++ b/src/controllers/admin_orders.rs @@ -7,11 +7,9 @@ use serde::Deserialize; use serde_json::json; use crate::{ - checkout::{ - models::{order_items, orders}, - view, - }, - i18n::current_lang, + models::{order_items, orders}, + views::checkout as view, + controllers::i18n::current_lang, shared::{guard, settings}, }; diff --git a/src/admin/products.rs b/src/controllers/admin_products.rs similarity index 97% rename from src/admin/products.rs rename to src/controllers/admin_products.rs index a7089ec..860bff8 100644 --- a/src/admin/products.rs +++ b/src/controllers/admin_products.rs @@ -10,18 +10,18 @@ use sea_orm::{ use serde_json::json; use crate::{ - admin::form::{read_multipart_form, store_image, MultipartForm}, - i18n::current_lang, - media::IMAGE_MAX_BYTES, + controllers::{ + admin_form::{read_multipart_form, store_image, MultipartForm}, + i18n::current_lang, + media::IMAGE_MAX_BYTES, + }, shared::{ guard, money::parse_price_to_cents, slug::{slugify, unique_slug}, }, - shop::{ - models::{categories, product_images, products}, - view, - }, + models::{categories, product_images, products}, + views::shop as view, }; async fn product_by_id(ctx: &AppContext, id: i32) -> Result { diff --git a/src/admin/shipping.rs b/src/controllers/admin_shipping.rs similarity index 96% rename from src/admin/shipping.rs rename to src/controllers/admin_shipping.rs index 717ff8e..0bc2c39 100644 --- a/src/admin/shipping.rs +++ b/src/controllers/admin_shipping.rs @@ -7,8 +7,8 @@ use serde::Deserialize; use serde_json::json; use crate::{ - checkout::models::shipping_methods, - i18n::current_lang, + models::shipping_methods, + controllers::i18n::current_lang, shared::{ guard, money::{format_price, parse_price_to_cents}, diff --git a/src/account/mod.rs b/src/controllers/auth.rs similarity index 98% rename from src/account/mod.rs rename to src/controllers/auth.rs index 614983f..3758d4d 100644 --- a/src/account/mod.rs +++ b/src/controllers/auth.rs @@ -1,9 +1,6 @@ -pub mod models; -pub mod view; - use crate::{ - account::models::users::{self, LoginParams, RegisterParams}, - account::view::{CurrentResponse, LoginResponse}, + models::users::{self, LoginParams, RegisterParams}, + views::auth::{CurrentResponse, LoginResponse}, mailers::auth::AuthMailer, shared::guard::is_admin, }; diff --git a/src/cart/mod.rs b/src/controllers/cart.rs similarity index 98% rename from src/cart/mod.rs rename to src/controllers/cart.rs index b726751..5407f66 100644 --- a/src/cart/mod.rs +++ b/src/controllers/cart.rs @@ -1,4 +1,4 @@ -use crate::{i18n::current_lang, shared::money::format_price, shop::models::products}; +use crate::{controllers::i18n::current_lang, shared::money::format_price, models::products}; use axum_extra::extract::cookie::{Cookie, CookieJar, SameSite}; use loco_rs::prelude::*; use sea_orm::{ColumnTrait, EntityTrait, QueryFilter}; diff --git a/src/checkout/mod.rs b/src/controllers/checkout.rs similarity index 96% rename from src/checkout/mod.rs rename to src/controllers/checkout.rs index 340a8b7..eb72b53 100644 --- a/src/checkout/mod.rs +++ b/src/controllers/checkout.rs @@ -8,18 +8,12 @@ use serde::Deserialize; use serde_json::json; use time::Duration as TimeDuration; -pub mod models; -pub mod view; - use crate::{ - cart::{resolve_cart, CART_COOKIE}, - checkout::models::{ - order_items, - orders::{self, Checkout}, - shipping_methods, - }, - i18n::current_lang, + controllers::cart::{resolve_cart, CART_COOKIE}, + models::{order_items, orders, shipping_methods}, + controllers::i18n::current_lang, shared::{money::format_price, settings}, + views::checkout as view, }; const PAYMENT_METHODS: [&str; 2] = ["cod", "bank_transfer"]; @@ -145,7 +139,7 @@ async fn place_order( let order = orders::place( &ctx, &valid, - Checkout { + orders::Checkout { email, customer_name: trimmed(&form.customer_name), address: trimmed(&form.address), diff --git a/src/home/mod.rs b/src/controllers/home.rs similarity index 88% rename from src/home/mod.rs rename to src/controllers/home.rs index 7faa885..9eb71e9 100644 --- a/src/home/mod.rs +++ b/src/controllers/home.rs @@ -4,7 +4,7 @@ use axum_extra::extract::cookie::CookieJar; use loco_rs::prelude::*; use serde_json::json; -use crate::{i18n::current_lang, shared::guard, shop}; +use crate::{controllers::i18n::current_lang, shared::guard, controllers::shop}; #[debug_handler] async fn index( diff --git a/src/i18n/mod.rs b/src/controllers/i18n.rs similarity index 100% rename from src/i18n/mod.rs rename to src/controllers/i18n.rs diff --git a/src/media/mod.rs b/src/controllers/media.rs similarity index 100% rename from src/media/mod.rs rename to src/controllers/media.rs diff --git a/src/controllers/mod.rs b/src/controllers/mod.rs new file mode 100644 index 0000000..479c95d --- /dev/null +++ b/src/controllers/mod.rs @@ -0,0 +1,14 @@ +pub mod auth; +pub mod admin_categories; +pub mod admin_dashboard; +pub mod admin_form; +pub mod admin_login; +pub mod admin_orders; +pub mod admin_products; +pub mod admin_shipping; +pub mod cart; +pub mod checkout; +pub mod home; +pub mod i18n; +pub mod media; +pub mod shop; diff --git a/src/shop/mod.rs b/src/controllers/shop.rs similarity index 97% rename from src/shop/mod.rs rename to src/controllers/shop.rs index b5166ea..669c82f 100644 --- a/src/shop/mod.rs +++ b/src/controllers/shop.rs @@ -6,13 +6,11 @@ use loco_rs::prelude::*; use sea_orm::{ColumnTrait, EntityTrait, QueryFilter, QueryOrder, QuerySelect, Set}; use serde_json::json; -pub mod models; -pub mod view; - use crate::{ - i18n::current_lang, + controllers::i18n::current_lang, shared::guard, - shop::models::{categories, product_images, products}, + models::{categories, product_images, products}, + views::shop as view, }; /// Shape a list of products into card rows, loading each one's primary image. diff --git a/src/initializers/admin_seeder.rs b/src/initializers/admin_seeder.rs index 810079e..b4d4620 100644 --- a/src/initializers/admin_seeder.rs +++ b/src/initializers/admin_seeder.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use loco_rs::prelude::*; -use crate::account::models::users::{self, RegisterParams}; +use crate::models::users::{self, RegisterParams}; pub struct AdminSeeder; diff --git a/src/lib.rs b/src/lib.rs index 3a9f39f..1ab61e9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,22 +1,10 @@ pub mod app; +pub mod controllers; pub mod data; pub mod initializers; pub mod mailers; pub mod models; -pub mod tasks; -pub mod workers; - -// Cross-cutting helpers shared by every feature. pub mod shared; - -// Feature slices: each owns its routes, handlers, view-shaping and the model -// methods/services specific to it. Generated sea-orm entities stay shared in -// `models::_entities`. -pub mod account; -pub mod admin; -pub mod cart; -pub mod checkout; -pub mod home; -pub mod i18n; -pub mod media; -pub mod shop; +pub mod tasks; +pub mod views; +pub mod workers; diff --git a/src/mailers/auth.rs b/src/mailers/auth.rs index ca385dd..88b949a 100644 --- a/src/mailers/auth.rs +++ b/src/mailers/auth.rs @@ -4,7 +4,7 @@ use loco_rs::prelude::*; use serde_json::json; -use crate::account::models::users; +use crate::models::users; static welcome: Dir<'_> = include_dir!("src/mailers/auth/welcome"); static forgot: Dir<'_> = include_dir!("src/mailers/auth/forgot"); diff --git a/src/admin/models/audit_logs.rs b/src/models/audit_logs.rs similarity index 100% rename from src/admin/models/audit_logs.rs rename to src/models/audit_logs.rs diff --git a/src/shop/models/categories.rs b/src/models/categories.rs similarity index 100% rename from src/shop/models/categories.rs rename to src/models/categories.rs diff --git a/src/models/mod.rs b/src/models/mod.rs index 7386ed0..206f25d 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -1,7 +1,18 @@ -//! Shared data layer: the sea-orm entities generated by `loco generate`. +//! Shared data layer: SeaORM entities and their hand-written model extensions. //! -//! These structs cross-reference each other (relations) and are regenerated as -//! a unit, so they live here centrally. The hand-written model methods, -//! services and view-shaping that use them live in the feature slices -//! (`shop::models`, `checkout::models`, `account::models`, …). +//! `_entities/` contains auto-generated SeaORM code (regenerated as a unit). +//! The sibling files contain hand-written model impls: ActiveModelBehavior, +//! finder methods, business logic, and query helpers. + pub mod _entities; + +pub mod audit_logs; +pub mod categories; +pub mod order_items; +pub mod orders; +pub mod product_images; +pub mod product_product_tags; +pub mod product_tags; +pub mod products; +pub mod shipping_methods; +pub mod users; diff --git a/src/checkout/models/order_items.rs b/src/models/order_items.rs similarity index 100% rename from src/checkout/models/order_items.rs rename to src/models/order_items.rs diff --git a/src/checkout/models/orders.rs b/src/models/orders.rs similarity index 100% rename from src/checkout/models/orders.rs rename to src/models/orders.rs diff --git a/src/shop/models/product_images.rs b/src/models/product_images.rs similarity index 100% rename from src/shop/models/product_images.rs rename to src/models/product_images.rs diff --git a/src/shop/models/product_product_tags.rs b/src/models/product_product_tags.rs similarity index 100% rename from src/shop/models/product_product_tags.rs rename to src/models/product_product_tags.rs diff --git a/src/shop/models/product_tags.rs b/src/models/product_tags.rs similarity index 100% rename from src/shop/models/product_tags.rs rename to src/models/product_tags.rs diff --git a/src/shop/models/products.rs b/src/models/products.rs similarity index 100% rename from src/shop/models/products.rs rename to src/models/products.rs diff --git a/src/checkout/models/shipping_methods.rs b/src/models/shipping_methods.rs similarity index 100% rename from src/checkout/models/shipping_methods.rs rename to src/models/shipping_methods.rs diff --git a/src/account/models/users.rs b/src/models/users.rs similarity index 100% rename from src/account/models/users.rs rename to src/models/users.rs diff --git a/src/shared/guard.rs b/src/shared/guard.rs index aab8b4f..db9d32f 100644 --- a/src/shared/guard.rs +++ b/src/shared/guard.rs @@ -3,8 +3,8 @@ use axum_extra::extract::cookie::CookieJar; use loco_rs::prelude::*; -use crate::account::models::users; -use crate::account::AUTH_COOKIE; +use crate::models::users; +use crate::controllers::auth::AUTH_COOKIE; use crate::shared::settings; /// Is `user` the configured admin (settings.admin_email)? diff --git a/src/shop/models/mod.rs b/src/shop/models/mod.rs deleted file mode 100644 index c9071d3..0000000 --- a/src/shop/models/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod categories; -pub mod product_images; -pub mod product_product_tags; -pub mod product_tags; -pub mod products; diff --git a/src/account/view.rs b/src/views/auth.rs similarity index 100% rename from src/account/view.rs rename to src/views/auth.rs diff --git a/src/checkout/view.rs b/src/views/checkout.rs similarity index 100% rename from src/checkout/view.rs rename to src/views/checkout.rs diff --git a/src/views/mod.rs b/src/views/mod.rs new file mode 100644 index 0000000..67afebd --- /dev/null +++ b/src/views/mod.rs @@ -0,0 +1,5 @@ +//! JSON view-shaping structs for API responses and templates. + +pub mod auth; +pub mod checkout; +pub mod shop; diff --git a/src/shop/view.rs b/src/views/shop.rs similarity index 100% rename from src/shop/view.rs rename to src/views/shop.rs diff --git a/tests/models/users.rs b/tests/models/users.rs index 6584ed9..fd8399b 100644 --- a/tests/models/users.rs +++ b/tests/models/users.rs @@ -4,7 +4,7 @@ use loco_rs::testing::prelude::*; use sea_orm::{ActiveModelTrait, ActiveValue, IntoActiveModel}; use serial_test::serial; use gitara_web::{ - account::models::users::{self, Model, RegisterParams}, + models::users::{self, Model, RegisterParams}, app::App, }; diff --git a/tests/requests/auth.rs b/tests/requests/auth.rs index 7e318c4..023e9d2 100644 --- a/tests/requests/auth.rs +++ b/tests/requests/auth.rs @@ -2,7 +2,7 @@ use insta::{assert_debug_snapshot, with_settings}; use loco_rs::testing::prelude::*; use rstest::rstest; use serial_test::serial; -use gitara_web::{account::models::users, app::App}; +use gitara_web::{models::users, app::App}; use super::prepare_data; diff --git a/tests/requests/prepare_data.rs b/tests/requests/prepare_data.rs index edf8b37..57174f7 100644 --- a/tests/requests/prepare_data.rs +++ b/tests/requests/prepare_data.rs @@ -1,6 +1,6 @@ use axum::http::{HeaderName, HeaderValue}; use loco_rs::{app::AppContext, TestServer}; -use gitara_web::{account::models::users, account::view::LoginResponse}; +use gitara_web::{models::users, views::auth::LoginResponse}; const USER_EMAIL: &str = "test@loco.com"; const USER_PASSWORD: &str = "1234";