> For the complete documentation index, see [llms.txt](https://docs.flexbase.in/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.flexbase.in/sample-references-domain/audit-app.md).

# Audit App

## 🎯 Application Overview

This document demonstrates how to implement a comprehensive audit management system using the Flexbase framework, featuring domain models, workflow states, audit planning, execution tracking, evidence collection, finding management, and enterprise-grade role-based access control. This system is designed to be **universally applicable** to both external audit firms auditing client organizations and internal audit departments auditing their own company.

***

## 📋 Business Requirements

### **Core Entities:**

* **Audit** - A formal audit engagement (External client audit, Internal department audit)
* **Client** - Organization being audited (External client, Internal department, Subsidiary)
* **Auditor** - Person conducting the audit (Senior Auditor, Junior Auditor, Audit Manager)
* **AuditPlan** - High-level scope, objectives, and timeline
* **AuditProgram** - Detailed procedures and steps to execute
* **AuditActivity** - Individual tasks within an audit program
* **Evidence** - Documents, records, and observations collected
* **Finding** - Issues, observations, or recommendations identified
* **Recommendation** - Actions to address findings
* **WorkingPaper** - Documentation of audit procedures performed
* **AuditReport** - Formal report summarizing audit results

### **Workflow Requirements:**

* **Audit Planning** - Risk assessment, scope definition, resource allocation
* **Program Development** - Creating detailed audit procedures and tests
* **Field Work Execution** - Performing audit activities and collecting evidence
* **Finding Documentation** - Recording issues, observations, and recommendations
* **Review & Quality Control** - Manager/Partner review of work performed
* **Report Generation** - Drafting and finalizing audit reports
* **Management Response** - Client/management commitments to address findings
* **Follow-Up** - Verifying implementation of recommendations

### **Role-Based Access Control:**

* **Partner/Senior Manager** - Oversight, report approval, quality review
* **AuditManager** - Plan audits, assign resources, review workpapers
* **SeniorAuditor** - Execute audits, review junior work, draft reports
* **JuniorAuditor** - Perform audit activities, document evidence
* **QualityReviewer** - Perform independent quality assurance reviews
* **ClientContact** - Provide information, respond to findings
* **ClientManagement** - Review findings, commit to recommendations
* **Admin** - Full system access, user management

***

## 🎯 Business Scenario Adaptations

This audit system is designed to be universally applicable. Here are example adaptations:

| Business Scenario      | Audit Type            | Client                 | Auditor                | Example Focus Areas                          |
| ---------------------- | --------------------- | ---------------------- | ---------------------- | -------------------------------------------- |
| **CPA Firm**           | Financial Audit       | Public Company         | External CPA Firm      | Financial statements, internal controls      |
| **Compliance Auditor** | Compliance Audit      | Healthcare Provider    | Regulatory Auditor     | HIPAA, patient privacy, billing              |
| **Internal Audit**     | Operational Audit     | IT Department          | Internal Audit Team    | System access controls, data security        |
| **Inventory Auditor**  | Asset Verification    | Retail Chain           | External Auditor       | Physical inventory, shrinkage analysis       |
| **ISO Auditor**        | Quality Audit         | Manufacturing Plant    | ISO Certification Body | Quality management system                    |
| **Tax Audit**          | Tax Compliance        | Business Entity        | IRS/State Revenue      | Tax returns, deductions, documentation       |
| **Bank Audit**         | Financial Institution | Bank Branch            | Regulatory Auditor     | Lending practices, capital adequacy          |
| **SOC Audit**          | Security Audit        | Cloud Service Provider | Licensed CPA           | Security, availability, processing integrity |
| **Grant Audit**        | Program Performance   | Non-Profit             | Granting Agency        | Grant compliance, fund usage                 |
| **Safety Audit**       | Workplace Safety      | Construction Site      | OSHA Inspector         | Safety protocols, hazard management          |

***

## 🧱 Core Audit Modules (In Depth)

### 1) Audits Module

#### AuditsController Features

* CreateAudit (POST) → `Audit.CreateAudit()`
* UpdateAudit (PUT)
* ApprovePlan (POST) → `Audit.ApprovePlan()`
* StartFieldWork (POST) → `Audit.StartFieldWork()`
* CompleteFieldWork (POST) → `Audit.CompleteFieldWork()`
* FinalizeReport (POST) → `Audit.FinalizeReport()`
* IssueReport (POST) → `Audit.IssueReport()`
* GetAudit(s) (GET)

#### Domain Object: Audit

* Workflow: `AuditWorkflowState`
* States: Planned → Approved → FieldWork → Review → ReportDraft → ReportFinal → Issued → Completed
* Types: Financial, Compliance, Operational, IT/Security, Asset Verification
* RBAC:
  * Manager: Create, Approve, Review
  * Auditor: Execute, Document
  * Partner: Approve, Issue Report
  * Client: Provide information, respond

```csharp
[Table("Audits")]
[Index(nameof(ClientId), Name="IX_Audits_Client")]
[Index(nameof(AuditType), Name="IX_Audits_Type")]
[Index(nameof(PlannedStartDate), Name="IX_Audits_StartDate")]
public partial class Audit : DomainModelBridge
{
    public AuditWorkflowState AuditState { get; protected set; } = new AuditPlanned();
    
    public string AuditType { get; protected set; } // Financial | Compliance | Operational | IT | Asset
    public string AuditCode { get; protected set; } // Unique identifier: FY2024-AUDIT-001
    public string AuditObjective { get; protected set; }
    
    public string ClientId { get; protected set; } // FK → Client.Id
    public string ClientName { get; protected set; } // Denormalized for reporting
    
    public string? ClientContactId { get; protected set; } // Primary client contact
    public string? AuditManagerId { get; protected set; } // Managing auditor
    public string? PartnerId { get; protected set; } // Partner in charge
    
    // Audit scope
    public string AuditScope { get; protected set; } // What areas are being audited
    public DateTime? PeriodStartDate { get; protected set; } // Period being audited
    public DateTime? PeriodEndDate { get; protected set; }
    public string[] AuditAreas { get; protected set; } // ["Cash", "Inventory", "Receivables"]
    
    // Timeline
    public DateTime PlannedStartDate { get; protected set; }
    public DateTime PlannedEndDate { get; protected set; }
    public DateTime? ActualStartDate { get; protected set; }
    public DateTime? ActualEndDate { get; protected set; }
    
    // Budget
    public decimal BudgetedHours { get; protected set; }
    public decimal ActualHours { get; protected set; }
    public decimal BudgetedFee { get; protected set; }
    
    // Risk assessment
    public string RiskAssessment { get; protected set; } // Low | Medium | High
    public string MaterialityLevel { get; protected set; }
    
    public string TimeZoneId { get; protected set; } = "UTC";
    public string? Notes { get; protected set; }
    
    // Navigation properties
    public Client Client { get; protected set; }
    public ICollection<AuditorAssignment> AuditorAssignments { get; protected set; } = new List<AuditorAssignment>();
    public ICollection<AuditProgram> AuditPrograms { get; protected set; } = new List<AuditProgram>();
    public ICollection<Finding> Findings { get; protected set; } = new List<Finding>();
    public ICollection<WorkingPaper> WorkingPapers { get; protected set; } = new List<WorkingPaper>();
    public AuditReport? Report { get; protected set; }
    
    [BusinessMethod]
    public virtual Audit CreateAudit(CreateAuditCommand cmd)
    {
        var role = cmd.Dto.GetAppContext()?.UserRole ?? "Guest";
        if (!AuditState.CanTransition(role, "Create")) throw new UnauthorizedAccessException();
        this.Convert(cmd.Dto);
        this.SetAdded(cmd.Dto.GetGeneratedId());
        return this;
    }
    
    [BusinessMethod]
    public virtual Audit ApprovePlan(ApprovePlanCommand cmd)
    {
        var role = cmd.Dto.GetAppContext()?.UserRole ?? "Guest";
        if (!AuditState.CanTransition(role, "Approve")) throw new UnauthorizedAccessException();
        AuditState = AuditState.Approve();
        this.SetModified();
        return this;
    }
    
    [BusinessMethod]
    public virtual Audit StartFieldWork(StartFieldWorkCommand cmd)
    {
        var role = cmd.Dto.GetAppContext()?.UserRole ?? "Guest";
        if (!AuditState.CanTransition(role, "StartFieldWork")) throw new UnauthorizedAccessException();
        AuditState = AuditState.StartFieldWork();
        ActualStartDate = DateTime.UtcNow;
        this.SetModified();
        return this;
    }
}

public class AuditWorkflowState : FlexState
{
    public virtual AuditWorkflowState Approve() => this;
    public virtual AuditWorkflowState StartFieldWork() => this;
    public virtual AuditWorkflowState CompleteFieldWork() => this;
    public virtual AuditWorkflowState SubmitForReview() => this;
    public virtual AuditWorkflowState ApproveReport() => this;
    public virtual AuditWorkflowState IssueReport() => this;
    public virtual AuditWorkflowState Complete() => this;
    public virtual bool CanTransition(string role, string action) => GetAllowedRoles(action).Contains(role);
    protected virtual string[] GetAllowedRoles(string action) => Array.Empty<string>();
}

public class AuditPlanned : AuditWorkflowState
{
    protected override string[] GetAllowedRoles(string action) => action switch
    {
        "Create" => new[] { "AuditManager", "Partner" },
        "Approve" => new[] { "Partner", "SeniorManager" },
        _ => Array.Empty<string>()
    };
    public override AuditWorkflowState Approve() => new AuditApproved();
}

public class AuditApproved : AuditWorkflowState
{
    protected override string[] GetAllowedRoles(string action) => action switch
    {
        "StartFieldWork" => new[] { "AuditManager", "SeniorAuditor" },
        "Approve" => new[] { "Partner" },
        _ => Array.Empty<string>()
    };
    public override AuditWorkflowState StartFieldWork() => new AuditInFieldWork();
}

public class AuditInFieldWork : AuditWorkflowState
{
    protected override string[] GetAllowedRoles(string action) => action switch
    {
        "CompleteFieldWork" => new[] { "AuditManager", "SeniorAuditor" },
        "StartFieldWork" => new[] { "AuditManager", "SeniorAuditor" },
        _ => Array.Empty<string>()
    };
    public override AuditWorkflowState CompleteFieldWork() => new AuditInReview();
}

public class AuditInReview : AuditWorkflowState
{
    protected override string[] GetAllowedRoles(string action) => action switch
    {
        "ApproveReport" => new[] { "Partner" },
        "CompleteFieldWork" => new[] { "AuditManager" },
        _ => Array.Empty<string>()
    };
    public override AuditWorkflowState ApproveReport() => new AuditReportDraft();
}

public class AuditReportDraft : AuditWorkflowState
{
    protected override string[] GetAllowedRoles(string action) => action switch
    {
        "IssueReport" => new[] { "Partner" },
        "ApproveReport" => new[] { "Partner" },
        _ => Array.Empty<string>()
    };
    public override AuditWorkflowState IssueReport() => new AuditReportIssued();
}

public class AuditReportIssued : AuditWorkflowState
{
    protected override string[] GetAllowedRoles(string action) => action switch
    {
        "Complete" => new[] { "AuditManager", "Partner" },
        _ => Array.Empty<string>()
    };
    public override AuditWorkflowState Complete() => new AuditCompleted();
}

public class AuditCompleted : AuditWorkflowState { }
```

***

### 2) Clients Module

#### ClientsController Features

* RegisterClient (POST) → `Client.RegisterClient()`
* UpdateProfile (PUT)
* SetStatus (POST) → `Client.SetActive()`
* Blacklist (POST) → `Client.Blacklist()`

#### Domain Object: Client

* Represents organizations being audited
* Types: External Client, Internal Department, Subsidiary

```csharp
[Table("Clients")]
[Index(nameof(ClientCode), Name="IX_Clients_Code", IsUnique = true)]
public partial class Client : DomainModelBridge
{
    public string ClientType { get; protected set; } // External | Internal | Subsidiary
    public string ClientCode { get; protected set; } // Unique identifier
    public string CompanyName { get; protected set; }
    public string? LegalName { get; protected set; }
    
    public string Industry { get; protected set; }
    public string Address { get; protected set; }
    public string City { get; protected set; }
    public string State { get; protected set; }
    public string PostalCode { get; protected set; }
    public string Country { get; protected set; }
    
    public string PrimaryContactName { get; protected set; }
    public string PrimaryContactEmail { get; protected set; }
    public string PrimaryContactPhone { get; protected set; }
    
    public DateTime? LastAuditDate { get; protected set; }
    public string? AuditorFirmId { get; protected set; } // For external audits
    
    public string TimeZoneId { get; protected set; } = "America/New_York";
    
    // Navigation properties
    public ICollection<Audit> Audits { get; protected set; } = new List<Audit>();
    public ICollection<ClientContact> Contacts { get; protected set; } = new List<ClientContact>();
}
```

***

### 3) Audit Programs Module

#### AuditProgramsController Features

* CreateProgram (POST) → `AuditProgram.Create()`
* AddActivity (POST) → `AuditProgram.AddActivity()`
* CompleteActivity (POST) → `AuditActivity.Complete()`
* MarkAsReviewed (POST) → `AuditActivity.MarkAsReviewed()`

#### Domain Object: AuditProgram

* Detailed procedures and steps for an audit
* Template-based or custom programs

```csharp
[Table("AuditPrograms")]
[Index(nameof(AuditId), Name="IX_Programs_Audit")]
public partial class AuditProgram : DomainModelBridge
{
    public string AuditId { get; protected set; }
    public string ProgramName { get; protected set; }
    public string AuditArea { get; protected set; } // Cash, Inventory, IT Controls, etc.
    
    public string ProgramObjective { get; protected set; }
    public string? TemplateId { get; protected set; } // If based on template
    
    public DateTime CreatedDate { get; protected set; }
    public DateTime? CompletedDate { get; protected set; }
    
    public string ProgramStatus { get; protected set; } // Draft | InProgress | Completed | Reviewed
    
    // Navigation properties
    public Audit Audit { get; protected set; }
    public ICollection<AuditActivity> Activities { get; protected set; } = new List<AuditActivity>();
}

[Table("AuditActivities")]
[Index(nameof(ProgramId), Name="IX_Activities_Program")]
public partial class AuditActivity : DomainModelBridge
{
    public ActivityWorkflowState ActivityState { get; protected set; } = new ActivityPending();
    
    public string ProgramId { get; protected set; }
    public int ActivityNumber { get; protected set; }
    public string ActivityDescription { get; protected set; }
    
    public string AssignedToId { get; protected set; } // Auditor assigned
    public DateTime? AssignedDate { get; protected set; }
    public DateTime? StartedDate { get; protected set; }
    public DateTime? CompletedDate { get; protected set; }
    
    public string? TestProcedure { get; protected set; } // What to test
    public string? TestSteps { get; protected set; } // How to test
    public string? ExpectedResult { get; protected set; }
    
    public string? ActualResult { get; protected set; } // What was found
    public string? Conclusion { get; protected set; } // Pass | Fail | Exception
    
    public decimal EstimatedHours { get; protected set; }
    public decimal ActualHours { get; protected set; }
    
    // Navigation properties
    public AuditProgram Program { get; protected set; }
    public ICollection<Evidence> EvidenceItems { get; protected set; } = new List<Evidence>();
    public ICollection<WorkingPaper> WorkingPapers { get; protected set; } = new List<WorkingPaper>();
}

public class ActivityWorkflowState : FlexState
{
    public virtual ActivityWorkflowState Start() => this;
    public virtual ActivityWorkflowState Complete() => this;
    public virtual ActivityWorkflowState Review() => this;
}

public class ActivityPending : ActivityWorkflowState
{
    public override ActivityWorkflowState Start() => new ActivityInProgress();
}

public class ActivityInProgress : ActivityWorkflowState
{
    public override ActivityWorkflowState Complete() => new ActivityCompleted();
}

public class ActivityCompleted : ActivityWorkflowState
{
    public override ActivityWorkflowState Review() => new ActivityReviewed();
}

public class ActivityReviewed : ActivityWorkflowState { }
```

***

### 4) Findings Module

#### FindingsController Features

* CreateFinding (POST) → `Finding.Create()`
* AssignPriority (POST) → `Finding.AssignPriority()`
* RequestManagementResponse (POST) → `Finding.RequestManagementResponse()`
* VerifyImplementation (POST) → `Finding.VerifyImplementation()`
* CloseFinding (POST) => `Finding.Close()`

#### Domain Object: Finding

* Issues, observations, or exceptions identified during audit

```csharp
[Table("Findings")]
[Index(nameof(AuditId), Name="IX_Findings_Audit")]
public partial class Finding : DomainModelBridge
{
    public FindingWorkflowState FindingState { get; protected set; } = new FindingDraft();
    
    public string AuditId { get; protected set; }
    public string ActivityId { get; protected set; } // Which activity found this
    
    public string FindingType { get; protected set; } // Deficiency | Observation | Recommendation
    public string Priority { get; protected set; } // Critical | High | Medium | Low
    
    public string Title { get; protected set; }
    public string Description { get; protected set; } // What was found
    public string Condition { get; protected set; } // What condition exists
    public string Criteria { get; protected set; } // What should have been
    public string Cause { get; protected set; } // Why it happened
    
    public string? RiskAssessment { get; protected set; } // Impact assessment
    public string? Recommendation { get; protected set; } // What should be done
    
    public DateTime IdentifiedDate { get; protected set; }
    public DateTime? ManagementResponseDate { get; protected set; }
    public string? ManagementResponse { get; protected set; }
    public DateTime? CommittedResolutionDate { get; protected set; }
    public DateTime? VerifiedDate { get; protected set; }
    public bool IsVerified { get; protected set; }
    
    public string IdentifiedBy { get; protected set; } // Auditor who found it
    public string? ReviewedBy { get; protected set; } // Manager who reviewed
    
    // Navigation properties
    public Audit Audit { get; protected set; }
    public AuditActivity Activity { get; protected set; }
    public ICollection<Evidence> EvidenceItems { get; protected set; } = new List<Evidence>();
}

public class FindingWorkflowState : FlexState
{
    public virtual FindingWorkflowState SubmitForReview() => this;
    public virtual FindingWorkflowState RequestManagementResponse() => this;
    public virtual FindingWorkflowState Verify() => this;
    public virtual FindingWorkflowState Close() => this;
}

public class FindingDraft : FindingWorkflowState
{
    public override FindingWorkflowState SubmitForReview() => new FindingPendingReview();
}

public class FindingPendingReview : FindingWorkflowState
{
    public override FindingWorkflowState RequestManagementResponse() => new FindingAwaitingResponse();
}

public class FindingAwaitingResponse : FindingWorkflowState
{
    public override FindingWorkflowState RequestManagementResponse() => new FindingResponded();
}

public class FindingResponded : FindingWorkflowState
{
    public override FindingWorkflowState Verify() => new FindingVerified();
}

public class FindingVerified : FindingWorkflowState
{
    public override FindingWorkflowState Close() => new FindingClosed();
}

public class FindingClosed : FindingWorkflowState { }
```

***

### 5) Evidence Module

#### EvidenceController Features

* UploadEvidence (POST) → `Evidence.Upload()`
* LinkToActivity (POST) → `Evidence.LinkToActivity()`
* LinkToFinding (POST) → `Evidence.LinkToFinding()`
* VerifyAuthenticity (POST) → `Evidence.Verify()`

#### Domain Object: Evidence

* Documents, records, screenshots, observations supporting audit work

```csharp
[Table("Evidence")]
[Index(nameof(AuditId), Name="IX_Evidence_Audit")]
public partial class Evidence : DomainModelBridge
{
    public string AuditId { get; protected set; }
    public string? ActivityId { get; protected set; } // Linked to activity
    public string? FindingId { get; protected set; } // Linked to finding
    
    public string EvidenceType { get; protected set; } // Document | Observation | Screenshot | Email | Interview
    public string EvidenceTitle { get; protected set; }
    public string EvidenceDescription { get; protected set; }
    
    public string FilePath { get; protected set; } // Path to file
    public string FileName { get; protected set; }
    public string FileExtension { get; protected set; }
    public long FileSize { get; protected set; }
    
    public DateTime ObtainedDate { get; protected set; }
    public string ObtainedBy { get; protected set; } // Auditor who obtained
    public string Source { get; protected set; } // From whom/where
    
    public bool IsAuthenticated { get; protected set; } // Verified authenticity
    public string? AuthenticatedBy { get; protected set; }
    public DateTime? AuthenticatedDate { get; protected set; }
    
    public string? Notes { get; protected set; }
    
    // Navigation properties
    public Audit Audit { get; protected set; }
    public AuditActivity? Activity { get; protected set; }
    public Finding? Finding { get; protected set; }
}
```

***

### 6) Working Papers Module

#### WorkingPapersController Features

* CreateWorkingPaper (POST) → `WorkingPaper.Create()`
* UpdateProcedures (PUT)
* AttachEvidence (POST) → `WorkingPaper.AttachEvidence()`
* MarkAsReviewed (POST) => `WorkingPaper.MarkAsReviewed()`

#### Domain Object: WorkingPaper

* Documentation of audit procedures performed and conclusions reached

```csharp
[Table("WorkingPapers")]
[Index(nameof(AuditId), Name="IX_WorkingPapers_Audit")]
[Index(nameof(ActivityId), Name="IX_WorkingPapers_Activity")]
public partial class WorkingPaper : DomainModelBridge
{
    public WorkingPaperWorkflowState PaperState { get; protected set; } = new PaperDraft();
    
    public string AuditId { get; protected set; }
    public string ActivityId { get; protected set; }
    public string WorkingPaperNumber { get; protected set; } // WP-001, WP-002
    
    public string PaperTitle { get; protected set; }
    public string PaperObjective { get; protected set; }
    public string ProceduresPerformed { get; protected set; }
    public string KeyObservations { get; protected set; }
    public string Conclusion { get; protected set; }
    
    public DateTime CreatedDate { get; protected set; }
    public DateTime? ReviewedDate { get; protected set; }
    public string? ReviewedBy { get; protected set; }
    public string? ReviewerComments { get; protected set; }
    
    public decimal HoursSpent { get; protected set; }
    
    // Navigation properties
    public Audit Audit { get; protected set; }
    public AuditActivity Activity { get; protected set; }
    public ICollection<Evidence> EvidenceItems { get; protected set; } = new List<Evidence>();
}
```

***

### 7) Audit Reports Module

#### ReportsController Features

* CreateReport (POST) → `AuditReport.Create()`
* DraftExecutiveSummary (POST) → `AuditReport.DraftExecutiveSummary()`
* AddFindingToReport (POST) → `AuditReport.AddFinding()`
* SubmitForApproval (POST) => `AuditReport.SubmitForApproval()`
* Approve (POST) => `AuditReport.Approve()`
* IssueReport (POST) => `AuditReport.Issue()`

#### Domain Object: AuditReport

* Formal report summarizing audit objectives, scope, findings, and conclusions

```csharp
[Table("AuditReports")]
[Index(nameof(AuditId), Name="IX_Reports_Audit", IsUnique = true)]
public partial class AuditReport : DomainModelBridge
{
    public ReportWorkflowState ReportState { get; protected set; } = new ReportDraft();
    
    public string AuditId { get; protected set; }
    public string ReportNumber { get; protected set; } // RPT-2024-001
    
    public string ExecutiveSummary { get; protected set; }
    public string AuditScope { get; protected set; }
    public string Methodology { get; protected set; }
    
    public int TotalFindings { get; protected set; }
    public int CriticalFindings { get; protected set; }
    public int HighFindings { get; protected set; }
    public int MediumFindings { get; protected set; }
    public int LowFindings { get; protected set; }
    
    public decimal TotalBudgetedHours { get; protected set; }
    public decimal TotalActualHours { get; protected set; }
    
    public DateTime ReportDate { get; protected set; }
    public DateTime? IssuedDate { get; protected set; }
    public string IssuedTo { get; protected set; } // Client management
    
    public string PreparedBy { get; protected set; }
    public string ReviewedBy { get; protected set; }
    public string ApprovedBy { get; protected set; }
    
    // Navigation properties
    public Audit Audit { get; protected set; }
    public ICollection<Finding> Findings { get; protected set; } = new List<Finding>();
}

public class ReportWorkflowState : FlexState
{
    public virtual ReportWorkflowState SubmitForApproval() => this;
    public virtual ReportWorkflowState Approve() => this;
    public virtual ReportWorkflowState Issue() => this;
}

public class ReportDraft : ReportWorkflowState
{
    public override ReportWorkflowState SubmitForApproval() => new ReportPendingApproval();
}

public class ReportPendingApproval : ReportWorkflowState
{
    public override ReportWorkflowState Approve() => new ReportApproved();
    public override ReportWorkflowState SubmitForApproval() => new ReportPendingRevision();
}

public class ReportPendingRevision : ReportWorkflowState
{
    public override ReportWorkflowState SubmitForApproval() => new ReportPendingApproval();
}

public class ReportApproved : ReportWorkflowState
{
    public override ReportWorkflowState Issue() => new ReportIssued();
}

public class ReportIssued : ReportWorkflowState { }
```

***

## 📊 Audit Tracking (Activity Logging)

Purpose: Track all audit activities, changes, and user actions with complete audit trail.

### Audit Trail Events

```csharp
[Table("AuditTrail")]
[Index(nameof(AuditId), nameof(EventDate), Name="IX_Trail_Audit_Date")]
public class AuditTrail : DomainModelBridge
{
    public string AuditId { get; set; }
    public string EntityType { get; set; } // Audit | Finding | Evidence | WorkingPaper
    public string EntityId { get; set; }
    public string EventType { get; set; } // Created | Updated | Deleted | Reviewed | Approved
    public DateTime EventDate { get; set; }
    public string UserId { get; set; }
    public string UserName { get; set; }
    public string? EventDescription { get; set; }
    public string? PreviousValue { get; set; }
    public string? NewValue { get; set; }
    public string? IPAddress { get; set; }
}
```

***

## 📚 Financial Audit Example (Detailed)

### Scenario: Annual Financial Statement Audit - Public Company

**Initial Setup:**

```csharp
var audit = new Audit()
{
    AuditType = "Financial",
    AuditCode = "FY2024-FIN-AUDIT-001",
    AuditObjective = "Express an opinion on the fair presentation of the financial statements",
    ClientId = "ABC_CORP_PUBLIC",
    ClientName = "ABC Corporation",
    ClientType = "Public Company",
    PeriodStartDate = new DateTime(2024, 1, 1),
    PeriodEndDate = new DateTime(2024, 12, 31),
    PlannedStartDate = new DateTime(2025, 1, 15),
    PlannedEndDate = new DateTime(2025, 3, 31),
    BudgetedHours = 800m,
    BudgetedFee = 150000m,
    RiskAssessment = "High",
    MaterialityLevel = 500000m,
    AuditState = new AuditPlanned()
};
```

**Program Development:**

```csharp
public void CreateFinancialAuditProgram(string auditId)
{
    var areas = new[] { "Cash", "Receivables", "Inventory", "FixedAssets", "Payables", "Equity" };
    
    foreach (var area in areas)
    {
        var program = new AuditProgram()
        {
            AuditId = auditId,
            ProgramName = $"Audit Program - {area}",
            AuditArea = area,
            ProgramObjective = $"Audit {area} for existence, completeness, valuation, rights, and presentation",
            ProgramStatus = "Draft"
        };
        
        // Create activities based on program
        CreateActivitiesForArea(program);
    }
}

private void CreateActivitiesForArea(AuditProgram program)
{
    var activities = new[]
    {
        new AuditActivity()
        {
            ProgramId = program.Id,
            ActivityNumber = 1,
            ActivityDescription = "Obtain and review bank reconciliations",
            TestProcedure = "Verify reconciliation adjustments",
            ExpectedResult = "All adjustments properly documented and approved",
            EstimatedHours = 4m,
            AssignedToId = "senior.auditor.001"
        },
        new AuditActivity()
        {
            ProgramId = program.Id,
            ActivityNumber = 2,
            ActivityDescription = "Confirm bank balances with financial institutions",
            TestProcedure = "Send confirmation requests to banks",
            ExpectedResult = "All balances confirmed by banks",
            EstimatedHours = 2m,
            AssignedToId = "junior.auditor.001"
        },
        new AuditActivity()
        {
            ProgramId = program.Id,
            ActivityNumber = 3,
            ActivityDescription = "Test cutoff of cash transactions",
            TestProcedure = "Verify transactions recorded in correct period",
            ExpectedResult = "All transactions properly cut off",
            EstimatedHours = 6m,
            AssignedToId = "junior.auditor.001"
        }
    };
    
    program.Activities = activities;
}
```

**Finding Documentation:**

```csharp
public void DocumentFinding(string auditId, string activityId, FindingInput dto)
{
    var finding = new Finding()
    {
        AuditId = auditId,
        ActivityId = activityId,
        FindingType = "Deficiency",
        Priority = "High",
        Title = "Segregation of Duties Violation in Cash Disbursements",
        Description = "Accounting clerk has access to both cash receipts and disbursements",
        Condition = "Same person can record both receipt and disbursement transactions",
        Criteria = "Cash receipts and disbursements should be handled by different staff",
        Cause = "Insufficient staffing in accounting department",
        RiskAssessment = "Material risk of fraud or error in cash transactions",
        Recommendation = "Hire additional accounting clerk or rotate responsibilities",
        IdentifiedDate = DateTime.UtcNow,
        IdentifiedBy = _currentAuditorId,
        FindingState = new FindingDraft()
    };
    
    _repo.Insert(finding);
    
    // Request management response
    RequestManagementResponse(finding.Id);
}

public void RequestManagementResponse(string findingId)
{
    var finding = FindFinding(findingId);
    
    // Notify client management
    var notification = new Notification()
    {
        Type = "FindingIdentified",
        RecipientId = finding.Audit.ClientContactId,
        Subject = "Audit Finding Requiring Your Response",
        Body = $"A high-priority finding has been identified: {finding.Title}",
        RelatedEntityId = findingId
    };
    
    finding.FindingState = new FindingAwaitingResponse();
}
```

**Evidence Collection:**

```csharp
public void UploadEvidence(string activityId, FileUploadDto dto)
{
    var evidence = new Evidence()
    {
        AuditId = _auditId,
        ActivityId = activityId,
        EvidenceType = "Document",
        EvidenceTitle = dto.Title,
        EvidenceDescription = dto.Description,
        FilePath = SaveFile(dto.File),
        FileName = dto.FileName,
        FileExtension = dto.FileExtension,
        FileSize = dto.FileSize,
        ObtainedDate = DateTime.UtcNow,
        ObtainedBy = _currentAuditorId,
        Source = dto.Source,
        IsAuthenticated = false
    };
    
    _repo.Insert(evidence);
    
    // Link to activity
    var activity = FindActivity(activityId);
    activity.EvidenceItems.Add(evidence);
}

public void VerifyEvidenceAuthenticity(string evidenceId, string verifiedBy)
{
    var evidence = FindEvidence(evidenceId);
    
    evidence.IsAuthenticated = true;
    evidence.AuthenticatedBy = verifiedBy;
    evidence.AuthenticatedDate = DateTime.UtcNow;
    
    // Record in audit trail
    RecordAuditTrail("Evidence", evidenceId, "Verified", _currentAuditorId);
}
```

**Working Paper Completion:**

```csharp
public void CompleteWorkingPaper(string activityId, WorkingPaperDto dto)
{
    var wp = new WorkingPaper()
    {
        AuditId = _auditId,
        ActivityId = activityId,
        WorkingPaperNumber = GenerateWpNumber(activityId),
        PaperTitle = dto.Title,
        PaperObjective = dto.Objective,
        ProceduresPerformed = dto.Procedures,
        KeyObservations = dto.Observations,
        Conclusion = dto.Conclusion,
        CreatedDate = DateTime.UtcNow,
        HoursSpent = dto.HoursSpent,
        PaperState = new PaperDraft()
    };
    
    _repo.Insert(wp);
    
    // Link evidence
    foreach (var evidenceId in dto.EvidenceIds)
    {
        var evidence = FindEvidence(evidenceId);
        wp.EvidenceItems.Add(evidence);
    }
    
    // Update activity
    var activity = FindActivity(activityId);
    activity.ActualResult = dto.Conclusion;
    activity.ActivityState = new ActivityCompleted();
    activity.CompletedDate = DateTime.UtcNow;
    activity.ActualHours = dto.HoursSpent;
}
```

**Report Generation:**

```csharp
public void GenerateAuditReport(string auditId)
{
    var audit = FindAudit(auditId);
    var findings = FindFindingsForAudit(auditId);
    
    var report = new AuditReport()
    {
        AuditId = auditId,
        ReportNumber = GenerateReportNumber(audit),
        ExecutiveSummary = GenerateExecutiveSummary(audit, findings),
        AuditScope = audit.AuditScope,
        Methodology = "Risk-based audit approach with substantive procedures",
        TotalFindings = findings.Count,
        CriticalFindings = findings.Count(f => f.Priority == "Critical"),
        HighFindings = findings.Count(f => f.Priority == "High"),
        MediumFindings = findings.Count(f => f.Priority == "Medium"),
        LowFindings = findings.Count(f => f.Priority == "Low"),
        TotalBudgetedHours = audit.BudgetedHours,
        TotalActualHours = audit.ActualHours,
        ReportDate = DateTime.UtcNow,
        PreparedBy = _currentAuditorId,
        Findings = findings.Where(f => f.FindingState is FindingVerified).ToList()
    };
    
    audit.Report = report;
    audit.AuditState = new AuditReportDraft();
}

public string GenerateExecutiveSummary(Audit audit, List<Finding> findings)
{
    return $@"
Audit Summary Report
Client: {audit.ClientName}
Audit Period: {audit.PeriodStartDate:yyyy-MM-dd} to {audit.PeriodEndDate:yyyy-MM-dd}
Audit Objectives: {audit.AuditObjective}

Findings Summary:
- Total Findings: {findings.Count}
- Critical/High Findings: {findings.Count(f => f.Priority == "Critical" || f.Priority == "High")}
- Medium Findings: {findings.Count(f => f.Priority == "Medium")}
- Low Findings: {findings.Count(f => f.Priority == "Low")}

Overall Assessment: {"Qualified" if findings.Any(f => f.Priority == "Critical") else "Clean"} Opinion
";
}
```

***

## 🎯 Key Implementation Notes

### Quality Control

* Two-level review: Manager reviews auditor work, Partner reviews entire engagement
* Mandatory review checkpoints before state transitions
* Sampling procedures for high-volume testing

### Compliance Standards

* Support GAAS, SOX, ISO, HIPAA, SOC, and other frameworks
* Template-based audit programs by standard
* Automated compliance checking

### Risk-Based Auditing

* Materiality calculations
* Risk assessment matrices
* Focused testing on high-risk areas

### Technology Integration

* Document management system integration
* Continuous auditing tools
* Data analytics integration

### Report Generation

* Templates by audit type and standard
* Automated finding aggregation
* Professional formatting

This design provides a flexible, enterprise-grade audit management system applicable to any audit scenario while maintaining comprehensive tracking, workflow controls, and quality assurance.
