1- use landscape_common:: cert:: order:: CertConfig ;
2- use sea_orm:: DatabaseConnection ;
1+ use std:: collections:: HashSet ;
2+
3+ use landscape_common:: cert:: account:: AccountStatus ;
4+ use landscape_common:: cert:: order:: { CertConfig , CertStatus , CertType } ;
5+ use landscape_common:: error:: LdError ;
6+ use sea_orm:: {
7+ ActiveModelTrait , DatabaseConnection , EntityTrait , TransactionError , TransactionTrait ,
8+ } ;
39
410use super :: entity:: { CertActiveModel , CertEntity , CertModel } ;
511use crate :: DBId ;
@@ -9,10 +15,84 @@ pub struct CertRepository {
915 db : DatabaseConnection ,
1016}
1117
18+ pub struct SyncAccountHintTxResult {
19+ pub changed_cert_ids : Vec < DBId > ,
20+ pub cancelled_cert_ids : Vec < DBId > ,
21+ }
22+
1223impl CertRepository {
1324 pub fn new ( db : DatabaseConnection ) -> Self {
1425 Self { db }
1526 }
27+
28+ pub async fn sync_account_status_hint_tx (
29+ & self ,
30+ account_id : DBId ,
31+ account_status : & AccountStatus ,
32+ hint_prefix : & str ,
33+ ) -> Result < SyncAccountHintTxResult , LdError > {
34+ let account_is_registered = matches ! ( account_status, AccountStatus :: Registered ) ;
35+ let hint = format ! ( "{hint_prefix} {:?}" , account_status) ;
36+ let hint_prefix = hint_prefix. to_string ( ) ;
37+ let hint_opt = if account_is_registered { None } else { Some ( hint) } ;
38+
39+ self . db
40+ . transaction :: < _ , SyncAccountHintTxResult , LdError > ( |txn| {
41+ let hint_prefix = hint_prefix. clone ( ) ;
42+ let hint_opt = hint_opt. clone ( ) ;
43+ Box :: pin ( async move {
44+ let cert_models = CertEntity :: find ( ) . all ( txn) . await ?;
45+ let mut changed_cert_ids = Vec :: new ( ) ;
46+ let mut cancelled_cert_ids = HashSet :: new ( ) ;
47+
48+ for cert_model in cert_models {
49+ let mut cert: CertConfig = cert_model. clone ( ) . into ( ) ;
50+ let CertType :: Acme ( acme) = & cert. cert_type else {
51+ continue ;
52+ } ;
53+ if acme. account_id != account_id {
54+ continue ;
55+ }
56+
57+ let mut changed = false ;
58+ if let Some ( hint) = & hint_opt {
59+ if matches ! ( cert. status, CertStatus :: Processing ) {
60+ cert. status = CertStatus :: Cancelled ;
61+ cancelled_cert_ids. insert ( cert. id ) ;
62+ changed = true ;
63+ }
64+ if cert. status_message . as_deref ( ) != Some ( hint. as_str ( ) ) {
65+ cert. status_message = Some ( hint. clone ( ) ) ;
66+ changed = true ;
67+ }
68+ } else if cert
69+ . status_message
70+ . as_deref ( )
71+ . is_some_and ( |m| m. starts_with ( & hint_prefix) )
72+ {
73+ cert. status_message = None ;
74+ changed = true ;
75+ }
76+
77+ if changed {
78+ let active: CertActiveModel = cert. into ( ) ;
79+ active. update ( txn) . await ?;
80+ changed_cert_ids. push ( cert_model. id ) ;
81+ }
82+ }
83+
84+ Ok ( SyncAccountHintTxResult {
85+ changed_cert_ids,
86+ cancelled_cert_ids : cancelled_cert_ids. into_iter ( ) . collect ( ) ,
87+ } )
88+ } )
89+ } )
90+ . await
91+ . map_err ( |e| match e {
92+ TransactionError :: Connection ( db_err) => LdError :: DatabaseError ( db_err) ,
93+ TransactionError :: Transaction ( ld_err) => ld_err,
94+ } )
95+ }
1696}
1797
1898crate :: impl_repository!( CertRepository , CertModel , CertEntity , CertActiveModel , CertConfig , DBId ) ;
0 commit comments