1. Introduction

The Single Audit implementation in the Audit-Lite application provides a streamlined approach for conducting audits by individual users. Unlike [team audits](../Team Audit/TeamAuditOverview.md), where multiple participants collaborate on different sections, single audits are designed for standalone use by a single auditor.

This documentation details the architecture, flows, and implementation specifics of the single audit feature, focusing on the questionnaire system, data management, and user experience.

2. Single Audit Workflow

The Single Audit process follows a comprehensive workflow from creation to completion:

2.1 Audit Initialization

The process begins when an auditor selects a site to audit and creates a new Single Audit:

sequenceDiagram
    participant User as Auditor
    participant App
    participant API
    participant DB as Database

    User->>App: Select "Create New Audit"
    User->>App: Select Site
    App->>API: POST /api/report/create {siteID, type: "single"}
    API->>DB: Create Audit Record
    DB-->>API: Return Audit ID
    API-->>App: Return Audit Data
    App-->>User: Display New Audit

The initialization creates a new audit record with the following state:

  • Status: “in_progress”
  • Progress: 0%
  • Questions initialized with default values
  • Timestamps for created/updated

2.1.1 Starting from Scheduled Audits

Many single audits begin from the schedule screen, where upcoming audits are listed:

sequenceDiagram
    participant User as Auditor
    participant Schedule as Schedule Screen
    participant Controller as StartReportController
    participant API as Backend API
    participant Router as Navigation Router

    User->>Schedule: View Scheduled Audits
    User->>Schedule: Select Site Schedule
    Schedule->>Controller: confirmStartReport(siteSchedule)
    Controller->>Controller: Open Confirmation Dialog
    User->>Controller: Confirm Start Audit
    Controller->>API: checkInReport(siteScheduleId)
    API-->>Controller: Return reportId and metadata
    Controller->>Router: Navigate to Questionnaire(reportId)
    Router->>User: Display Questionnaire Screen

The start report process involves:

  1. Schedule Selection: Choosing from pre-configured audit schedules
  2. Check-in Process: Creating a report record associated with the schedule
  3. Initialization: Setting up the questionnaire with the correct template
  4. Navigation: Taking the user to the first question

During initialization, the system checks:

  • User permissions for the selected site
  • Connectivity status (online/offline)
  • Template availability
  • Previous incomplete audits for the same site

2.2 Questionnaire Navigation

Auditors move through the questionnaire in sequence, providing responses and evidence:

stateDiagram-v2
    [*] --> Question1
    Question1 --> CompleteQ1: Answer
    CompleteQ1 --> Question2: Next
    Question2 --> CompleteQ2: Answer
    Question2 --> Question1: Previous
    CompleteQ2 --> Question3: Next
    Question3 --> Question2: Previous
    Question3 --> CompleteQ3: Answer
    CompleteQ3 --> Review: Submit
    Review --> [*]

Navigation is controlled by the useQuestionnaireNavigation hook, which provides:

  • onPressPrevious: Navigate to the previous question
  • onPressNext: Navigate to the next question or summary if on last question
  • onPressClear: Clear the current question’s answers and attachments
  • onPressReview: Navigate to the summary screen

2.3 Question Types and Response Handling

The questionnaire supports various question types, each with specific UI and validation requirements:

Question TypeDescriptionValidation
BINARYYes/No questionsMust select one option
BINARY_WITH_RED_FLAGYes/No with flag optionsMust select option and flag if applicable
SCORENumeric scoring questionsMust provide valid score
MULTIPLE_CHOICESelection from optionsMust select at least one option
CHECKLISTMultiple selectable itemsOptional selections
OPENFree text inputLength validation if applicable
NUMBERNumeric input fieldRange validation if applicable

When a question is answered:

  1. The answer is validated against requirements
  2. Progress is automatically calculated and updated
  3. Changes are saved to local cache and synchronized
  4. Any conditional questions are dynamically shown or hidden

2.4 Attachment Management

Each question can specify requirements for different types of attachments:

graph TD
    A[Question] --> B{Requires Attachments?}
    B -->|Yes| C[Display Attachment Controls]
    B -->|No| D[Skip Attachment UI]

    C --> E[Photos]
    C --> F[Videos]
    C --> G[Documents]

    E --> H[Camera/Gallery Access]
    F --> I[Video Recording]
    G --> J[Document Picker]

    H --> K[Process and Store]
    I --> K
    J --> K

    K --> L[Display in UI]
    K --> M[Upload When Online]

Attachment specifications:

  • photoMinimum: Minimum number of photos required
  • videoLimit: Maximum number of videos allowed
  • documentMinimum: Minimum number of documents required

Attachments are:

  1. Captured through device camera or selected from gallery/files
  2. Stored locally first with metadata (creation time, size, etc.)
  3. Uploaded to server when online (with retry mechanism)
  4. Accessible for review during the audit process

If an attachment is deleted:

  1. It is removed from the question’s attachment list
  2. The cached version is deleted
  3. The server is notified to remove it (if online)
  4. Progress is recalculated based on remaining attachments

2.5 Progress Tracking

Progress tracking is automatically calculated based on completion of questions:

flowchart TD
    A[User Answers Question] --> B[useActiveQuestionProgressTrigger]
    B --> C[Calculate Question Progress]
    C --> D[Update Progress State]
    D --> E[Update UI]
    C --> F[Save Progress to Cache]

    G[Initialize Questionnaire] --> H[useQuestionnaireProgressTrigger]
    H --> I[Calculate Overall Progress]
    I --> J[Update Progress State]
    J --> K[Update Progress UI]

Progress calculation considers:

  • Answered required questions
  • Completed attachment requirements
  • Added required comments
  • Completed conditional questions

The progress is displayed in the UI via a progress bar and percentage, helping auditors track their completion status.

2.5.1 Progress Calculation Logic

The progress calculation is handled by dedicated controllers that track completion of individual questions:

sequenceDiagram
    participant Form as Form State
    participant Trigger as Progress Trigger
    participant Usecase as Progress Usecase
    participant Atoms as Progress Atoms
    participant UI as User Interface
    participant Cache as Report Cache

    Note over Form,UI: User answers a question
    Form->>Trigger: Value changes
    Trigger->>Usecase: computeActiveQuestionProgress()
    Usecase->>Form: Get current question state

    Usecase->>Usecase: Apply validation rules
    Usecase->>Usecase: Update completion status

    Usecase->>Atoms: Update progress state
    Atoms->>UI: Reactive UI update

    Usecase->>Cache: Save progress data

    Note over Form,UI: Initial load or full recalculation
    Form->>Trigger: Initialize or recalculate
    Trigger->>Usecase: computeQuestionnaireProgress()
    Usecase->>Form: Get all questions state

    Usecase->>Usecase: Process each question
    Usecase->>Usecase: Count completed questions
    Usecase->>Usecase: Calculate percentage

    Usecase->>Atoms: Update overall progress
    Atoms->>UI: Update progress bar and count

    Usecase->>Cache: Save overall progress

The progress calculation uses a weighted approach:

  1. Question Weight Calculation:
  • Each question has a base weight of 1
  • Questions with required attachments get additional weight
  • Questions with conditional sub-questions have increased weight
  • Required questions are prioritized over optional ones
  1. Progress Detail Storage:
type QuestionnaireProgressDetail = Array<{
  questionIndex: number;
  isCompleted: boolean;
}>;
 
type QuestionnaireProgressState = {
  progress: number; // Percentage (0-100)
  count: number; // Completed questions count
  total: number; // Total questions count
  progressDetail: QuestionnaireProgressDetail;
  flagCount: number; // Total flags count
  flagColors: Array<{ color: string; count: number }>; // Flag breakdown
};
  1. Optimization Techniques:
  • Only recalculate affected questions when possible
  • Caching of intermediate results
  • Memoization of complex calculations

2.5.2 Progress UI Components

The progress is visualized through multiple UI components:

  1. Top Progress Bar:
  • Horizontal bar showing overall completion percentage
  • Color coding to indicate completion status:
  • Red: <50% complete
  • Yellow: 50-80% complete
  • Green: >80% complete
  • Animated transitions when progress changes
  1. Summary Statistics:
  • Questions answered: X/Y (with percentage)
  • Required questions completed: X/Y
  • Flags raised: X (breakdown by color)
  • Attachments added: X (breakdown by type)
  1. Question-Level Indicators:
  • Checkmark for completed questions
  • Warning icon for incomplete required questions
  • Badge showing conditional questions status
  1. Navigation Assists:
  • “Jump to next incomplete” functionality
  • Filtering options to show only incomplete questions
  • Section completion indicators

Progress tracking is tightly integrated with the form state and validation system, ensuring that the displayed progress accurately reflects the audit’s completion status in real-time.

2.6 Review and Submission

Before finalization, the audit undergoes a comprehensive review:

flowchart TD
    A[Open Summary Screen] --> B{Complete?}
    B -->|Incomplete Items| C[Highlight Incomplete]
    C --> D[Navigate to Incomplete]
    D --> A

    B -->|All Complete| E[Review Responses]
    E --> F[Review Attachments]
    F --> G[Review Flags/Priorities]
    G --> H[Submit Audit]
    H --> I[Generate Report]
    I --> J[Notify Stakeholders]

During review:

  • Completion percentage is verified (ideally 100%)
  • Incomplete questions are highlighted for completion
  • All attachments are verified
  • Flags and priorities are confirmed
  • Summary statistics are compiled
  • Final submission processes the audit for reporting

2.6.1 Summary Screen Features

The summary screen provides comprehensive overview and finalization options:

graph TD
    A[Summary Screen] --> B[Completion Status]
    A --> C[Question List]
    A --> D[Flag Summary]
    A --> E[Attachment Summary]
    A --> F[Action Buttons]

    B --> B1[Progress Bar]
    B --> B2[Percentage Complete]
    B --> B3[Required vs Optional Status]

    C --> C1[Sectioned Question List]
    C --> C2[Completion Status Indicators]
    C --> C3[Quick Navigation Links]

    D --> D1[Red Flags Count]
    D --> D2[Yellow Flags Count]
    D --> D3[Green Flags Count]

    E --> E1[Photos Count]
    E --> E2[Videos Count]
    E --> E3[Documents Count]

    F --> F1[Submit Button]
    F --> F2[Return to Questionnaire]
    F --> F3[Save Draft]

Key summary screen functionality:

  1. Question Navigation: Users can tap on any question to navigate directly to it for editing
  2. Completion Validation:
  • Visual indicators show completion status of each question
  • Required but incomplete questions are highlighted in red
  • Warning shown if attempting to submit with incomplete required questions
  1. Flag Analysis:
  • Breakdown of flags by color and priority
  • Quick navigation to flagged items
  • Option to add notes to flagged items
  1. Attachment Review:
  • List of all attachments grouped by question
  • Thumbnail previews of photos and videos
  • File size and type information for documents
  • Option to add, replace, or delete attachments
  1. Final Actions:
  • Submit: Complete the audit and generate report
  • Save Draft: Store current state without finalizing
  • Sync: Synchronize data and generate JSON export (feature flag controlled)

2.6.2 JSON Data Export

When the EXPORT_JSON_REPORT_ON_SUBMIT_SYNC feature flag is enabled, the sync process includes automatic JSON export:

sequenceDiagram
    participant User
    participant SubmitController as SubmitQuestionnaireController
    participant ExportUseCase as AuditDataExportUseCase
    participant FileSystem
    participant Server

    User->>SubmitController: Click Submit
    SubmitController->>SubmitController: Validate Report
    SubmitController->>SubmitController: Check Feature Flag

    alt Feature Flag Enabled
        SubmitController->>ExportUseCase: exportAuditData(reportData)
        ExportUseCase->>FileSystem: Save JSON to Device
        FileSystem-->>SubmitController: Export Result
        Note over SubmitController: Log export result (non-blocking)
    end

    SubmitController->>Server: Upload Report
    Server-->>SubmitController: Submission Confirmed
    SubmitController-->>User: Navigate to Payoff

Export Features:

  • Automatic Export: JSON file automatically generated during sync
  • Complete Data: Exports the full ReportForm object with all questions and answers
  • Non-Blocking: Export failures don’t prevent submission
  • Platform Support: Android SAF, iOS sharing, Web download
  • File Naming: report_[reportID]_[timestamp].json

Exported Data Structure:

{
  "questions": [...],
  "sections": [...],
  "status": "complete",
  "site": "site_id",
  "auditor": "user_id",
  "datetimeSubmitted": "2025-01-19T10:30:00Z",
  "questionnaire": "questionnaire_id",
  "grade": "A",
  "maxScore": 100,
  // ... complete report data
}

Upon submission:

  1. A final validation check is performed
  2. Confirmation dialog verifies user intent
  3. All data is synchronized to the server
  4. JSON export initiated during sync (if feature flag enabled)
  5. Report generation begins in the background
  6. User is directed to the payoff screen
  7. Notifications are sent to stakeholders
  8. Audit is marked as complete in the database

3. Architecture Overview

The Single Audit feature follows a modular architecture pattern:

graph TD
    A[Single Audit Entry Point] --> B[Questionnaire Screen]
    B --> C[Questionnaire Component]
    C --> D[Questionnaire Form]
    D --> E[Question Container]
    E --> F[Individual Questions]

    B --- G[Controllers]
    G --> H[Screen Controller]
    G --> I[Navigation Controller]
    G --> J[Progress Controller]
    G --> K[Attachment Controllers]

    B --- L[State Management]
    L --> M[Form State]
    L --> N[Navigation State]
    L --> O[Progress State]
    L --> P[Attachment State]

3.1 Component Structure

Key components in the hierarchy:

3.2 State Management

The Single Audit uses Jotai for state management with several key atoms:

graph TD
    A[State Atoms] --> B[Form State]
    A --> C[UI State]
    A --> D[Navigation State]

    B --> E[questionnaireFormAtom]

    C --> F[isRecommendationOpenAtom]
    C --> G[addedRemediesAtom]

    D --> H[activeQuestionIndexAtom]

    I[Progress State] --> J[questionnaireProgressAtom]

These atoms provide:

  • Reactive updates to the UI
  • Easy state sharing across components
  • Optimized rendering through selective updates

3.3 Controllers

Controllers handle business logic and data management:

4. Core Flows

4.1 Navigation Flow

sequenceDiagram
    participant User
    participant UI as User Interface
    participant Nav as Navigation Controller
    participant State as State Management
    participant Form as Form State

    User->>UI: Press Next Button
    UI->>Nav: onPressNext()
    Nav->>State: Check if Last Question

    alt Last Question
    State-->>Nav: Yes, Last Question
    Nav->>State: Save Form State
    Nav->>UI: Navigate to Summary
    else Not Last Question
    State-->>Nav: Not Last Question
    Nav->>State: Increment Question Index
    State->>UI: Render Next Question
    end

    User->>UI: Press Previous Button
    UI->>Nav: onPressPrevious()
    Nav->>State: Check if First Question

    alt First Question
    State-->>Nav: Yes, First Question
    Nav->>UI: Stay on First Question
    else Not First Question
    State-->>Nav: Not First Question
    Nav->>State: Decrement Question Index
    State->>UI: Render Previous Question
    end

    User->>UI: Press Clear Button
    UI->>Nav: onPressClear()
    Nav->>Form: Reset Current Question Data
    Form->>State: Update Form State
    State->>UI: Render Empty Question

The navigation flow ensures auditors can move through questions in a logical sequence, clearing responses when needed, and reviewing their work before submission.

4.2 Form State Management

The questionnaire uses React Hook Form for form state management:

graph TD
    A[Initialize Form] --> B[FormProvider]
    B --> C[Component Tree]
    C --> D[Question Components]
    D --> E[Input Fields]

    E --> F[onChange Events]
    F --> G[Form State Updates]
    G --> H[Validation]
    H --> I[Error States]

    G --> J[Progress Calculation]
    J --> K[Progress Updates]

    G --> L[Debounced Cache]
    L --> M[Report Service]
    M --> N[Server Sync]

Form values are structured hierarchically:

  • Top level: Report metadata (ID, type, progress)
  • Questions array: Contains all question data
  • Each question: Type, content, answer, attachments, etc.
  • Conditional questions: Nested within parent questions

4.3 Attachment Handling

Attachments (photos, videos, documents) follow this workflow:

sequenceDiagram
    participant User
    participant Question as Question UI
    participant Controller as Attachment Controller
    participant Storage as Local Storage
    participant API as Server API

    User->>Question: Add Attachment
    Question->>Controller: Request Camera/Gallery

    alt Camera
    Controller->>User: Open Camera
    User->>Controller: Capture Media
    else Gallery
    Controller->>User: Open Gallery
    User->>Controller: Select Media
    end

    Controller->>Storage: Save to Local Path
    Controller->>Question: Update UI with Attachment

    alt Online Mode
    Controller->>API: Upload Attachment
    API-->>Controller: Return Attachment ID
    Controller->>Storage: Update with Server ID
    else Offline Mode
    Controller->>Storage: Queue for Upload
    end

    User->>Question: Remove Attachment
    Question->>Controller: Delete Request
    Controller->>Storage: Remove Local File
    Controller->>API: Delete from Server (if online)

When internet connectivity resumes after offline usage:

  1. Queued attachments are automatically uploaded
  2. Local paths are updated with server identifiers
  3. Sync status indicators show completion

4.3.1 Attachment Error Handling

When dealing with attachments, various errors can occur, which are handled systematically:

flowchart TD
    A[Attachment Operation] --> B{Permission Check}
    B -->|Granted| C[Prepare Media Operation]
    B -->|Denied| D[Display Permission Dialog]

    D --> E{User Response}
    E -->|Grant Permission| B
    E -->|Deny Permission| F[Show Error Message]

    C --> G{Operation Type}
    G -->|Capture Photo| H[Camera Interface]
    G -->|Record Video| I[Video Interface]
    G -->|Select Document| J[Document Picker]

    H --> K{Capture Result}
    I --> K
    J --> K

    K -->|Success| L[Process Media]
    K -->|Failure| M[Handle Specific Error]
    K -->|User Cancel| N[Return to Question]

    M --> M1[Show Error Message]
    M --> M2[Log Error Details]
    M --> M3[Offer Retry Option]

    L --> O{Storage Space Check}
    O -->|Sufficient| P[Save to Local Storage]
    O -->|Insufficient| Q[Show Storage Error]

    P --> R{Upload Check}
    R -->|Online| S[Upload to Server]
    R -->|Offline| T[Queue for Later Upload]

    S --> U{Upload Result}
    U -->|Success| V[Update Attachment Metadata]
    U -->|Failure| W[Retry Logic]

    W --> W1{Retry Count}
    W1 -->|< Max Retries| X[Wait and Retry]
    W1 -->|>= Max Retries| Y[Add to Error List]

    X --> S
    Y --> Y1[Show Sync Error]
    Y --> Y2[Provide Manual Retry Option]

4.3.2 Attachment Storage

Attachments are stored in a structured way to ensure efficient access and synchronization:

  1. Local Storage Structure:
  • Directory created for each audit
  • Subdirectories for questions
  • Files named with unique identifiers
  • Example path: /auditData/{reportId}/q{questionIndex}/{timestamp}_{fileType}.{extension}
  1. Metadata Storage:
  • Each attachment has metadata stored in the form state
  • Metadata includes:
  • Local URI
  • Server ID (when uploaded)
  • Creation timestamp
  • File size and dimensions
  • Upload status
  • Sync status
  1. Storage Limitations:
  • Each question can specify maximum counts for different attachment types
  • System enforces size limits for different media types:
  • Photos: 10MB per image
  • Videos: 100MB total, 30 seconds maximum duration
  • Documents: 25MB per file
  1. Deletion Handling:
  • When an attachment is deleted:
  • Local file is removed immediately
  • Server delete request is queued if offline
  • Form state is updated to remove reference
  • Progress is recalculated

4.4 Online/Offline Mode

The Single Audit supports both online and offline operation:

graph TD
    A[App Start] --> B{Check Connectivity}

    B -->|Online| C[Standard Operation]
    B -->|Offline| D[Offline Mode]

    C --> E[Real-time Sync]
    C --> F[Direct Attachment Upload]
    C --> G[Live Data Fetching]

    D --> H[Local Storage]
    D --> I[Sync Queue]
    D --> J[Cached Data]

    H --> K{Connectivity Restored?}
    I --> K
    J --> K

    K -->|Yes| L[Background Sync]
    K -->|No| M[Continue Offline]

    L --> N[Upload Queued Data]
    L --> O[Fetch Updates]
    L --> P[Resolve Conflicts]

During offline operation:

  • All data is stored locally first
  • UI indicates offline status
  • Attachments are stored locally
  • Progress is tracked normally
  • When connectivity is restored, data is synchronized

4.4.1 Synchronization Mechanism

The application implements a robust synchronization system to handle offline operations:

sequenceDiagram
    participant App
    participant Cache as Local Cache
    participant SyncQueue as Sync Queue
    participant API as Backend API
    participant Conflict as Conflict Resolution

    Note over App,Cache: Offline Mode
    App->>Cache: Save Question Answer
    App->>SyncQueue: Queue Change for Sync
    App->>Cache: Store Attachment Locally

    Note over App,API: Connection Restored
    App->>API: Check Connection
    App->>SyncQueue: Process Queued Changes

    loop For Each Queued Item
    SyncQueue->>API: Send Update

    alt Successful Sync
    API-->>SyncQueue: Confirm Update
    SyncQueue->>Cache: Clear Item from Queue
    else Sync Conflict
    API-->>SyncQueue: Return Conflict
    SyncQueue->>Conflict: Resolve Conflict
    Conflict->>API: Send Resolved Data
    end
    end

    App->>Cache: Update Local Cache with Server Data

Key synchronization features:

  1. Change Tracking: Every modification is tracked with timestamps and change types
  2. Queued Operations: Changes are stored in a FIFO queue during offline mode
  3. Batch Processing: Multiple changes are processed in batches when connection is restored
  4. Conflict Resolution:
  • Last-write-wins for simple conflicts
  • Merge strategy for non-overlapping changes
  • User intervention for critical conflicts
  1. Attachment Handling:
  • Photos, videos, and documents are stored locally with metadata
  • Background upload of attachments when connectivity is restored
  • Progress tracking for uploads
  • Retry mechanism for failed uploads

The sync status is clearly indicated in the UI:

  • Sync indicator in the header shows online/offline status
  • Individual questions show sync status (synced, pending, conflict)
  • Attachments display upload status and progress
  • Toast notifications for sync completion and errors

5. Data Models

5.1 Question Model

The core building block is the Question type:

interface Question {
  content: string;
  type: QuestionTypes;
  answer: string | number;
  answers: string[];
  comment: string;
  photos: AttachmentMetadata[];
  videos: AttachmentMetadata[];
  documents: AttachmentMetadata[];
  category?: string;
  reference?: string;
  answerRequired?: boolean;
  commentRequired?: boolean;
  photoMinimum?: number;
  videoLimit?: number;
  documentMinimum?: number;
  isConditional?: boolean;
  conditionalQuestion?: ConditionalQuestion;
  redFlag?: boolean;
  flagColor?: string;
  priority?: string;
  uom?: string;
}

5.2 Form Structure

The QuestionnaireFormValues mirrors the ReportForm entity:

type ReportForm = {
  id: string;
  siteID: string;
  auditType: "single" | "team";
  status: ReportStatus;
  totalQuestions: number;
  totalAnswered: number;
  createdAt: string;
  updatedAt: string;
  completedAt?: string;
  questions: Question[];
  questionnaireProgress?: number;
  questionnaireProgressDetail?: Array<{
    questionIndex: number;
    isCompleted: boolean;
  }>;
  questionnaireFlags?: {
    flagCount: number;
    flagColors: Array<{ color: string; count: number }>;
  };
};

5.3 Attachment Types

Media attachments use specialized metadata:

type AttachmentMetadata = {
  id: string;
  uri: string;
  name: string;
  type: "image" | "video" | "document";
  size?: number;
  width?: number;
  height?: number;
  duration?: number;
  createdAt: string;
  status: "pending" | "uploading" | "uploaded" | "failed";
  progress?: number;
  error?: string;
};

6. Implementation Details

6.1 Conditional Questions

The questionnaire supports conditional questions that appear based on answers to parent questions:

graph TD
    A[Parent Question] --> B{Answer Selected}
    B -->|Option A| C[Show Conditional Questions Set A]
    B -->|Option B| D[Show Conditional Questions Set B]
    B -->|Other| E[No Conditional Questions]

Implementation details:

  • Parent questions have an isConditional flag
  • conditionalQuestion.conditions object maps answers to question arrays
  • Conditional rendering in QuestionnaireQuestionContainer
  • Progress calculation includes conditional questions

6.2 Validation Logic

The questionnaire implements several validation rules:

flowchart TD
    A[Question Validation] --> B{Required Answer?}
    B -->|Yes| C{Answer Provided?}
    B -->|No| D[Mark as Valid]

    C -->|Yes| E{Attachment Requirements}
    C -->|No| F[Mark as Invalid]

    E -->|Met| G{Comment Requirements}
    E -->|Not Met| H[Mark as Invalid]

Key validation aspects:

  • Required answers based on answerRequired flag
  • Required attachments based on minimum counts
  • Comment requirements based on question type
  • Validation integrated with progress tracking

6.2.1 Question Type-Specific Validation

Each question type has specific validation rules to ensure data integrity:

Question TypeValidation LogicRequired Elements
BINARYMust select “Yes” or “No”Single selection
BINARY_WITH_RED_FLAGMust select option and appropriate flag if answer is “No”Selection and flag selection
SCOREValue must be within defined min/max rangeNumeric value
MULTIPLE_CHOICEAt least one option must be selected (if required)One or more selections
CHECKLISTNo validation unless marked as requiredSelections as specified
OPENText length must be between min/max if specifiedText input
NUMBERValue must be numeric and within range if specifiedNumeric value within bounds
DATE_TIMEMust be a valid date/time and within allowed range if specifiedValid date and time

6.2.2 Validation Code Implementation

The validation logic is implemented in the progress calculation and consists of multiple checks:

// Simplified validation logic (pseudo-code)
function isQuestionComplete(question: Question): boolean {
  // Check for required answer
  if (question.answerRequired && !hasValidAnswer(question)) {
    return false;
  }
 
  // Check for required attachments
  if (!hasRequiredAttachments(question)) {
    return false;
  }
 
  // Check for required comments
  if (question.commentRequired && !question.comment) {
    return false;
  }
 
  // Check for conditional questions
  if (question.isConditional && hasActiveConditionals(question)) {
    const conditionals = getActiveConditionalQuestions(question);
    return conditionals.every((q) => isQuestionComplete(q));
  }
 
  return true;
}
 
function hasValidAnswer(question: Question): boolean {
  switch (question.type) {
    case "BINARY":
    case "BINARY_WITH_RED_FLAG":
      return question.answer === "yes" || question.answer === "no";
    case "SCORE":
      return (
        typeof question.answer === "number" &&
        question.answer >= question.minValue &&
        question.answer <= question.maxValue
      );
    case "MULTIPLE_CHOICE":
      return Array.isArray(question.answers) && question.answers.length > 0;
    case "CHECKLIST":
      return (
        !question.answerRequired ||
        (Array.isArray(question.answers) && question.answers.length > 0)
      );
    case "OPEN":
      return (
        !!question.answer &&
        (!question.minLength || question.answer.length >= question.minLength) &&
        (!question.maxLength || question.answer.length <= question.maxLength)
      );
    case "NUMBER":
      return (
        typeof question.answer === "number" &&
        (!question.minValue || question.answer >= question.minValue) &&
        (!question.maxValue || question.answer <= question.maxValue)
      );
    default:
      return !!question.answer;
  }
}
 
function hasRequiredAttachments(question: Question): boolean {
  const { photoMinimum, videoLimit, documentMinimum } = question;
 
  if (
    photoMinimum &&
    (!question.photos || question.photos.length < photoMinimum)
  ) {
    return false;
  }
 
  if (
    videoLimit &&
    videoLimit > 0 &&
    (!question.videos || question.videos.length < videoLimit)
  ) {
    return false;
  }
 
  if (
    documentMinimum &&
    (!question.documents || question.documents.length < documentMinimum)
  ) {
    return false;
  }
 
  return true;
}

6.2.3 User Feedback

When validation fails, the system provides immediate feedback:

  • Visual indicators highlight incomplete or invalid fields
  • Error messages explain specific requirements
  • The “Next” button may be disabled until validation passes for critical fields
  • Warning prompts appear when trying to proceed with incomplete required fields
  • Progress indicators reflect the validation status

6.3 Flag and Priority Handling

Questions can be flagged with different colors to indicate status:

pie title Audit Flag Distribution
"Green Flags" : 42
"Yellow Flags" : 28
"Red Flags" : 15

Flags are used to:

  • Highlight critical safety issues (red flags)
  • Indicate potential compliance risks (yellow flags)
  • Mark items meeting or exceeding standards (green flags)

Priorities can be assigned as:

  • Critical (immediate action required)
  • High (action needed within 24 hours)
  • Medium (action needed within 7 days)
  • Low (action needed within 30 days)

7. API Reference

The Single Audit interacts with several endpoints:

API EndpointPurposeController
GET /api/[questionnaire](../../Questionnaires/QuestionnairesOverview.md)/{firebaseReportID}Fetch questionnaire datauseQuestionnaireData()
PATCH /api/[report](../../Reports/ReportsOverview.md)/{firebaseReportID}Update report datareportService.updateCache()
GET /api/organization/prioritiesGet priority settingsuseOrganizationPrioritiesQuery()
GET /api/reference/{referenceId}Fetch reference materialReferenceViewer
POST /api/attachment/uploadUpload attachmentquestionnairePhotoController
GET /api/attachment/{attachmentId}Get attachmentquestionnaireDocumentController
GET /api/user/auditsGet user auditsuseAuditsQuery()
POST /api/[report](../../Reports/ReportsOverview.md)/createCreate new reportreportService.createReport()

8. File Path Reference

9. Questionnaire Routes

The questionnaire feature in the Audit-Lite application follows a specific navigation flow through various screens:

RoutePurposeScreen Component
/[questionnaire](../../Questionnaires/QuestionnairesOverview.md)Main questionnaire entry pointQuestionnaireScreen
/[questionnaire](../../Questionnaires/QuestionnairesOverview.md)/summaryReview and submit completed questionnaireQuestionnaireSummaryScreen
/[questionnaire](../../Questionnaires/QuestionnairesOverview.md)/reference-viewerView reference materials and documentationReferenceViewerScreen
/[questionnaire](../../Questionnaires/QuestionnairesOverview.md)/payoffPost-completion screen with next stepsPayoffScreen
/[questionnaire](../../Questionnaires/QuestionnairesOverview.md)/signatureSign and finalize completed auditSignatureScreen
/[questionnaire](../../Questionnaires/QuestionnairesOverview.md)/overviewOverview of entire questionnaireQuestionnaireOverviewScreen

Each route accepts query parameters that include:

  • siteID: The ID of the site being audited
  • firebaseReportID: The ID of the report in Firebase
  • auditType: Type of audit (‘single’ or ‘team’)
  • sectionIndex: Section index (only used in [team audits](../Team Audit/TeamAuditOverview.md))

10. Dependencies

The Single Audit implementation uses several key packages:

PackagePurpose
React Hook FormForm state management
JotaiAtomic state management
React NavigationScreen navigation
KeyboardAwareScrollViewKeyboard management
TanStack QueryData fetching and caching
LodashUtility functions (debounce, etc.)
Expo Camera/Image PickerMedia capture
Document PickerFile selection
BurntToast notifications
MMKVLocal storage