acme_proxy_store/lib.rs
1//! Persistence: one module per table, over `sqlx` and SQLite or PostgreSQL —
2//! acme-proxy's storage layer, below everything that reads or writes a row. An internal
3//! crate of the `acme-proxy` binary, published in lockstep with it and with no
4//! semver promise of its own.
5//!
6//! Queries are built with the runtime `sqlx::query` API rather than the
7//! compile-time macros, so `DATABASE_URL` is not needed to build the crate.
8//! Migrations are embedded and run at startup — see [`db`].
9//!
10//! Two invariants shape almost everything here:
11//!
12//! - **A profile is a data boundary.** `accounts` and `orders` carry a
13//! `profile` column and `accounts` is keyed `UNIQUE(profile, pubkey)`, so one
14//! client key at two endpoints is two unrelated accounts. Request-path
15//! lookups always take the profile; the admin layer uses the deliberately
16//! unscoped `find_any_*` variants.
17//! - **[`audit`] rows outlive their subjects.** That table has no foreign keys,
18//! because a `CASCADE` would delete the evidence along with the account or
19//! order it describes. It is INSERT-only: there is no setter and no `UPDATE`
20//! against it anywhere in the crate.
21//!
22//! Methods return `Result<_, sqlx::Error>` and leave the mapping to a
23//! [`acme_proxy_core::error::Problem`] to their caller.
24
25pub mod account;
26pub mod admin_recovery_code;
27pub mod admin_session;
28pub mod admin_user;
29pub mod audit;
30pub mod authz;
31pub mod crl;
32pub mod db;
33pub mod eab;
34pub mod expiring;
35pub mod http01_token;
36pub mod id;
37pub mod job;
38pub mod nonce;
39pub mod order;
40pub mod query;
41pub mod revocation;
42pub mod sql;
43pub mod status;
44#[cfg(any(test, feature = "test-util"))]
45pub mod testutil;
46pub mod transfer;
47pub mod upstream_order;