1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
//! Domain Layer Marker Traits
//!
//! This module provides marker traits for enforcing domain-driven design boundaries
//! at compile time. Types marked with these traits are guaranteed to be free of
//! infrastructure dependencies (`sqlx`, `sea_orm`, `http`, `axum`, etc.).
//!
//! # Usage
//!
//! Use the `#[domain_model]` attribute macro to mark domain types:
//!
//! ```rust,ignore
//! use modkit_macros::domain_model;
//!
//! #[domain_model]
//! pub struct User {
//! pub id: Uuid,
//! pub email: String,
//! pub created_at: DateTime<Utc>,
//! }
//! ```
//!
//! The macro will:
//! - Implement `DomainModel` for the type
//! - Validate at macro-expansion time that all fields are free of infrastructure types
//! - Generate clear error messages if forbidden types are detected
//!
//! # Enforcement
//!
//! Domain services can use trait bounds to ensure they only work with domain types:
//!
//! ```rust,ignore
//! pub trait UserRepository: Send + Sync {
//! type Model: DomainModel;
//!
//! async fn find(&self, id: Uuid) -> Result<Option<Self::Model>>;
//! }
//! ```
//!
//! # Validation Strategy
//!
//! The `#[domain_model]` macro performs validation by checking field type names against
//! a list of forbidden patterns (e.g., `sqlx::`, `http::`, `sea_orm::`). This provides
//! clear error messages at macro expansion time, similar to how `#[api_dto]` validates
//! its arguments.
//!
//! Additional enforcement is provided by Dylint lints:
//! - `DE0301`: Prohibits infrastructure imports in domain layer
//! - `DE0308`: Prohibits HTTP types in domain layer
/// Marker trait for domain models (business entities).
///
/// Domain models represent core business concepts and should:
/// - Contain only business-relevant data
/// - Be independent of persistence mechanisms
/// - Be free of infrastructure dependencies
///
/// # Usage
///
/// Use the `#[domain_model]` attribute macro to implement this trait:
///
/// ```rust,ignore
/// #[domain_model]
/// pub struct Order {
/// pub id: Uuid,
/// pub customer_id: Uuid,
/// pub total: Decimal,
/// pub status: OrderStatus,
/// }
/// ```
///
/// The macro validates field types at expansion time and generates clear error
/// messages if forbidden types (e.g., `sqlx::PgPool`, `http::StatusCode`) are detected.
///
/// # Thread Safety
///
/// This trait does not require `Send + Sync`. If you need thread-safe domain models,
/// wrap them in `Arc<T>` at the point of use.
/// Marker trait for domain errors.
///
/// Domain errors represent business rule violations and should not
/// contain infrastructure-specific error types.