Expand description
GenericCrudRepository<T, DeleteMode> — one implementation for all entities.
The generated repository file previously duplicated ~20 identical method bodies for every entity. This module provides those implementations once so that the generator can emit a thin newtype wrapper instead of hundreds of lines of copy-paste.
§Delete mode markers
| Marker | Behaviour |
|---|---|
SoftDelete | deleted_at stored in metadata JSONB; active rows filter IS NULL |
HardDelete | Rows are permanently deleted; no trash concept |
§Generated output (after this change)
ⓘ
// ~20 lines total instead of ~460-560
pub struct UserRepository(
backbone_orm::GenericCrudRepository<User, backbone_orm::SoftDelete>
);
impl std::ops::Deref for UserRepository {
type Target = backbone_orm::GenericCrudRepository<User, backbone_orm::SoftDelete>;
fn deref(&self) -> &Self::Target { &self.0 }
}
impl UserRepository {
pub fn new(pool: sqlx::PgPool) -> Self {
Self(backbone_orm::GenericCrudRepository::new(pool, "users"))
}
// entity-specific methods only:
pub async fn find_by_email(&self, email: &str) -> anyhow::Result<Option<User>> { … }
pub async fn partial_update(…) { … }
pub async fn list_paginated_filtered(…) { … }
}
backbone_core::impl_crud_repository!(UserRepository, User, soft_delete);Structs§
- Generic
Crud Repository - Generic PostgreSQL CRUD repository parameterised by entity type
Tand delete strategyD(SoftDeleteorHardDelete). - Hard
Delete - Marker: entity uses hard deletes only — no soft delete / trash concept.
- Missing
Company Scope - The caller could not be scoped to a company for an entity that requires one.
- Soft
Delete - Marker: entity uses JSONB-based soft delete (
metadata->>'deleted_at').
Traits§
- Entity
Repo Meta - Metadata trait that entities implement so
GenericCrudRepositorycan providelist_paginated_filteredandlist_deleted_filteredwithout per-entity boilerplate.
Functions§
- and_
conditions - AND two optional SQL conditions into the single
__base_conditionslot. - company_
fence - Build the SQL fence for
T, or fail closed. - fetch_
by_ ids_ as_ json - Fetch rows from an arbitrary table by id list, as JSON — hydrates
?include=relations in the generic CRUD handler without a typed repository for the target entity.tableis a generator-emitted collection name (fromEntityRepoMeta::relations()), NEVER client input, so the interpolation is not an injection vector.caller_tableis the hydrated entity’s own (schema-qualified) table name, used to qualify a baretable— seequalify_relation_table. One batchedWHERE id = ANY(...)per relation. Returnsrow_to_jsonobjects keyed by raw (snake_case) column names. - qualify_
relation_ table - Qualify a relation target table with the calling entity’s schema.
- strip_
client_ company_ filters - Remove any caller-supplied filter on the company column.