# 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.flexbase.in/sample-references-domain/audit-app.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
