@@ -337,50 +337,41 @@ impl Database {
337337 }
338338
339339 pub async fn count_events ( & self , query : & EventQuery ) -> Result < i64 , AppError > {
340- let mut sql = "SELECT COUNT(*) FROM events WHERE 1=1" . to_string ( ) ;
341- let mut bindings: Vec < String > = vec ! [ ] ;
342-
343- if let Some ( event_type) = & query. event_type {
344- sql. push_str ( & format ! ( " AND event_type = ${}" , bindings. len( ) + 1 ) ) ;
345- bindings. push ( event_type. clone ( ) ) ;
340+ let mut b = sqlx:: QueryBuilder :: new ( "SELECT COUNT(*) FROM events WHERE 1=1" ) ;
341+ if let Some ( ref event_type) = query. event_type {
342+ b. push ( " AND event_type = " ) ;
343+ b. push_bind ( event_type) ;
346344 }
347- if let Some ( category) = & query. category {
348- sql . push_str ( & format ! ( " AND category = ${}" , bindings . len ( ) + 1 ) ) ;
349- bindings . push ( category. clone ( ) ) ;
345+ if let Some ( ref category) = query. category {
346+ b . push ( " AND category = " ) ;
347+ b . push_bind ( category) ;
350348 }
351- if let Some ( contract_id) = & query. contract_id {
352- sql . push_str ( & format ! ( " AND contract_id = ${}" , bindings . len ( ) + 1 ) ) ;
353- bindings . push ( contract_id. clone ( ) ) ;
349+ if let Some ( ref contract_id) = query. contract_id {
350+ b . push ( " AND contract_id = " ) ;
351+ b . push_bind ( contract_id) ;
354352 }
355353 if let Some ( trade_id) = query. trade_id {
356- sql . push_str ( & format ! ( " AND data->>'trade_id' = ${}" , bindings . len ( ) + 1 ) ) ;
357- bindings . push ( trade_id. to_string ( ) ) ;
354+ b . push ( " AND data->>'trade_id' = " ) ;
355+ b . push_bind ( trade_id. to_string ( ) ) ;
358356 }
359357 if let Some ( from_ledger) = query. from_ledger {
360- sql . push_str ( & format ! ( " AND ledger >= ${}" , bindings . len ( ) + 1 ) ) ;
361- bindings . push ( from_ledger. to_string ( ) ) ;
358+ b . push ( " AND ledger >= " ) ;
359+ b . push_bind ( from_ledger) ;
362360 }
363361 if let Some ( to_ledger) = query. to_ledger {
364- sql. push_str ( & format ! ( " AND ledger <= ${}" , bindings. len( ) + 1 ) ) ;
365- bindings. push ( to_ledger. to_string ( ) ) ;
366- }
367-
368- let mut q = sqlx:: query ( & sql) ;
369- for b in & bindings {
370- q = q. bind ( b) ;
362+ b. push ( " AND ledger <= " ) ;
363+ b. push_bind ( to_ledger) ;
371364 }
372- // Timestamp filters bound separately (DateTime type)
373365 if let Some ( from_time) = query. from_time {
374- sql . push_str ( & format ! ( " AND timestamp >= ${}" , bindings . len ( ) + 1 ) ) ;
375- q = q . bind ( from_time) ;
366+ b . push ( " AND timestamp >= " ) ;
367+ b . push_bind ( from_time) ;
376368 }
377369 if let Some ( to_time) = query. to_time {
378- sql . push_str ( & format ! ( " AND timestamp <= ${}" , bindings . len ( ) + 1 ) ) ;
379- q = q . bind ( to_time) ;
370+ b . push ( " AND timestamp <= " ) ;
371+ b . push_bind ( to_time) ;
380372 }
381-
382- let row = q. fetch_one ( & self . pool ) . await ?;
383- Ok ( row. get :: < i64 , _ > ( 0 ) )
373+ let total: i64 = b. build_query_scalar ( ) . fetch_one ( & self . pool ) . await ?;
374+ Ok ( total)
384375 }
385376
386377 pub async fn get_events_in_range (
@@ -1230,6 +1221,12 @@ impl Database {
12301221 . bind ( status_code as i16 )
12311222 . bind ( duration_ms as i64 )
12321223 . bind ( is_error)
1224+ . execute ( & self . pool )
1225+ . await ?;
1226+ Ok ( ( ) )
1227+ }
1228+
1229+ // -----------------------------------------------------------------------
12331230 // Integration service
12341231 // -----------------------------------------------------------------------
12351232
@@ -1281,6 +1278,7 @@ impl Database {
12811278 Ok ( ( ) )
12821279 }
12831280
1281+ pub async fn get_integration_deliveries (
12841282 /// Query the hourly APM rollup materialized view for the last `hours` hours.
12851283 pub async fn get_perf_hourly_rollup (
12861284 & self ,
@@ -1566,6 +1564,42 @@ impl Database {
15661564 . bind ( ep. active )
15671565 . bind ( ep. created_at )
15681566 . bind ( ep. failure_count as i32 )
1567+ . execute ( & self . pool )
1568+ . await ?;
1569+ Ok ( ( ) )
1570+ }
1571+
1572+ pub async fn deactivate_webhook_endpoint( & self , id: Uuid ) -> Result <( ) , anyhow:: Error > {
1573+ sqlx:: query ( "UPDATE webhook_endpoints SET active = false WHERE id = $1" )
1574+ . bind ( id)
1575+ . execute ( & self . pool )
1576+ . await ?;
1577+ Ok ( ( ) )
1578+ }
1579+
1580+ pub async fn insert_webhook_delivery(
1581+ & self ,
1582+ record: & crate :: webhook_service:: WebhookDeliveryRecord ,
1583+ ) -> Result <( ) , AppError > {
1584+ sqlx:: query (
1585+ "INSERT INTO webhook_deliveries (id, endpoint_id, event_type, payload, status_code, success, attempt, error, delivered_at, duration_ms) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)"
1586+ )
1587+ . bind ( record. id )
1588+ . bind ( record. endpoint_id )
1589+ . bind ( & record. event_type )
1590+ . bind ( & record. payload )
1591+ . bind ( record. status_code . map ( |c| c as i32 ) )
1592+ . bind ( record. success )
1593+ . bind ( record. attempt as i32 )
1594+ . bind ( & record. error )
1595+ . bind ( record. delivered_at )
1596+ . bind ( record. duration_ms as i64 )
1597+ . execute ( & self . pool )
1598+ . await ?;
1599+ Ok ( ( ) )
1600+ }
1601+ }
1602+
15691603// Compliance Operations
15701604// =============================================================================
15711605
@@ -1668,34 +1702,6 @@ impl Database {
16681702 Ok ( ( ) )
16691703 }
16701704
1671- pub async fn deactivate_webhook_endpoint ( & self , id : Uuid ) -> Result < ( ) , anyhow:: Error > {
1672- sqlx:: query ( "UPDATE webhook_endpoints SET active = false WHERE id = $1" )
1673- . bind ( id)
1674- . execute ( & self . pool )
1675- . await ?;
1676- Ok ( ( ) )
1677- }
1678-
1679- pub async fn insert_webhook_delivery (
1680- & self ,
1681- record : & crate :: webhook_service:: WebhookDeliveryRecord ,
1682- ) -> Result < ( ) , AppError > {
1683- sqlx:: query (
1684- "INSERT INTO webhook_deliveries (id, endpoint_id, event_type, payload, status_code, success, attempt, error, delivered_at, duration_ms) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)"
1685- )
1686- . bind ( record. id )
1687- . bind ( record. endpoint_id )
1688- . bind ( & record. event_type )
1689- . bind ( & record. payload )
1690- . bind ( record. status_code . map ( |c| c as i32 ) )
1691- . bind ( record. success )
1692- . bind ( record. attempt as i32 )
1693- . bind ( & record. error )
1694- . bind ( record. delivered_at )
1695- . bind ( record. duration_ms as i64 )
1696- . execute ( & self . pool )
1697- . await ?;
1698- Ok ( ( ) )
16991705 fn row_to_compliance_check(
17001706 & self ,
17011707 row: & sqlx:: postgres:: PgRow ,
0 commit comments