loco straucture
This commit is contained in:
@@ -1 +0,0 @@
|
||||
pub mod users;
|
||||
@@ -1 +0,0 @@
|
||||
pub mod audit_logs;
|
||||
24
src/app.rs
24
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<AppContext> {
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
pub mod order_items;
|
||||
pub mod orders;
|
||||
pub mod shipping_methods;
|
||||
@@ -11,14 +11,16 @@ use sea_orm::{
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{
|
||||
admin::form::{read_multipart_form, store_image, MultipartForm},
|
||||
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<categories::Model> {
|
||||
@@ -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 {
|
||||
@@ -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<String>) -> Option<String> {
|
||||
value.and_then(|value| {
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -7,11 +7,9 @@ use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{
|
||||
checkout::{
|
||||
models::{order_items, orders},
|
||||
view,
|
||||
},
|
||||
i18n::current_lang,
|
||||
views::checkout as view,
|
||||
controllers::i18n::current_lang,
|
||||
shared::{guard, settings},
|
||||
};
|
||||
|
||||
@@ -10,18 +10,18 @@ use sea_orm::{
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{
|
||||
admin::form::{read_multipart_form, store_image, MultipartForm},
|
||||
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,
|
||||
},
|
||||
views::shop as view,
|
||||
};
|
||||
|
||||
async fn product_by_id(ctx: &AppContext, id: i32) -> Result<products::Model> {
|
||||
@@ -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},
|
||||
@@ -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,
|
||||
};
|
||||
@@ -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};
|
||||
@@ -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),
|
||||
@@ -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(
|
||||
14
src/controllers/mod.rs
Normal file
14
src/controllers/mod.rs
Normal file
@@ -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;
|
||||
@@ -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.
|
||||
@@ -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;
|
||||
|
||||
|
||||
20
src/lib.rs
20
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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)?
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
pub mod categories;
|
||||
pub mod product_images;
|
||||
pub mod product_product_tags;
|
||||
pub mod product_tags;
|
||||
pub mod products;
|
||||
5
src/views/mod.rs
Normal file
5
src/views/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
//! JSON view-shaping structs for API responses and templates.
|
||||
|
||||
pub mod auth;
|
||||
pub mod checkout;
|
||||
pub mod shop;
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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";
|
||||
|
||||
Reference in New Issue
Block a user