1use std::sync::Arc;
2
3use crate::db::{ConnExt, CursorPage, CursorRequest, Database, ValidatedFilter};
4use crate::error::Result;
5
6use super::record::AuditRecord;
7
8const COLS: &str = "id, actor, action, resource_type, resource_id, metadata, \
9 ip, user_agent, fingerprint, tenant_id, created_at";
10
11#[derive(Clone)]
17pub struct AuditRepo {
18 inner: Arc<AuditRepoInner>,
19}
20
21struct AuditRepoInner {
22 db: Database,
23}
24
25impl AuditRepo {
26 pub fn new(db: Database) -> Self {
28 Self {
29 inner: Arc::new(AuditRepoInner { db }),
30 }
31 }
32
33 pub async fn list(&self, req: CursorRequest) -> Result<CursorPage<AuditRecord>> {
39 self.inner
40 .db
41 .conn()
42 .select(&format!("SELECT {COLS} FROM audit_log"))
43 .cursor::<AuditRecord>(req)
44 .await
45 }
46
47 pub async fn query(
53 &self,
54 filter: ValidatedFilter,
55 req: CursorRequest,
56 ) -> Result<CursorPage<AuditRecord>> {
57 self.inner
58 .db
59 .conn()
60 .select(&format!("SELECT {COLS} FROM audit_log"))
61 .filter(filter)
62 .cursor::<AuditRecord>(req)
63 .await
64 }
65}