Skip to main content

backbone_inventory/infrastructure/persistence/
stock_entry_item_repository.rs

1//! Repository for StockEntryItem entities
2//!
3//! Originally generated by metaphor-schema; now **user-owned** — this exact path is declared under
4//! `user_owned` in `metaphor.codegen.yaml`, so the generator skips it wholesale. The custom methods
5//! below hold the hand-written StockEntryItem SQL
6//! (4-layer rule: services orchestrate, repositories hold the SQL).
7//!
8//! Thin newtype over `backbone_orm::GenericCrudRepository<StockEntryItem, backbone_orm::SoftDelete>`.
9//! All standard CRUD methods are available via `Deref`.
10
11use anyhow::Result;
12use rust_decimal::Decimal;
13use sqlx::PgPool;
14use uuid::Uuid;
15
16use crate::domain::entity::StockEntryItem;
17
18/// Table name for StockEntryItem entities
19pub const TABLE_NAME: &str = "inventory.stock_entry_items";
20
21/// Repository for StockEntryItem entities.
22///
23/// All standard CRUD, soft-delete, pagination, and bulk methods are
24/// provided automatically via `Deref` to `backbone_orm::GenericCrudRepository`.
25pub struct StockEntryItemRepository(
26    backbone_orm::GenericCrudRepository<StockEntryItem, backbone_orm::SoftDelete>,
27);
28
29impl std::ops::Deref for StockEntryItemRepository {
30    type Target = backbone_orm::GenericCrudRepository<StockEntryItem, backbone_orm::SoftDelete>;
31    fn deref(&self) -> &Self::Target { &self.0 }
32}
33
34impl StockEntryItemRepository {
35    /// Create a new repository instance.
36    pub fn new(pool: PgPool) -> Self {
37        Self(backbone_orm::GenericCrudRepository::new(pool, TABLE_NAME))
38    }
39}
40
41/// The exact row a transfer line insert writes.
42pub struct NewStockEntryItemRow {
43    pub id: Uuid,
44    pub entry_id: Uuid,
45    pub item_id: Uuid,
46    pub quantity: Decimal,
47}
48
49/// Hand-written StockEntryItem SQL. Lives here per the module's 4-layer rule.
50impl StockEntryItemRepository {
51    /// Insert one transfer line. Takes the CALLER'S connection so it commits with the paired
52    /// out/in movement; the caller has already relayed the ambient org scope onto it — don't
53    /// re-bind here.
54    pub async fn insert_item(
55        &self,
56        conn: &mut sqlx::PgConnection,
57        l: &NewStockEntryItemRow,
58    ) -> Result<(), sqlx::Error> {
59        sqlx::query("INSERT INTO inventory.stock_entry_items (id, entry_id, item_id, quantity) VALUES ($1,$2,$3,$4)")
60            .bind(l.id).bind(l.entry_id).bind(l.item_id).bind(l.quantity)
61            .execute(conn)
62            .await?;
63        Ok(())
64    }
65}
66
67backbone_core::impl_crud_repository!(StockEntryItemRepository, StockEntryItem, soft_delete);