Skip to main content

datasynth_core/models/
internal_control.rs

1//! Internal Controls System (ICS) definitions for SOX compliance.
2//!
3//! Provides structures for modeling internal controls, control testing,
4//! and SOX 404 compliance markers in synthetic accounting data.
5
6use chrono::NaiveDate;
7use serde::{Deserialize, Serialize};
8use std::collections::HashMap;
9
10use super::coso::{ControlScope, CosoComponent, CosoMaturityLevel, CosoPrinciple};
11use super::graph_properties::{GraphPropertyValue, ToNodeProperties};
12use super::user::UserPersona;
13
14/// Control type based on SOX 404 framework.
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
16#[serde(rename_all = "snake_case")]
17pub enum ControlType {
18    /// Prevents errors/fraud before they occur
19    Preventive,
20    /// Detects errors/fraud after they occur
21    Detective,
22    /// Continuous monitoring and analytics
23    Monitoring,
24}
25
26impl std::fmt::Display for ControlType {
27    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28        match self {
29            Self::Preventive => write!(f, "Preventive"),
30            Self::Detective => write!(f, "Detective"),
31            Self::Monitoring => write!(f, "Monitoring"),
32        }
33    }
34}
35
36/// Control testing frequency.
37#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
38#[serde(rename_all = "snake_case")]
39pub enum ControlFrequency {
40    /// Applied to every transaction
41    Transactional,
42    /// Performed daily
43    Daily,
44    /// Performed weekly
45    Weekly,
46    /// Performed monthly
47    Monthly,
48    /// Performed quarterly
49    Quarterly,
50    /// Performed annually
51    Annual,
52}
53
54impl std::fmt::Display for ControlFrequency {
55    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56        match self {
57            Self::Transactional => write!(f, "Transactional"),
58            Self::Daily => write!(f, "Daily"),
59            Self::Weekly => write!(f, "Weekly"),
60            Self::Monthly => write!(f, "Monthly"),
61            Self::Quarterly => write!(f, "Quarterly"),
62            Self::Annual => write!(f, "Annual"),
63        }
64    }
65}
66
67/// Risk level for controls and control deficiencies.
68#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
69#[serde(rename_all = "snake_case")]
70pub enum RiskLevel {
71    /// Low risk - minor impact
72    Low,
73    /// Medium risk - moderate impact
74    Medium,
75    /// High risk - significant impact
76    High,
77    /// Critical risk - material impact on financial statements
78    Critical,
79}
80
81impl std::fmt::Display for RiskLevel {
82    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83        match self {
84            Self::Low => write!(f, "Low"),
85            Self::Medium => write!(f, "Medium"),
86            Self::High => write!(f, "High"),
87            Self::Critical => write!(f, "Critical"),
88        }
89    }
90}
91
92/// SOX 404 financial statement assertions.
93#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
94#[serde(rename_all = "snake_case")]
95pub enum SoxAssertion {
96    /// Transactions and events have been recorded
97    Existence,
98    /// All transactions have been recorded
99    Completeness,
100    /// Amounts are recorded at appropriate values
101    Valuation,
102    /// Entity has rights to assets and obligations for liabilities
103    RightsAndObligations,
104    /// Components are properly classified and disclosed
105    PresentationAndDisclosure,
106}
107
108impl ToNodeProperties for SoxAssertion {
109    fn node_type_name(&self) -> &'static str {
110        "sox_assertion"
111    }
112    fn node_type_code(&self) -> u16 {
113        502
114    }
115    fn to_node_properties(&self) -> HashMap<String, GraphPropertyValue> {
116        let mut p = HashMap::new();
117        p.insert("name".into(), GraphPropertyValue::String(self.to_string()));
118        p.insert(
119            "code".into(),
120            GraphPropertyValue::String(format!("{self:?}")),
121        );
122        p
123    }
124}
125
126impl std::fmt::Display for SoxAssertion {
127    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
128        match self {
129            Self::Existence => write!(f, "Existence"),
130            Self::Completeness => write!(f, "Completeness"),
131            Self::Valuation => write!(f, "Valuation"),
132            Self::RightsAndObligations => write!(f, "RightsAndObligations"),
133            Self::PresentationAndDisclosure => write!(f, "PresentationAndDisclosure"),
134        }
135    }
136}
137
138/// Result of control testing.
139#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
140#[serde(rename_all = "snake_case")]
141pub enum TestResult {
142    /// Control test passed — no exceptions found
143    Pass,
144    /// Control test partially passed — minor exceptions
145    Partial,
146    /// Control test failed — material exception
147    Fail,
148    /// Control has not been tested
149    #[default]
150    NotTested,
151}
152
153impl std::fmt::Display for TestResult {
154    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
155        match self {
156            Self::Pass => write!(f, "Pass"),
157            Self::Partial => write!(f, "Partial"),
158            Self::Fail => write!(f, "Fail"),
159            Self::NotTested => write!(f, "NotTested"),
160        }
161    }
162}
163
164/// Derived control effectiveness rating.
165#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
166#[serde(rename_all = "snake_case")]
167pub enum ControlEffectiveness {
168    /// Control is operating effectively
169    Effective,
170    /// Control is partially effective — some deficiencies
171    PartiallyEffective,
172    /// Control has not been tested for effectiveness
173    #[default]
174    NotTested,
175    /// Control is not effective — material weakness or significant deficiency
176    Ineffective,
177}
178
179impl std::fmt::Display for ControlEffectiveness {
180    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
181        match self {
182            Self::Effective => write!(f, "Effective"),
183            Self::PartiallyEffective => write!(f, "PartiallyEffective"),
184            Self::NotTested => write!(f, "NotTested"),
185            Self::Ineffective => write!(f, "Ineffective"),
186        }
187    }
188}
189
190/// Control status for transaction-level tracking.
191#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
192#[serde(rename_all = "snake_case")]
193pub enum ControlStatus {
194    /// Control operating effectively
195    #[default]
196    Effective,
197    /// Control exception/deficiency found
198    Exception,
199    /// Control not yet tested
200    NotTested,
201    /// Exception has been remediated
202    Remediated,
203}
204
205impl std::fmt::Display for ControlStatus {
206    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
207        match self {
208            Self::Effective => write!(f, "Effective"),
209            Self::Exception => write!(f, "Exception"),
210            Self::NotTested => write!(f, "NotTested"),
211            Self::Remediated => write!(f, "Remediated"),
212        }
213    }
214}
215
216/// Internal control definition.
217#[derive(Debug, Clone, Serialize, Deserialize)]
218pub struct InternalControl {
219    /// Unique control identifier (e.g., "C001", "C010")
220    pub control_id: String,
221    /// Control name/title
222    pub control_name: String,
223    /// Type of control (Preventive, Detective, Monitoring)
224    pub control_type: ControlType,
225    /// Control objective description
226    pub objective: String,
227    /// How often the control is performed
228    pub frequency: ControlFrequency,
229    /// Role responsible for executing/owning the control
230    pub owner_role: UserPersona,
231    /// Risk level associated with control failure
232    pub risk_level: RiskLevel,
233    /// Detailed description of the control procedure
234    pub description: String,
235    /// Whether this is a SOX 404 key control
236    pub is_key_control: bool,
237    /// SOX assertion this control addresses
238    pub sox_assertion: SoxAssertion,
239    /// COSO 2013 component this control maps to
240    pub coso_component: CosoComponent,
241    /// COSO 2013 principles this control addresses
242    pub coso_principles: Vec<CosoPrinciple>,
243    /// Control scope (entity-level vs transaction-level)
244    pub control_scope: ControlScope,
245    /// Control maturity level
246    pub maturity_level: CosoMaturityLevel,
247
248    // --- New fields for test history, effectiveness, owner resolution, risk linkage ---
249    /// Employee ID of the control owner (resolved from owner_role at generation time)
250    pub owner_employee_id: Option<String>,
251    /// Display name of the control owner
252    pub owner_name: String,
253
254    /// Number of times this control has been tested
255    pub test_count: u32,
256    /// Date of the most recent test
257    pub last_tested_date: Option<NaiveDate>,
258    /// Result of the most recent test
259    pub test_result: TestResult,
260
261    /// Derived effectiveness rating (from maturity_level + test_result)
262    pub effectiveness: ControlEffectiveness,
263
264    /// IDs of risks this control mitigates (populated at generation time)
265    pub mitigates_risk_ids: Vec<String>,
266    /// Account classes this control covers (derived from sox_assertion)
267    pub covers_account_classes: Vec<String>,
268}
269
270impl InternalControl {
271    /// Create a new internal control.
272    pub fn new(
273        control_id: impl Into<String>,
274        control_name: impl Into<String>,
275        control_type: ControlType,
276        objective: impl Into<String>,
277    ) -> Self {
278        Self {
279            control_id: control_id.into(),
280            control_name: control_name.into(),
281            control_type,
282            objective: objective.into(),
283            frequency: ControlFrequency::Transactional,
284            owner_role: UserPersona::Controller,
285            risk_level: RiskLevel::Medium,
286            description: String::new(),
287            is_key_control: false,
288            sox_assertion: SoxAssertion::Existence,
289            coso_component: CosoComponent::ControlActivities,
290            coso_principles: vec![CosoPrinciple::ControlActions],
291            control_scope: ControlScope::TransactionLevel,
292            maturity_level: CosoMaturityLevel::Defined,
293            owner_employee_id: None,
294            owner_name: String::new(),
295            test_count: 0,
296            last_tested_date: None,
297            test_result: TestResult::NotTested,
298            effectiveness: ControlEffectiveness::NotTested,
299            mitigates_risk_ids: Vec::new(),
300            covers_account_classes: Vec::new(),
301        }
302    }
303
304    /// Builder method to set frequency.
305    pub fn with_frequency(mut self, frequency: ControlFrequency) -> Self {
306        self.frequency = frequency;
307        self
308    }
309
310    /// Builder method to set owner role.
311    pub fn with_owner(mut self, owner: UserPersona) -> Self {
312        self.owner_role = owner;
313        self
314    }
315
316    /// Builder method to set risk level.
317    pub fn with_risk_level(mut self, level: RiskLevel) -> Self {
318        self.risk_level = level;
319        self
320    }
321
322    /// Builder method to set description.
323    pub fn with_description(mut self, description: impl Into<String>) -> Self {
324        self.description = description.into();
325        self
326    }
327
328    /// Builder method to mark as key control.
329    pub fn as_key_control(mut self) -> Self {
330        self.is_key_control = true;
331        self
332    }
333
334    /// Builder method to set SOX assertion.
335    pub fn with_assertion(mut self, assertion: SoxAssertion) -> Self {
336        self.sox_assertion = assertion;
337        self
338    }
339
340    /// Builder method to set COSO component.
341    pub fn with_coso_component(mut self, component: CosoComponent) -> Self {
342        self.coso_component = component;
343        self
344    }
345
346    /// Builder method to set COSO principles.
347    pub fn with_coso_principles(mut self, principles: Vec<CosoPrinciple>) -> Self {
348        self.coso_principles = principles;
349        self
350    }
351
352    /// Builder method to set control scope.
353    pub fn with_control_scope(mut self, scope: ControlScope) -> Self {
354        self.control_scope = scope;
355        self
356    }
357
358    /// Builder method to set maturity level.
359    pub fn with_maturity_level(mut self, level: CosoMaturityLevel) -> Self {
360        self.maturity_level = level;
361        self
362    }
363
364    /// Builder method to set owner employee ID and name.
365    pub fn with_owner_employee(
366        mut self,
367        employee_id: impl Into<String>,
368        name: impl Into<String>,
369    ) -> Self {
370        self.owner_employee_id = Some(employee_id.into());
371        self.owner_name = name.into();
372        self
373    }
374
375    /// Builder method to set test history.
376    pub fn with_test_history(
377        mut self,
378        test_count: u32,
379        last_tested_date: Option<NaiveDate>,
380        test_result: TestResult,
381    ) -> Self {
382        self.test_count = test_count;
383        self.last_tested_date = last_tested_date;
384        self.test_result = test_result;
385        self
386    }
387
388    /// Builder method to set effectiveness.
389    pub fn with_effectiveness(mut self, effectiveness: ControlEffectiveness) -> Self {
390        self.effectiveness = effectiveness;
391        self
392    }
393
394    /// Builder method to set mitigated risk IDs.
395    pub fn with_mitigates_risk_ids(mut self, risk_ids: Vec<String>) -> Self {
396        self.mitigates_risk_ids = risk_ids;
397        self
398    }
399
400    /// Builder method to set covered account classes.
401    pub fn with_covers_account_classes(mut self, classes: Vec<String>) -> Self {
402        self.covers_account_classes = classes;
403        self
404    }
405
406    /// Derive test history and effectiveness from the current `maturity_level`.
407    ///
408    /// Call this after setting `maturity_level` to populate `test_count`,
409    /// `last_tested_date`, `test_result`, and `effectiveness`.
410    ///
411    /// - Maturity >= 4 (Managed/Optimized): tested multiple times, Pass, Effective
412    /// - Maturity == 3 (Defined): tested once, Partial, PartiallyEffective
413    /// - Maturity <= 2 (NonExistent/AdHoc/Repeatable): not tested
414    ///
415    /// `assessed_date` is the reference date from which `last_tested_date` is
416    /// back-computed: `assessed_date - 30 * (5 - maturity_level)` days.
417    pub fn derive_from_maturity(&mut self, assessed_date: NaiveDate) {
418        let level = self.maturity_level.level();
419
420        if level >= 4 {
421            // Managed (4) or Optimized (5)
422            self.test_count = (level as u32).saturating_sub(2); // 2 or 3
423            let days_back = 30_i64 * (5 - level as i64);
424            self.last_tested_date =
425                assessed_date.checked_sub_signed(chrono::Duration::days(days_back));
426            self.test_result = TestResult::Pass;
427            self.effectiveness = ControlEffectiveness::Effective;
428        } else if level == 3 {
429            // Defined
430            self.test_count = 1;
431            let days_back = 30_i64 * (5 - 3);
432            self.last_tested_date =
433                assessed_date.checked_sub_signed(chrono::Duration::days(days_back));
434            self.test_result = TestResult::Partial;
435            self.effectiveness = ControlEffectiveness::PartiallyEffective;
436        } else {
437            // NonExistent (0), AdHoc (1), Repeatable (2)
438            self.test_count = 0;
439            self.last_tested_date = None;
440            self.test_result = TestResult::NotTested;
441            self.effectiveness = ControlEffectiveness::NotTested;
442        }
443    }
444
445    /// Derive `covers_account_classes` from `sox_assertion`.
446    ///
447    /// Maps SOX assertions to the account classes they cover:
448    /// - Existence -> Assets
449    /// - Completeness -> Revenue, Liabilities
450    /// - Valuation -> Assets, Liabilities, Equity, Revenue, Expenses
451    /// - RightsAndObligations -> Assets, Liabilities
452    /// - PresentationAndDisclosure -> Revenue, Equity
453    pub fn derive_account_classes(&mut self) {
454        self.covers_account_classes = match self.sox_assertion {
455            SoxAssertion::Existence => vec!["Assets".into()],
456            SoxAssertion::Completeness => vec!["Revenue".into(), "Liabilities".into()],
457            SoxAssertion::Valuation => vec![
458                "Assets".into(),
459                "Liabilities".into(),
460                "Equity".into(),
461                "Revenue".into(),
462                "Expenses".into(),
463            ],
464            SoxAssertion::RightsAndObligations => vec!["Assets".into(), "Liabilities".into()],
465            SoxAssertion::PresentationAndDisclosure => vec!["Revenue".into(), "Equity".into()],
466        };
467    }
468
469    /// Generate standard controls for a typical organization.
470    ///
471    /// Includes both transaction-level controls (C001-C060) and
472    /// entity-level controls (C070-C081) with full COSO 2013 mappings.
473    pub fn standard_controls() -> Vec<Self> {
474        vec![
475            // ========================================
476            // TRANSACTION-LEVEL CONTROLS (C001-C060)
477            // ========================================
478
479            // Cash controls
480            Self::new(
481                "C001",
482                "Cash Account Daily Review",
483                ControlType::Detective,
484                "Review all cash transactions daily for unauthorized activity",
485            )
486            .with_frequency(ControlFrequency::Daily)
487            .with_owner(UserPersona::Controller)
488            .with_risk_level(RiskLevel::High)
489            .as_key_control()
490            .with_assertion(SoxAssertion::Existence)
491            .with_description(
492                "Daily reconciliation of cash accounts with bank statements and review of unusual transactions",
493            )
494            .with_coso_component(CosoComponent::ControlActivities)
495            .with_coso_principles(vec![
496                CosoPrinciple::ControlActions,
497                CosoPrinciple::OngoingMonitoring,
498            ])
499            .with_control_scope(ControlScope::TransactionLevel)
500            .with_maturity_level(CosoMaturityLevel::Managed),
501
502            // Large transaction approval
503            Self::new(
504                "C002",
505                "Large Transaction Multi-Level Approval",
506                ControlType::Preventive,
507                "Transactions over $10,000 require additional approval levels",
508            )
509            .with_frequency(ControlFrequency::Transactional)
510            .with_owner(UserPersona::Manager)
511            .with_risk_level(RiskLevel::High)
512            .as_key_control()
513            .with_assertion(SoxAssertion::Valuation)
514            .with_description(
515                "Multi-level approval workflow for transactions exceeding defined thresholds",
516            )
517            .with_coso_component(CosoComponent::ControlActivities)
518            .with_coso_principles(vec![
519                CosoPrinciple::ControlActions,
520                CosoPrinciple::PoliciesAndProcedures,
521            ])
522            .with_control_scope(ControlScope::TransactionLevel)
523            .with_maturity_level(CosoMaturityLevel::Defined),
524
525            // P2P Three-Way Match
526            Self::new(
527                "C010",
528                "Three-Way Match",
529                ControlType::Preventive,
530                "Match purchase order, receipt, and invoice before payment",
531            )
532            .with_frequency(ControlFrequency::Transactional)
533            .with_owner(UserPersona::SeniorAccountant)
534            .with_risk_level(RiskLevel::Medium)
535            .as_key_control()
536            .with_assertion(SoxAssertion::Completeness)
537            .with_description(
538                "Automated matching of PO, goods receipt, and vendor invoice prior to payment release",
539            )
540            .with_coso_component(CosoComponent::ControlActivities)
541            .with_coso_principles(vec![
542                CosoPrinciple::ControlActions,
543                CosoPrinciple::TechnologyControls,
544            ])
545            .with_control_scope(ControlScope::ItApplicationControl)
546            .with_maturity_level(CosoMaturityLevel::Managed),
547
548            // Vendor Master Maintenance
549            Self::new(
550                "C011",
551                "Vendor Master Data Maintenance",
552                ControlType::Preventive,
553                "Segregated access for vendor master data changes",
554            )
555            .with_frequency(ControlFrequency::Transactional)
556            .with_owner(UserPersona::SeniorAccountant)
557            .with_risk_level(RiskLevel::High)
558            .as_key_control()
559            .with_assertion(SoxAssertion::Existence)
560            .with_description(
561                "Restricted access to vendor master data with dual-approval for bank account changes",
562            )
563            .with_coso_component(CosoComponent::ControlActivities)
564            .with_coso_principles(vec![
565                CosoPrinciple::ControlActions,
566                CosoPrinciple::FraudRisk,
567            ])
568            .with_control_scope(ControlScope::TransactionLevel)
569            .with_maturity_level(CosoMaturityLevel::Defined),
570
571            // O2C Revenue Recognition
572            Self::new(
573                "C020",
574                "Revenue Recognition Review",
575                ControlType::Detective,
576                "Review revenue entries for proper timing and classification",
577            )
578            .with_frequency(ControlFrequency::Monthly)
579            .with_owner(UserPersona::Controller)
580            .with_risk_level(RiskLevel::Critical)
581            .as_key_control()
582            .with_assertion(SoxAssertion::Valuation)
583            .with_description(
584                "Monthly review of revenue recognition to ensure compliance with ASC 606",
585            )
586            .with_coso_component(CosoComponent::ControlActivities)
587            .with_coso_principles(vec![
588                CosoPrinciple::ControlActions,
589                CosoPrinciple::ClearObjectives,
590            ])
591            .with_control_scope(ControlScope::TransactionLevel)
592            .with_maturity_level(CosoMaturityLevel::Managed),
593
594            // Credit Limit Enforcement
595            Self::new(
596                "C021",
597                "Customer Credit Limit Check",
598                ControlType::Preventive,
599                "Automatic credit limit check before order acceptance",
600            )
601            .with_frequency(ControlFrequency::Transactional)
602            .with_owner(UserPersona::AutomatedSystem)
603            .with_risk_level(RiskLevel::Medium)
604            .with_assertion(SoxAssertion::Valuation)
605            .with_description(
606                "System-enforced credit limit validation at order entry",
607            )
608            .with_coso_component(CosoComponent::ControlActivities)
609            .with_coso_principles(vec![
610                CosoPrinciple::TechnologyControls,
611                CosoPrinciple::ControlActions,
612            ])
613            .with_control_scope(ControlScope::ItApplicationControl)
614            .with_maturity_level(CosoMaturityLevel::Optimized),
615
616            // GL Account Reconciliation
617            Self::new(
618                "C030",
619                "GL Account Reconciliation",
620                ControlType::Detective,
621                "Monthly reconciliation of all balance sheet accounts",
622            )
623            .with_frequency(ControlFrequency::Monthly)
624            .with_owner(UserPersona::SeniorAccountant)
625            .with_risk_level(RiskLevel::High)
626            .as_key_control()
627            .with_assertion(SoxAssertion::Completeness)
628            .with_description(
629                "Complete reconciliation of all balance sheet accounts with supporting documentation",
630            )
631            .with_coso_component(CosoComponent::MonitoringActivities)
632            .with_coso_principles(vec![CosoPrinciple::OngoingMonitoring])
633            .with_control_scope(ControlScope::TransactionLevel)
634            .with_maturity_level(CosoMaturityLevel::Managed),
635
636            // Journal Entry Review
637            Self::new(
638                "C031",
639                "Manual Journal Entry Review",
640                ControlType::Detective,
641                "Review of all manual journal entries over threshold",
642            )
643            .with_frequency(ControlFrequency::Daily)
644            .with_owner(UserPersona::Controller)
645            .with_risk_level(RiskLevel::High)
646            .as_key_control()
647            .with_assertion(SoxAssertion::Existence)
648            .with_description(
649                "Daily review of manual journal entries with supporting documentation",
650            )
651            .with_coso_component(CosoComponent::ControlActivities)
652            .with_coso_principles(vec![
653                CosoPrinciple::ControlActions,
654                CosoPrinciple::FraudRisk,
655            ])
656            .with_control_scope(ControlScope::TransactionLevel)
657            .with_maturity_level(CosoMaturityLevel::Managed),
658
659            // Period Close Review
660            Self::new(
661                "C032",
662                "Period Close Checklist",
663                ControlType::Detective,
664                "Comprehensive checklist for period-end close procedures",
665            )
666            .with_frequency(ControlFrequency::Monthly)
667            .with_owner(UserPersona::Controller)
668            .with_risk_level(RiskLevel::Medium)
669            .with_assertion(SoxAssertion::Completeness)
670            .with_description(
671                "Standardized period-end close checklist ensuring all procedures completed",
672            )
673            .with_coso_component(CosoComponent::ControlActivities)
674            .with_coso_principles(vec![
675                CosoPrinciple::PoliciesAndProcedures,
676                CosoPrinciple::ControlActions,
677            ])
678            .with_control_scope(ControlScope::TransactionLevel)
679            .with_maturity_level(CosoMaturityLevel::Defined),
680
681            // Payroll Processing
682            Self::new(
683                "C040",
684                "Payroll Processing Review",
685                ControlType::Detective,
686                "Review of payroll processing for accuracy",
687            )
688            .with_frequency(ControlFrequency::Monthly)
689            .with_owner(UserPersona::Controller)
690            .with_risk_level(RiskLevel::High)
691            .as_key_control()
692            .with_assertion(SoxAssertion::Valuation)
693            .with_description(
694                "Monthly review of payroll journals and reconciliation to HR records",
695            )
696            .with_coso_component(CosoComponent::ControlActivities)
697            .with_coso_principles(vec![
698                CosoPrinciple::ControlActions,
699                CosoPrinciple::FraudRisk,
700            ])
701            .with_control_scope(ControlScope::TransactionLevel)
702            .with_maturity_level(CosoMaturityLevel::Managed),
703
704            // Fixed Asset Additions
705            Self::new(
706                "C050",
707                "Fixed Asset Addition Approval",
708                ControlType::Preventive,
709                "Multi-level approval for capital expenditures",
710            )
711            .with_frequency(ControlFrequency::Transactional)
712            .with_owner(UserPersona::Manager)
713            .with_risk_level(RiskLevel::Medium)
714            .with_assertion(SoxAssertion::Existence)
715            .with_description(
716                "Approval workflow for capital asset additions based on dollar thresholds",
717            )
718            .with_coso_component(CosoComponent::ControlActivities)
719            .with_coso_principles(vec![
720                CosoPrinciple::ControlActions,
721                CosoPrinciple::PoliciesAndProcedures,
722            ])
723            .with_control_scope(ControlScope::TransactionLevel)
724            .with_maturity_level(CosoMaturityLevel::Defined),
725
726            // Intercompany Reconciliation
727            Self::new(
728                "C060",
729                "Intercompany Balance Reconciliation",
730                ControlType::Detective,
731                "Monthly reconciliation of intercompany balances",
732            )
733            .with_frequency(ControlFrequency::Monthly)
734            .with_owner(UserPersona::SeniorAccountant)
735            .with_risk_level(RiskLevel::High)
736            .as_key_control()
737            .with_assertion(SoxAssertion::Completeness)
738            .with_description(
739                "Full reconciliation of intercompany accounts between all entities",
740            )
741            .with_coso_component(CosoComponent::MonitoringActivities)
742            .with_coso_principles(vec![
743                CosoPrinciple::OngoingMonitoring,
744                CosoPrinciple::DeficiencyEvaluation,
745            ])
746            .with_control_scope(ControlScope::TransactionLevel)
747            .with_maturity_level(CosoMaturityLevel::Managed),
748
749            // ========================================
750            // ENTITY-LEVEL CONTROLS (C070-C081)
751            // ========================================
752
753            // Code of Conduct
754            Self::new(
755                "C070",
756                "Code of Conduct and Ethics",
757                ControlType::Preventive,
758                "Establish and communicate ethical values and standards of conduct",
759            )
760            .with_frequency(ControlFrequency::Annual)
761            .with_owner(UserPersona::Controller)
762            .with_risk_level(RiskLevel::High)
763            .as_key_control()
764            .with_assertion(SoxAssertion::PresentationAndDisclosure)
765            .with_description(
766                "Annual review and acknowledgment of code of conduct by all employees; \
767                 includes ethics hotline and whistleblower protections",
768            )
769            .with_coso_component(CosoComponent::ControlEnvironment)
770            .with_coso_principles(vec![
771                CosoPrinciple::IntegrityAndEthics,
772                CosoPrinciple::Accountability,
773            ])
774            .with_control_scope(ControlScope::EntityLevel)
775            .with_maturity_level(CosoMaturityLevel::Managed),
776
777            // Audit Committee Oversight
778            Self::new(
779                "C071",
780                "Audit Committee Oversight",
781                ControlType::Monitoring,
782                "Board and audit committee exercise independent oversight of internal control",
783            )
784            .with_frequency(ControlFrequency::Quarterly)
785            .with_owner(UserPersona::Controller)
786            .with_risk_level(RiskLevel::Critical)
787            .as_key_control()
788            .with_assertion(SoxAssertion::PresentationAndDisclosure)
789            .with_description(
790                "Quarterly audit committee meetings with review of internal control effectiveness, \
791                 external auditor findings, and management representations",
792            )
793            .with_coso_component(CosoComponent::ControlEnvironment)
794            .with_coso_principles(vec![
795                CosoPrinciple::BoardOversight,
796                CosoPrinciple::OrganizationalStructure,
797            ])
798            .with_control_scope(ControlScope::EntityLevel)
799            .with_maturity_level(CosoMaturityLevel::Managed),
800
801            // Risk Assessment Process
802            Self::new(
803                "C075",
804                "Enterprise Risk Assessment",
805                ControlType::Detective,
806                "Identify and assess risks to achievement of organizational objectives",
807            )
808            .with_frequency(ControlFrequency::Annual)
809            .with_owner(UserPersona::Controller)
810            .with_risk_level(RiskLevel::High)
811            .as_key_control()
812            .with_assertion(SoxAssertion::Completeness)
813            .with_description(
814                "Annual enterprise risk assessment process including fraud risk evaluation; \
815                 risk register maintained and updated quarterly",
816            )
817            .with_coso_component(CosoComponent::RiskAssessment)
818            .with_coso_principles(vec![
819                CosoPrinciple::IdentifyRisks,
820                CosoPrinciple::FraudRisk,
821                CosoPrinciple::ChangeIdentification,
822            ])
823            .with_control_scope(ControlScope::EntityLevel)
824            .with_maturity_level(CosoMaturityLevel::Defined),
825
826            // IT General Controls
827            Self::new(
828                "C077",
829                "IT General Controls Program",
830                ControlType::Preventive,
831                "General controls over IT environment supporting financial reporting systems",
832            )
833            .with_frequency(ControlFrequency::Transactional)
834            .with_owner(UserPersona::AutomatedSystem)
835            .with_risk_level(RiskLevel::High)
836            .as_key_control()
837            .with_assertion(SoxAssertion::Existence)
838            .with_description(
839                "IT general controls including access management, change management, \
840                 computer operations, and program development for systems supporting \
841                 financial reporting",
842            )
843            .with_coso_component(CosoComponent::ControlActivities)
844            .with_coso_principles(vec![
845                CosoPrinciple::TechnologyControls,
846                CosoPrinciple::PoliciesAndProcedures,
847            ])
848            .with_control_scope(ControlScope::ItGeneralControl)
849            .with_maturity_level(CosoMaturityLevel::Managed),
850
851            // Information Quality
852            Self::new(
853                "C078",
854                "Financial Information Quality",
855                ControlType::Detective,
856                "Obtain and use quality information for internal control",
857            )
858            .with_frequency(ControlFrequency::Monthly)
859            .with_owner(UserPersona::Controller)
860            .with_risk_level(RiskLevel::Medium)
861            .with_assertion(SoxAssertion::Valuation)
862            .with_description(
863                "Monthly data quality reviews for key financial reports; validation of \
864                 data inputs, processing, and outputs supporting management decisions",
865            )
866            .with_coso_component(CosoComponent::InformationCommunication)
867            .with_coso_principles(vec![
868                CosoPrinciple::QualityInformation,
869                CosoPrinciple::InternalCommunication,
870            ])
871            .with_control_scope(ControlScope::EntityLevel)
872            .with_maturity_level(CosoMaturityLevel::Defined),
873
874            // Monitoring Program
875            Self::new(
876                "C081",
877                "Internal Control Monitoring Program",
878                ControlType::Monitoring,
879                "Ongoing and periodic evaluations of internal control effectiveness",
880            )
881            .with_frequency(ControlFrequency::Quarterly)
882            .with_owner(UserPersona::Controller)
883            .with_risk_level(RiskLevel::High)
884            .as_key_control()
885            .with_assertion(SoxAssertion::Completeness)
886            .with_description(
887                "Continuous monitoring program with quarterly control testing, \
888                 deficiency tracking, and remediation management; annual SOX 404 \
889                 assessment and certification",
890            )
891            .with_coso_component(CosoComponent::MonitoringActivities)
892            .with_coso_principles(vec![
893                CosoPrinciple::OngoingMonitoring,
894                CosoPrinciple::DeficiencyEvaluation,
895            ])
896            .with_control_scope(ControlScope::EntityLevel)
897            .with_maturity_level(CosoMaturityLevel::Managed),
898        ]
899    }
900}
901
902#[cfg(test)]
903#[allow(clippy::unwrap_used)]
904mod tests {
905    use super::*;
906
907    #[test]
908    fn test_control_creation() {
909        let control = InternalControl::new(
910            "TEST001",
911            "Test Control",
912            ControlType::Preventive,
913            "Test objective",
914        )
915        .with_frequency(ControlFrequency::Daily)
916        .with_risk_level(RiskLevel::High)
917        .as_key_control();
918
919        assert_eq!(control.control_id, "TEST001");
920        assert_eq!(control.control_type, ControlType::Preventive);
921        assert_eq!(control.frequency, ControlFrequency::Daily);
922        assert_eq!(control.risk_level, RiskLevel::High);
923        assert!(control.is_key_control);
924    }
925
926    #[test]
927    fn test_standard_controls() {
928        let controls = InternalControl::standard_controls();
929        assert!(!controls.is_empty());
930
931        // Verify key controls exist
932        let key_controls: Vec<_> = controls.iter().filter(|c| c.is_key_control).collect();
933        assert!(key_controls.len() >= 5);
934
935        // Verify different control types exist
936        let preventive: Vec<_> = controls
937            .iter()
938            .filter(|c| c.control_type == ControlType::Preventive)
939            .collect();
940        let detective: Vec<_> = controls
941            .iter()
942            .filter(|c| c.control_type == ControlType::Detective)
943            .collect();
944
945        assert!(!preventive.is_empty());
946        assert!(!detective.is_empty());
947    }
948
949    #[test]
950    fn test_control_status_display() {
951        assert_eq!(ControlStatus::Effective.to_string(), "Effective");
952        assert_eq!(ControlStatus::Exception.to_string(), "Exception");
953    }
954}