backbone_catalog/infrastructure/persistence/
attribute_value_repository.rs1use sqlx::PgPool;
16use uuid::Uuid;
17
18use crate::domain::entity::AttributeValue;
19
20pub const TABLE_NAME: &str = "catalog.attribute_values";
22
23pub struct AttributeValueRepository(
28 backbone_orm::GenericCrudRepository<AttributeValue, backbone_orm::SoftDelete>,
29);
30
31impl std::ops::Deref for AttributeValueRepository {
32 type Target = backbone_orm::GenericCrudRepository<AttributeValue, backbone_orm::SoftDelete>;
33 fn deref(&self) -> &Self::Target { &self.0 }
34}
35
36impl AttributeValueRepository {
37 pub fn new(pool: PgPool) -> Self {
39 Self(backbone_orm::GenericCrudRepository::new(pool, TABLE_NAME))
40 }
41}
42
43pub struct NewAttributeValueRow<'a> {
45 pub id: Uuid,
46 pub attribute_id: Uuid,
47 pub code: &'a str,
48 pub label: &'a str,
49 pub label_en: Option<&'a str>,
50 pub swatch_hex: Option<&'a str>,
51 pub sort_order: i32,
52}
53
54#[derive(Debug, Clone)]
58pub struct AttributeValueResolveRow {
59 pub id: Uuid,
60 pub label: String,
61}
62
63impl AttributeValueRepository {
65 pub async fn find_value_with_attribute(
70 &self,
71 executor: impl sqlx::Executor<'_, Database = sqlx::Postgres>,
72 attr_code: &str,
73 val_code: &str,
74 ) -> Result<Option<AttributeValueResolveRow>, sqlx::Error> {
75 let row: Option<(Uuid, String)> = sqlx::query_as(
76 r#"SELECT av.id, av.label
77 FROM catalog.attribute_values av
78 JOIN catalog.attributes a ON a.id = av.attribute_id
79 WHERE a.code = $1 AND av.code = $2
80 AND (a.metadata->>'deleted_at') IS NULL
81 AND (av.metadata->>'deleted_at') IS NULL"#,
82 )
83 .bind(attr_code)
84 .bind(val_code)
85 .fetch_optional(executor)
86 .await?;
87 Ok(row.map(|(id, label)| AttributeValueResolveRow { id, label }))
88 }
89
90 pub async fn insert_attribute_value(
93 &self,
94 executor: impl sqlx::Executor<'_, Database = sqlx::Postgres>,
95 r: &NewAttributeValueRow<'_>,
96 ) -> Result<(), sqlx::Error> {
97 sqlx::query(
98 r#"INSERT INTO catalog.attribute_values
99 (id, attribute_id, code, label, label_en, swatch_hex, sort_order, status)
100 VALUES ($1,$2,$3,$4,$5,$6,$7,'active'::catalog_status)"#,
101 )
102 .bind(r.id)
103 .bind(r.attribute_id)
104 .bind(r.code)
105 .bind(r.label)
106 .bind(r.label_en)
107 .bind(r.swatch_hex)
108 .bind(r.sort_order)
109 .execute(executor)
110 .await?;
111 Ok(())
112 }
113}
114
115backbone_core::impl_crud_repository!(AttributeValueRepository, AttributeValue, soft_delete);