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
//! `arcature-data` — the Arcature high-level data layer over `arcature-db`.
//!
//! AP2.1-6 (ADR-0006): a high-level model/query experience for ordinary CRUD
//! over SeaORM, preserving the SeaORM and SQLx escape hatches. **No new database
//! engine, no ORM, no hidden global pool, no task-local connection, and no
//! request-global DB.** Every public API takes the [`Db`] handle (or the
//! `DatabaseConnection` / `PgPool` it exposes) by reference — ownership is
//! explicit on every call.
//!
//! # What this crate owns
//!
//! * **Explicit-ownership query ergonomics** over SeaORM entities: a typed
//! [`Query<E>`] bound to a `&Db`, reached on the golden path as
//! `Entity::query(&db)` via the blanket [`QueryModel`] trait (no application
//! trait implementation required — it works for any SeaORM `Entity`).
//! * **Vertical slices:** find by primary key, filter, order, paginate
//! ([`Page<T>`]), eager-load typed relations, and CRUD — all carrying the
//! `&Db` so the caller never re-passes `db.orm()` on every terminal call.
//! * **Typed transactions** ([`Transaction`]) over the SeaORM and SQLx paths,
//! with explicit ownership and no hidden nesting/savepoint magic.
//! * **Development/CI N+1 detection** behind the `n1` Cargo feature: a
//! request-scoped tracker (`n1::Tracker`) that records query events with
//! source attribution and reports likely relation N+1 patterns. **Zero
//! production hot-path overhead when the feature is off** — the tracker, the
//! recording calls, and the analyzer are `cfg`-gated out of the default
//! build.
//! * **Migration lint** ([`classify`] / [`classify_statements`]) — a
//! deterministic, database-free classifier of real PostgreSQL migration risks
//! (destructive drops, unsafe `NOT NULL`, type narrowing, dangerous renames,
//! blocking indexes).
//!
//! # What this crate does not own
//!
//! It does not open a connection pool (it borrows [`Db`]), it does not
//! reimplement SeaORM's query builder or relation engine, it does not add a
//! second transaction abstraction with hidden savepoints, and it does not
//! introduce any global, thread-local, or task-local state. Raw SeaORM and
//! SQLx remain first-class escape hatches via `db.orm()` / `db.sqlx()`.
//!
//! This crate is an **internal** workspace member (`publish = false`); its
//! public surface is re-exported through the `arcature` facade behind the
//! existing `db` feature. ADR-0006 authorizes no new *public* crate for
//! AP2.1-6 — `arcature-data` is not an independent crates.io release unit.
//!
//! # Raw Axum usage
//!
//! `Db` is `Clone + Send + Sync + 'static` (from `arcature-db`); this crate
//! adds no state of its own. `Query<E>` borrows `&Db` for the duration of the
//! query, so it composes with normal Axum state without a runtime dependency:
//!
//! ```ignore
//! use arcature_data::QueryModel;
//! # async fn show(db: &arcature_db::Db) -> Result<(), arcature_data::DataError> {
//! let posts = post::Entity::query(db)
//! .filter(post::Column::Active.eq(true))
//! .order_by_desc(post::Column::CreatedAt)
//! .all()
//! .await?;
//! # Ok(())
//! # }
//! ```
//!
//! # Security note
//!
//! Every query carries an explicit `&Db`; there is no hidden pool the
//! framework resolves on the caller's behalf. Migration lint output is
//! side-effect-free and never reads environment variables or connects to a
//! database; the N+1 tracker is request-scoped and constructed explicitly.
/// The certified `arcature-db` engine, re-exported so downstream code targets
/// the Arcature-pinned types through this crate. [`Db`] is the explicit
/// ownership handle every API in this crate borrows.
pub use Db;
pub use ;
pub use ;
pub use ;
pub use ;
pub use Transaction;