1. Overview

The File Repository module is a comprehensive file management system within the Nimbly Audit Lite application. It provides users with capabilities to upload, organize, share, and manage files in a cloud-based environment with folder hierarchies, filtering, and various file operations.

1.1 Key Features

  • File Organization: Hierarchical folder structure with navigation
  • File Operations: Upload, download, rename, delete, restore, share
  • View Modes: Grid and list views for file browsing
  • Filtering & Sorting: By file type, date, users, and custom sorting
  • Dashboard Analytics: Storage usage and file statistics
  • Trash Management: Soft delete with restoration capabilities
  • Sharing: User-based file and folder sharing
  • File Preview: In-app preview for supported file types

2. Architecture

The module follows a modular architecture pattern with clear separation of concerns:

graph TB
    subgraph "Screen Layer"
        A[Repository Index] --> B[Dashboard Screen]
        A --> C[Filter Options Screen]
        A --> D[File Preview Screen]
    end
    
    subgraph "Feature Layer"
        E[Repository Component] --> F[Components]
        E --> G[Controllers]
        E --> H[Modals]
        E --> I[Utils]
    end
    
    subgraph "Data Layer"
        G --> J[Query Hooks]
        G --> K[Data Hooks]
        J --> L[API Client]
    end
    
    A --> E
    B --> E
    C --> E
    D --> E

3. Screen Structure & Navigation

3.1 Main Screens

ScreenPathPurposeSource File
Repository Index/repositoryMain entry point with authenticationapps/expo/app/repository/index.tsx
Dashboard/repository/dashboardStorage analytics and usage statisticsapps/expo/app/repository/dashboard.tsx
Filter Options/repository/filter-optionAdvanced filtering interfaceapps/expo/app/repository/filter-option.tsx
File Preview/repository/file-previewIn-app file viewerapps/expo/app/repository/file-preview/index.tsx

3.2 Navigation Flow

graph LR
    A[Repository Index] --> B[Main Repository View]
    B --> CDashboard
    B --> D[Filter Options]
    B --> E[File Preview]
    B --> F[Folder Navigation]
    
    F --> F1[Nested Folders]
    F1 --> F2[Files]
    
    B --> G[Tab Navigation]
    G --> G1[My Files]
    G --> G2[Shared With Me]
    G --> G3[Recent]
    G --> G4[Starred]
    G --> G5[Trash]

3.3 Repository Tabs

The repository supports multiple tab views for different file collections:

enum RepositoryTabEnum {
    MY_FILES = 'myFiles',
    SHARED_WITH_ME = 'sharedWithMe',
    RECENT = 'recent',
    STARRED = 'starred',
    TRASH = 'trash',
    SEARCH = 'search',
    DASHBOARD = 'dashboard',
    FOLDER = 'folder',
}

Each tab provides a filtered view of the repository content based on specific criteria:

  • My Files: User’s personal files and folders
  • Shared With Me: Files shared by other users
  • Recent: Recently accessed or modified files
  • Starred: User’s bookmarked files
  • Trash: Soft-deleted files pending permanent deletion

4. Components

4.1 Core Components

ComponentPurposeKey FeaturesSource File
RepositoryHeaderMain navigation and search barSearch functionality, filter access, tab switchingrepository-header.tsx
RepositoryViewMain content display areaGrid/List view switching, virtualized scrolling, pull-to-refreshrepository-view.tsx
RepositoryFooterTab navigation footerQuick tab switching between My Files and Sharedrepository-footer.tsx
RepositorySubHeaderContextual headerBreadcrumb navigation, view mode toggle, select moderepository-sub-header.tsx

4.2 File Display Components

ComponentView TypeFeaturesSource File
RepositoryItemGridCardGrid/TileThumbnail preview, file status indicators, multi-selectrepository-item-grid-card.tsx
RepositoryItemListCardListDetailed file info, last modified, file size, ownerrepository-item-list-card.tsx
FileIconMapIcon mappingMIME type to icon mapping, file type detectionfile-icon-map.tsx

4.3 Support Components

ComponentPurposeFeaturesSource File
DashboardHeaderDashboard stats headerStorage usage, file count displaydashboard-header.tsx
ProgressBarUpload/Download progressVisual progress indicationprogress-bar.tsx
FileActionsBottomSheetContext menuFile operations menufile-actions-bottom-sheet.tsx
RepositoryFolderSelectorFolder navigationFolder hierarchy selectionrepository-folder-selector.tsx

4.4 Component Architecture

graph TD
    A[Repository Main] --> B[RepositoryHeader]
    A --> C[RepositoryView]
    A --> D[RepositoryFooter]
    A --> E[RepositoryModals]
    
    B --> B1[Search Component]
    B --> B2[Filter Button]
    B --> B3[SubHeader]
    
    C --> C1[VirtualList]
    C1 --> C2[GridCard]
    C1 --> C3[ListCard]
    
    C2 --> F[FileIconMap]
    C3 --> F
    
    D --> D1[Tab Buttons]
    
    E --> E1[Modal Components]

4.5 View Modes

The repository supports two view modes for file display:

  1. Grid View (Tile):
    • 2-column layout
    • Visual thumbnails
    • File type icons
    • Status indicators (starred, shared)
  2. List View:
    • Single column layout
    • Detailed file information
    • Last modified date
    • File size and owner details

5. Data Management

5.1 Core Hooks

HookPurposeKey FeaturesSource File
useRepositoryDataMain data orchestratorManages files/folders state, selection, view modesuse-repository-data.ts
useRepositoryFile operations handlerCRUD operations, sharing, starring, trash managementuse-repository.ts
useRepositoryUploadUpload managerChunked uploads, progress tracking, retry logicuse-repository-upload.ts
useRepositoryDownloadDownload handlerFile/folder downloads, bulk download supportuse-repository-download.ts

5.2 State Management Architecture

graph TD
    A[Jotai Atoms] --> B[Repository State]
    B --> C[Files State]
    B --> D[Folders State]
    B --> E[Selection State]
    B --> F[UI State]
    
    C --> C1[filesAtom]
    C --> C2[fileSectionsAtom]
    C --> C3[tempFilesAtom]
    
    D --> D1[foldersAtom]
    D --> D2[folderHierarchyAtom]
    
    E --> E1[selectedFileIdsAtom]
    E --> E2[selectedFilesAtom]
    E --> E3[totalSelectedItemsAtom]
    
    F --> F1[activeTabAtom]
    F --> F2[viewTypeAtom]
    F --> F3[sortByAtom]

5.3 Data Flow

  1. Query Management:

    • useRepositoryQuery fetches data based on current filters and tab
    • Supports pagination with infinite scroll
    • Caches data per tab/folder context
  2. State Updates:

    • Optimistic updates for immediate UI feedback
    • Batch operations for bulk actions
    • Section-based updates for date-grouped views
  3. File Operations Flow:

    sequenceDiagram
        User->>UI: Initiates action
        UI->>Hook: Calls operation method
        Hook->>API: Sends request
        Hook->>State: Optimistic update
        API-->>Hook: Response
        Hook->>State: Final update
        Hook->>Toast: Show success/error
    

5.4 Upload Process

The upload system uses chunked upload for large files:

  1. Initialization:

    • Creates temporary file placeholder
    • Generates unique upload ID
    • Shows in UI immediately
  2. Chunked Upload:

    • Files split into chunks
    • Progress tracked per chunk
    • Resumable on failure
  3. Completion:

    • Creates repository entry
    • Updates UI state
    • Removes temporary placeholder

5.5 Download Limitations

  • Maximum 30 items per download
  • Maximum 100MB total size
  • Folder downloads create zip files
  • Direct file links for single files

6. API Endpoints

6.1 Repository API Endpoints

EndpointMethodPurposeParametersSource File
/repository/itemsGETFetch paginated itemsQuery params, filters, paginationrepository-repository.ts
/repository/foldersGETGet folder list-repository-repository.ts
/repository/itemsPOSTCreate file/folderentityInfo, parentIDrepository-repository.ts
/repository/itemsPUTUpdate itemoperation, entityIDs, additional paramsrepository-repository.ts
/repository/uploadPOSTGet upload URLfileName, fileType, fileSizerepository-repository.ts
/repository/downloadPOSTDownload itemsentityIDsrepository-repository.ts
/repository/storageGETStorage usageorganizationIDrepository-repository.ts

6.2 Query Parameters

The repository query supports extensive filtering:

interface RepositoryQueryOptions {
    qSearch: string;        // Search term
    parentID: string;       // Folder ID for navigation
    limit: number;          // Items per page (default: 20)
    page: number;           // Current page
    sortBy: RepositorySortByOptionsEnum;
    sortType: SortDirection;
    list: RepositoryListEnum;
    
    // Filter options
    qFileType: string[];    // File type filter
    qUser: string[];        // User filter
    qLocation: string;      // Location filter
    qStartDate: string;     // Date range start
    qEndDate: string;       // Date range end
}

7. File Operations

7.1 Operation Types

The repository supports various file operations through a unified API:

enum RepositoryItemOperations {
    OPEN = 'open',
    RENAME = 'rename',
    STARRED = 'starred',
    REMOVE_STARRED = 'remove_starred',
    SHARE = 'share',
    MOVE_TO = 'move_to',
    TRASH = 'trash',
    RESTORE = 'restore',
    HARD_DELETE = 'hard_delete',
    EMPTY_TRASH = 'empty_trash',
}

7.2 Context-Aware Operations

Operations available depend on the current tab and item state:

TabAvailable Operations
My FilesOpen, Download, Rename, Star, Share, Move, Trash
Shared With MeOpen, Download, Star, Share (limited)
RecentOpen, Download, Rename, Star, Share
StarredOpen, Download, Rename, Unstar, Share, Move, Trash
TrashRestore, Delete Forever

7.3 Modal System

Each operation has a dedicated modal for user interaction:

ModalPurposeFeatures
NewFolderModalCreate foldersName validation, parent folder context
RenameModalRename itemsPreserves extension, validates uniqueness
ShareModalShare with usersUser search, permission management
TrashModalMove to trashConfirmation, bulk operations
DeleteForeverModalPermanent deletionDouble confirmation
RestoreModalRestore from trashOriginal location preservation
StarModalStar/unstar itemsQuick access management

7.4 Bulk Operations

The system supports bulk operations for efficiency:

  1. Selection Mode:

    • Long press to enter
    • Maximum 30 items
    • Visual feedback
  2. Bulk Actions:

    • Star/Unstar multiple
    • Move to trash
    • Share with users
    • Download as zip

8. Package Dependencies

8.1 Core Dependencies

PackagePurposeUsage in Repository Module
reactCore React libraryComponent structure, hooks
react-nativeMobile frameworkNative components, platform APIs
expo-routerNavigationScreen routing, navigation stack
jotaiState managementGlobal state atoms, reactive updates
@tanstack/react-queryData fetchingAPI queries, caching, pagination

8.2 UI Libraries

PackagePurposeUsage in Repository Module
@my/uiCustom UI componentsButtons, modals, layouts, forms
@tamagui/*UI frameworkIcons, styled components, themes
@expo/vector-iconsIcon libraryMaterialCommunityIcons, FontAwesome5

8.3 Utility Libraries

PackagePurposeUsage in Repository Module
dayjsDate manipulationDate formatting, relative time
lodashUtility functionscloneDeep for state immutability
uuidUnique ID generationUpload session IDs
query-stringURL query parsingAPI query parameter formatting

8.4 Expo SDK

PackagePurposeUsage in Repository Module
expo-file-systemFile system accessFile downloads, content URIs
expo-intent-launcherIntent handlingOpening files on Android
expo-document-pickerFile selectionDocument picker integration

8.5 Internal Packages

PackagePurposeUsage in Repository Module
@nimbly-technologies/nimbly-commonShared types/enumsTypeScript interfaces, enumerations
app/shared/controller/*Shared controllersAuthentication, localization, routing
app/shared/state/*Shared atomsRepository state management
app/shared/domain/*Domain logicRepository usecase layer

9. User Flows

9.1 File Upload Flow

flowchart TD
    A[User selects files] --> B[Document Picker]
    B --> C{File validation}
    C -->|Valid| D[Create temp placeholder]
    C -->|Invalid| E[Show error]
    D --> F[Generate upload ID]
    F --> G[Request signed URL]
    G --> H[Chunked upload]
    H --> I{Upload progress}
    I -->|In progress| J[Update UI progress]
    I -->|Failed| K[Retry option]
    I -->|Success| L[Create repository entry]
    J --> I
    K --> H
    L --> M[Update UI state]
    M --> N[Show success toast]

9.2 Folder Navigation Flow

flowchart LR
    A[Root folder] --> B{User action}
    B -->|Tap folder| C[Update hierarchy]
    B -->|Breadcrumb| D[Navigate to parent]
    C --> E[Fetch folder contents]
    D --> F[Pop hierarchy levels]
    E --> G[Update file list]
    F --> H[Fetch parent contents]
    G --> I[Display contents]
    H --> I
    I --> J{View type}
    J -->|Grid| K[Show grid view]
    J -->|List| L[Show list view]

9.3 File Sharing Flow

sequenceDiagram
    participant User
    participant UI
    participant ShareModal
    participant API
    participant State
    
    User->>UI: Long press file
    UI->>UI: Enter selection mode
    User->>UI: Select files
    User->>UI: Tap share button
    UI->>ShareModal: Open modal
    ShareModal->>User: Show user list
    User->>ShareModal: Select users
    User->>ShareModal: Confirm share
    ShareModal->>API: Send share request
    API-->>ShareModal: Success response
    ShareModal->>State: Update file metadata
    ShareModal->>UI: Close modal
    UI->>User: Show success toast

9.4 Search and Filter Flow

flowchart TD
    A[User input] --> B{Input type}
    B -->|Search query| C[Debounce 500ms]
    B -->|Filter option| D[Open filter modal]
    C --> E[Update search atom]
    D --> F{Filter type}
    F -->|File type| G[Select file types]
    F -->|Date range| H[Select dates]
    F -->|Users| I[Select users]
    E --> J[Trigger query]
    G --> K[Update filter atom]
    H --> K
    I --> K
    K --> J
    J --> L[Fetch filtered data]
    L --> M[Update UI]

9.5 Trash Management Flow

stateDiagram-v2
    [*] --> Active: File created
    Active --> Trashed: Move to trash
    Trashed --> Active: Restore
    Trashed --> Deleted: Delete forever
    Deleted --> [*]
    
    note right of Trashed
        30-day retention
        Bulk operations supported
    end note
    
    note right of Active
        Can be starred
        Can be shared
        Can be moved
    end note

10. State Management

10.1 Atom Structure

The repository module uses Jotai atoms for state management with the following hierarchy:

graph TD
    A[Repository State] --> B[UI State]
    A --> C[Data State]
    A --> D[Operation State]
    
    B --> B1[activeTabAtom]
    B --> B2[viewTypeAtom]
    B --> B3[sortByAtom]
    B --> B4[isSelectModeAtom]
    
    C --> C1[filesAtom]
    C --> C2[foldersAtom]
    C --> C3[fileSectionsAtom]
    C --> C4[selectedFileIdsAtom]
    
    D --> D1[Modal visibility atoms]
    D --> D2[Loading states]
    D --> D3[Error states]

10.2 State Update Patterns

  1. Optimistic Updates: UI updates immediately before API confirmation
  2. Batch Updates: Multiple items updated in single operation
  3. Section Updates: Date-grouped views maintain section integrity
  4. Hierarchical Updates: Folder navigation maintains breadcrumb state

11. Security & Permissions

11.1 Access Control

  1. Authentication:

    • AuthGuard wrapper on repository index
    • Token-based API authentication
    • Session management
  2. File Permissions:

    • Owner-based access control
    • Shared user permissions
    • Read-only for shared files
  3. Operation Restrictions:

    • Cannot delete shared files
    • Cannot rename shared files
    • Limited operations in trash

11.2 Data Security

  1. Signed URLs:

    • Temporary access tokens
    • Expiring download links
    • Secure upload sessions
  2. File Validation:

    • MIME type verification
    • File size limits (100MB)
    • Extension validation

12. Performance Optimizations

12.1 Virtualization

  1. VirtualList Implementation:

    • Efficient rendering of large lists
    • Dynamic item height calculation
    • Recycled view components
  2. Pagination Strategy:

    • 20 items per page default
    • Infinite scroll with React Query
    • Cached page results

12.2 State Optimization

  1. Debounced Search:

    • 500ms debounce on search input
    • Prevents excessive API calls
    • Smooth user experience
  2. Memoization:

    • useMemo for expensive computations
    • Cached file list transformations
    • Optimized re-renders

12.3 Network Optimization

  1. Chunked Uploads:

    • Large file splitting
    • Parallel chunk uploads
    • Resume on failure
  2. Query Caching:

    • React Query cache management
    • Stale-while-revalidate strategy
    • Background refetching

13. Error Handling

13.1 Upload Errors

  1. Retry Mechanism:

    • Automatic retry for network failures
    • Manual retry option in UI
    • Progress preservation
  2. Error States:

    • Visual error indicators
    • Detailed error messages
    • Recovery actions

13.2 API Error Handling

  1. Toast Notifications:

    • User-friendly error messages
    • Haptic feedback on errors
    • Action suggestions
  2. Fallback States:

    • Empty state components
    • Loading placeholders
    • Offline indicators

14. Testing Considerations

14.1 Component Testing

  • Each component has corresponding .test.tsx file
  • UI interaction testing
  • State management testing
  • Mock API responses

14.2 Integration Points

  1. API Mocking:

    • Mock repository usecase
    • Simulated network conditions
    • Error scenario testing
  2. State Testing:

    • Atom value assertions
    • State transition testing
    • Side effect validation
  3. Advanced Search:

    • Full-text search
    • OCR for images
    • Content indexing
  4. Collaboration:

    • Real-time updates
    • Comments on files
    • Version history
  5. Offline Support:

    • Local file caching
    • Offline queue for operations
    • Sync on reconnection
  6. Image Optimization:

    • Thumbnail generation
    • Progressive loading
    • Format optimization
  7. Batch Operations:

    • Bulk upload optimization
    • Parallel processing
    • Queue management

15. Troubleshooting

15.1 Common Issues

  1. Upload Failures:

    • Check network connectivity
    • Verify file size limits
    • Validate file types
  2. Performance Issues:

    • Clear app cache
    • Check storage space
    • Update to latest version
  3. Sync Problems:

    • Pull to refresh
    • Check permissions
    • Verify authentication

15.2 Debug Information

  1. Logging:

    • Console logs for development
    • Error tracking integration
    • Performance metrics
  2. Developer Tools:

    • React DevTools integration
    • Network inspector
    • State debugging with Jotai DevTools

16. Dashboard Module

16.1 Overview

The dashboard provides comprehensive storage analytics and usage statistics for the organization. It displays storage allocation, user-wise consumption, and visual representations of data distribution.

16.2 Dashboard Features

  1. Storage Overview:

    • Total storage allocation
    • Used vs available storage
    • Visual progress bar
    • Percentage breakdown
  2. Category Breakdown:

    • Documents storage
    • Photos storage
    • Videos storage
    • LMS content storage
    • Trash storage
  3. User Analytics:

    • Per-user storage consumption
    • Sortable user list
    • Storage quota tracking
    • Usage trends

16.3 Dashboard Implementation

// Dashboard data structure
interface DashboardData {
    totalAllowedStorageGB: number;
    totalUsedStorageGB: number;
    allocationPerEntity: {
        documents: number;
        photos: number;
        videos: number;
        LMS: number;
        trash: number;
    };
    userStorageList: Array<{
        displayName: string;
        usedStorageGB: number;
    }>;
}

16.4 Visual Components

  1. Progress Bar:

    • Multi-segment progress indicator
    • Color-coded categories
    • Responsive sizing
    • Smooth animations
  2. Storage Cards:

    • Category icons
    • Size formatting (MB/GB)
    • Color indicators
    • Click interactions

17. Filter System

17.1 Filter Architecture

The filter system provides comprehensive file filtering capabilities with multiple criteria support.

17.2 Available Filters

  1. File Type Filter:

    enum FileTypeFilter {
        IMAGE = 'image',
        VIDEO = 'video',
        DOCUMENT = 'document',
        SPREADSHEET = 'spreadsheet',
        PRESENTATION = 'presentation',
        PDF = 'pdf',
        ARCHIVE = 'archive'
    }
  2. User Filter:

    • Multi-select user list
    • Search within users
    • Show files shared by selected users
    • Owner-based filtering
  3. Date Range Filter:

    • Start date selector
    • End date selector
    • Preset ranges (Today, This Week, This Month)
    • Custom date selection
  4. Sort Options:

    enum SortOptions {
        NAME = 'name',
        LAST_MODIFIED = 'lastModified',
        SIZE = 'size',
        SHARED_DATE = 'sharedDate',
        OWNER = 'owner'
    }

17.3 Filter State Management

flowchart TD
    A[Filter Modal] --> B[Local State]
    B --> C{User Action}
    C -->|Apply| D[Update Atoms]
    C -->|Reset| E[Clear Filters]
    D --> F[Trigger Query]
    E --> G[Default Values]
    F --> H[Fetch Filtered Data]
    G --> H

17.4 Filter Persistence

  1. Session Persistence:

    • Filters maintained during session
    • Tab-specific filter states
    • Clear on logout
  2. Default Filters:

    • No filters on initial load
    • Tab-specific defaults
    • Configurable presets

18. File Type Detection

18.1 MIME Type Mapping

The system uses comprehensive MIME type detection for accurate file categorization:

const fileMimeType = {
    [FileTypeEnum.IMAGE]: [
        'image/jpeg', 'image/png', 'image/gif', 
        'image/webp', 'image/svg+xml', 'image/bmp'
    ],
    [FileTypeEnum.VIDEO]: [
        'video/mp4', 'video/quicktime', 'video/x-msvideo',
        'video/x-ms-wmv', 'video/webm'
    ],
    [FileTypeEnum.DOCUMENT]: [
        'application/msword', 
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        'text/plain', 'text/markdown'
    ],
    [FileTypeEnum.SPREADSHEET]: [
        'application/vnd.ms-excel',
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    ],
    [FileTypeEnum.PDF]: ['application/pdf'],
    [FileTypeEnum.ARCHIVE]: [
        'application/zip', 'application/x-rar-compressed',
        'application/x-7z-compressed', 'application/x-tar'
    ]
};

18.2 Icon Mapping

Dynamic icon selection based on file type:

const getFileIcon = (kind: Kind, mimeType: string) => {
    if (kind === Kind.FOLDER) {
        return <MaterialCommunityIcons name="folder" />;
    }
    
    // MIME-based icon selection
    const iconMap = {
        'application/pdf': 'file-pdf',
        'image/*': 'file-image',
        'video/*': 'file-video',
        'audio/*': 'file-music',
        // ... more mappings
    };
    
    return <MaterialCommunityIcons name={iconMap[mimeType] || 'file'} />;
};

19. Localization

19.1 Multi-language Support

The repository module fully supports internationalization:

  1. Translation Keys:

    LL.repository = {
        search: () => 'Search files',
        upload: () => 'Upload',
        download: () => 'Download',
        share: () => 'Share',
        delete: () => 'Delete',
        // ... more keys
    };
  2. Dynamic Labels:

    • Tab names
    • Operation labels
    • Error messages
    • Success notifications
  3. Date Formatting:

    • Locale-aware dates
    • Relative time (Today, Yesterday)
    • Custom formats

20. Accessibility

20.1 Keyboard Navigation

  1. Tab Order:

    • Logical tab sequence
    • Skip links
    • Focus indicators
  2. Shortcuts:

    • Cmd/Ctrl + U: Upload
    • Cmd/Ctrl + N: New folder
    • Delete: Move to trash
    • Escape: Close modals

20.2 Screen Reader Support

  1. ARIA Labels:

    • Descriptive button labels
    • File type announcements
    • Status updates
  2. Semantic Structure:

    • Proper heading hierarchy
    • List semantics
    • Form associations

21. Platform-Specific Features

21.1 iOS Specific

  1. File Handling:

    • Native share sheet
    • Quick Look integration
    • Files app integration
  2. Gestures:

    • Swipe actions
    • 3D Touch preview
    • Haptic feedback

21.2 Android Specific

  1. File Handling:

    • Intent system integration
    • Content URI handling
    • Storage Access Framework
  2. Material Design:

    • FAB for upload
    • Bottom sheets
    • Snackbar notifications

22. Configuration

22.1 Environment Variables

// Repository configuration
const REPO_CONFIG = {
    MAX_FILE_SIZE: 100 * 1024 * 1024, // 100MB
    MAX_SELECTION: 30,
    CHUNK_SIZE: 5 * 1024 * 1024, // 5MB
    PAGE_SIZE: 20,
    DEBOUNCE_DELAY: 500,
    CACHE_TIME: 5 * 60 * 1000, // 5 minutes
};

22.2 Feature Flags

const FEATURE_FLAGS = {
    ENABLE_BULK_UPLOAD: true,
    ENABLE_DRAG_DROP: false,
    ENABLE_PREVIEW: true,
    ENABLE_VERSIONING: false,
    ENABLE_COMMENTS: false,
};

23. Implementation Details

23.1 Component Lifecycle

23.1.1 Repository Initialization

The repository module follows a specific initialization sequence:

sequenceDiagram
    participant App
    participant AuthGuard
    participant Repository
    participant Query
    participant State
    
    App->>AuthGuard: Check authentication
    AuthGuard->>Repository: Initialize component
    Repository->>State: Set default atoms
    Repository->>Query: Fetch initial data
    Query->>State: Update with data
    Repository->>App: Render UI

23.1.2 Data Loading Strategy

  1. Initial Load:

    • Authentication check
    • Default state setup
    • First page fetch
    • UI render
  2. Lazy Loading:

    • Infinite scroll trigger
    • Next page fetch
    • Append to existing data
    • Update UI
  3. Refresh Strategy:

    • Pull-to-refresh gesture
    • Reset pagination
    • Fetch latest data
    • Replace existing data

23.2 File Upload Implementation

23.2.1 Chunked Upload Algorithm

class ChunkedFileUploader {
    private file: File;
    private chunkSize: number = 5 * 1024 * 1024; // 5MB
    private chunks: Blob[];
    private uploadedChunks: Set<number> = new Set();
    
    constructor(file: File, signedUrl: string) {
        this.file = file;
        this.chunks = this.createChunks();
    }
    
    private createChunks(): Blob[] {
        const chunks: Blob[] = [];
        let start = 0;
        
        while (start < this.file.size) {
            const end = Math.min(start + this.chunkSize, this.file.size);
            chunks.push(this.file.slice(start, end));
            start = end;
        }
        
        return chunks;
    }
    
    async uploadChunk(index: number): Promise<void> {
        if (this.uploadedChunks.has(index)) return;
        
        const chunk = this.chunks[index];
        const headers = {
            'Content-Range': `bytes ${index * this.chunkSize}-${(index + 1) * this.chunkSize - 1}/${this.file.size}`,
            'Content-Type': this.file.type
        };
        
        await fetch(this.signedUrl, {
            method: 'PUT',
            body: chunk,
            headers
        });
        
        this.uploadedChunks.add(index);
    }
    
    async startUpload(onProgress: (percent: number) => void): Promise<void> {
        const totalChunks = this.chunks.length;
        
        for (let i = 0; i < totalChunks; i++) {
            await this.uploadChunk(i);
            const progress = ((i + 1) / totalChunks) * 100;
            onProgress(progress);
        }
    }
}

23.2.2 Upload State Management

interface UploadState {
    fileId: string;
    fileName: string;
    progress: number;
    status: 'pending' | 'uploading' | 'success' | 'error';
    error?: string;
    retryCount: number;
}
 
const uploadQueue = new Map<string, UploadState>();
 
const processUploadQueue = async () => {
    for (const [fileId, state] of uploadQueue) {
        if (state.status === 'pending') {
            state.status = 'uploading';
            try {
                await uploadFile(state);
                state.status = 'success';
            } catch (error) {
                state.status = 'error';
                state.error = error.message;
                if (state.retryCount < 3) {
                    state.retryCount++;
                    state.status = 'pending';
                }
            }
        }
    }
};

23.3 Search Implementation

const useDebounceValue = <T>(value: T, delay: number): T => {
    const [debouncedValue, setDebouncedValue] = useState<T>(value);
    
    useEffect(() => {
        const handler = setTimeout(() => {
            setDebouncedValue(value);
        }, delay);
        
        return () => {
            clearTimeout(handler);
        };
    }, [value, delay]);
    
    return debouncedValue;
};
 
// Usage in search
const searchQuery = useDebounceValue(searchInput, 500);

23.3.2 Search Algorithm

const searchFiles = (query: string, files: RepositoryItem[]): RepositoryItem[] => {
    const normalizedQuery = query.toLowerCase().trim();
    
    if (!normalizedQuery) return files;
    
    return files.filter(file => {
        // Search in file name
        if (file.name.toLowerCase().includes(normalizedQuery)) return true;
        
        // Search in file extension
        const extension = file.name.split('.').pop()?.toLowerCase();
        if (extension?.includes(normalizedQuery)) return true;
        
        // Search in owner name
        if (file.owner.toLowerCase().includes(normalizedQuery)) return true;
        
        // Search in shared users
        if (file.sharedUsers?.some(user => 
            user.toLowerCase().includes(normalizedQuery)
        )) return true;
        
        return false;
    });
};

23.4 Selection Management

23.4.1 Multi-Select Implementation

const useMultiSelect = () => {
    const [selectedIds, setSelectedIds] = useAtom(selectedFileIdsAtom);
    const [isSelectMode, setSelectMode] = useAtom(isSelectModeAtom);
    
    const toggleSelection = (id: string) => {
        setSelectedIds(prev => {
            const newSet = new Set(prev);
            if (newSet.has(id)) {
                newSet.delete(id);
            } else if (newSet.size < MAX_SELECTION) {
                newSet.add(id);
            } else {
                // Show max selection toast
                toast.show('Maximum 30 items can be selected');
            }
            
            // Exit select mode if no items selected
            if (newSet.size === 0) {
                setSelectMode(false);
            }
            
            return newSet;
        });
    };
    
    const selectAll = (ids: string[]) => {
        const limitedIds = ids.slice(0, MAX_SELECTION);
        setSelectedIds(new Set(limitedIds));
    };
    
    const clearSelection = () => {
        setSelectedIds(new Set());
        setSelectMode(false);
    };
    
    return {
        selectedIds,
        isSelectMode,
        toggleSelection,
        selectAll,
        clearSelection
    };
};

23.5 Performance Optimizations

23.5.1 Virtualized List Optimization

const VirtualizedFileList = () => {
    const getItemLayout = useCallback((data, index) => ({
        length: ITEM_HEIGHT,
        offset: ITEM_HEIGHT * index,
        index,
    }), []);
    
    const keyExtractor = useCallback((item) => 
        `${item.entityID}-${item.lastModified}`, 
    []);
    
    const renderItem = useCallback(({ item, index }) => (
        <RepositoryItemCard
            {...item}
            index={index}
        />
    ), []);
    
    return (
        <VirtualList
            data={files}
            renderItem={renderItem}
            keyExtractor={keyExtractor}
            getItemLayout={getItemLayout}
            removeClippedSubviews={true}
            maxToRenderPerBatch={10}
            updateCellsBatchingPeriod={50}
            windowSize={10}
        />
    );
};

23.5.2 Image Optimization

const OptimizedFilePreview = ({ file }: { file: RepositoryItem }) => {
    const [imageError, setImageError] = useState(false);
    
    const getOptimizedUrl = (url: string, size: 'small' | 'medium' | 'large') => {
        const sizeMap = {
            small: 150,
            medium: 300,
            large: 600
        };
        
        return `${url}?w=${sizeMap[size]}&q=75`;
    };
    
    if (file.mimeType.startsWith('image/') && !imageError) {
        return (
            <FastImage
                source={{ 
                    uri: getOptimizedUrl(file.thumbnailURL, 'small'),
                    priority: FastImage.priority.normal,
                    cache: FastImage.cacheControl.immutable
                }}
                style={styles.thumbnail}
                onError={() => setImageError(true)}
            />
        );
    }
    
    return <FileIcon mimeType={file.mimeType} />;
};

23.6 Error Handling Patterns

23.6.1 Comprehensive Error Handling

const useErrorHandler = () => {
    const toast = useToastController();
    
    const handleError = (error: Error, context: string) => {
        console.error(`Error in ${context}:`, error);
        
        let userMessage = 'An unexpected error occurred';
        
        if (error.message.includes('Network')) {
            userMessage = 'Network error. Please check your connection.';
        } else if (error.message.includes('401')) {
            userMessage = 'Authentication expired. Please login again.';
        } else if (error.message.includes('403')) {
            userMessage = 'You don\'t have permission for this action.';
        } else if (error.message.includes('404')) {
            userMessage = 'File not found. It may have been deleted.';
        } else if (error.message.includes('413')) {
            userMessage = 'File too large. Maximum size is 100MB.';
        } else if (error.message.includes('429')) {
            userMessage = 'Too many requests. Please try again later.';
        } else if (error.message.includes('500')) {
            userMessage = 'Server error. Please try again later.';
        }
        
        toast.show(userMessage, {
            burntOptions: {
                haptic: 'error',
                preset: 'error'
            }
        });
        
        // Report to error tracking service
        if (typeof Sentry !== 'undefined') {
            Sentry.captureException(error, {
                tags: { context },
                extra: { userMessage }
            });
        }
    };
    
    return { handleError };
};

23.6.2 Retry Logic

const useRetry = () => {
    const exponentialBackoff = (retryCount: number): number => {
        return Math.min(1000 * Math.pow(2, retryCount), 30000);
    };
    
    const retryWithBackoff = async <T>(
        fn: () => Promise<T>,
        maxRetries: number = 3,
        context: string = 'operation'
    ): Promise<T> => {
        let lastError: Error;
        
        for (let i = 0; i < maxRetries; i++) {
            try {
                return await fn();
            } catch (error) {
                lastError = error;
                
                if (i < maxRetries - 1) {
                    const delay = exponentialBackoff(i);
                    console.log(`Retry ${i + 1}/${maxRetries} for ${context} after ${delay}ms`);
                    await new Promise(resolve => setTimeout(resolve, delay));
                }
            }
        }
        
        throw lastError;
    };
    
    return { retryWithBackoff };
};

24. Conclusion

The File Repository module is a comprehensive file management system that provides users with a familiar and intuitive interface for managing their digital assets. With features like chunked uploads, real-time search, bulk operationss, and granular permissions, it offers a robust solution for file storage and collaboration within the Nimbly Audit Lite application.

The modular architecture, combined with modern React patterns and performance optimizations, ensures a smooth user experience even with large file collections. The extensive use of TypeScript provides type safety, while the comprehensive test coverage ensures reliability.