File Storage Module Overview
Overview Description
The File Storage module provides comprehensive functionality for managing file uploads to Google Cloud Storage (GCS) and tracking upload history. This module includes features for generating signed URLs for direct uploads, storing upload metadata, retrieving upload histories, and managing error reporting. The module is designed to support CSV file uploads with validation error tracking and provides both API responses and CSV export capabilities.
Activity Diagram
---
config:
theme: base
layout: dagre
flowchart:
curve: linear
htmlLabels: true
themeVariables:
edgeLabelBackground: "transparent"
---
flowchart TD
Client[Client Application]
API[UploadGcsController]
GCSService[GcsService]
ImportService[ImportReviewService]
ExportService[ExportService]
Repository[ReviewUploadHistoryRepository]
Database[(Database)]
GCS[(Google Cloud Storage)]
Client --- Step1[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>1</span>
<p style='margin-top: 8px'>Request Signed URL</p>
</div>
]
Step1 --> API
API --- Step2[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>2</span>
<p style='margin-top: 8px'>Generate Signed URL</p>
</div>
]
Step2 --> ImportService
ImportService --- Step3[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3</span>
<p style='margin-top: 8px'>Request URL from GCS</p>
</div>
]
Step3 --> GCSService
GCSService --- Step4[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4</span>
<p style='margin-top: 8px'>Return Signed URL</p>
</div>
]
Step4 --> GCS
GCS --- Step5[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5</span>
<p style='margin-top: 8px'>Return URL to Client</p>
</div>
]
Step5 --> GCSService
GCSService --> ImportService
ImportService --> API
API --> Client
Client --- Step6[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>6</span>
<p style='margin-top: 8px'>Upload File Directly</p>
</div>
]
Step6 --> GCS
Client --- Step7[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>7</span>
<p style='margin-top: 8px'>Store Upload History</p>
</div>
]
Step7 --> API
API --- Step8[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>8</span>
<p style='margin-top: 8px'>Save to Database</p>
</div>
]
Step8 --> Repository
Repository --- Step9[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>9</span>
<p style='margin-top: 8px'>Store History Record</p>
</div>
]
Step9 --> Database
Client --- Step10[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #cc66cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>10</span>
<p style='margin-top: 8px'>Request History List</p>
</div>
]
Step10 --> API
API --- Step11[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #cc66cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>11</span>
<p style='margin-top: 8px'>Query Database</p>
</div>
]
Step11 --> Repository
Repository --- Step12[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #cc66cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>12</span>
<p style='margin-top: 8px'>Return History Data</p>
</div>
]
Step12 --> Database
Client --- Step13[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #ff9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>13</span>
<p style='margin-top: 8px'>Download Error CSV</p>
</div>
]
Step13 --> API
API --- Step14[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #ff9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>14</span>
<p style='margin-top: 8px'>Generate CSV File</p>
</div>
]
Step14 --> ExportService
ExportService --- Step15[
<div style='text-align: center'>
<span style='display: inline-block; background-color: #ff9966 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>15</span>
<p style='margin-top: 8px'>Return CSV Download</p>
</div>
]
Step15 --> API
API --> Client
style Client fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
style API fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
style GCSService fill:#f0f8e6,stroke:#339933,stroke-width:2px
style ImportService fill:#f0f8e6,stroke:#339933,stroke-width:2px
style ExportService fill:#f0f8e6,stroke:#339933,stroke-width:2px
style Repository fill:#fff0f5,stroke:#cc6699,stroke-width:2px
style Database fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
style GCS fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
style Step1 fill:transparent,stroke:transparent,stroke-width:1px
style Step2 fill:transparent,stroke:transparent,stroke-width:1px
style Step3 fill:transparent,stroke:transparent,stroke-width:1px
style Step4 fill:transparent,stroke:transparent,stroke-width:1px
style Step5 fill:transparent,stroke:transparent,stroke-width:1px
style Step6 fill:transparent,stroke:transparent,stroke-width:1px
style Step7 fill:transparent,stroke:transparent,stroke-width:1px
style Step8 fill:transparent,stroke:transparent,stroke-width:1px
style Step9 fill:transparent,stroke:transparent,stroke-width:1px
style Step10 fill:transparent,stroke:transparent,stroke-width:1px
style Step11 fill:transparent,stroke:transparent,stroke-width:1px
style Step12 fill:transparent,stroke:transparent,stroke-width:1px
style Step13 fill:transparent,stroke:transparent,stroke-width:1px
style Step14 fill:transparent,stroke:transparent,stroke-width:1px
style Step15 fill:transparent,stroke:transparent,stroke-width:1px
Module List
| Name |
Overview Link |
Description |
| Generate Signed URL |
GCS Upload |
Generate signed URLs for direct file uploads to Google Cloud Storage |
| Store Upload History |
Store History |
Store metadata about file uploads including status and error information |
| Upload Histories |
Upload Histories |
Retrieve paginated list of upload history records with filtering |
| List Histories |
List Histories |
Get formatted history list with API resource transformation |
| Get History by ID |
Get by ID |
Retrieve detailed information about a specific upload history |
| Get Import Errors |
Import Errors |
Retrieve validation errors for a specific upload history |
| Download Error CSV |
Download CSV |
Download CSV file containing detailed error information |
API Endpoints
| Method |
Endpoint |
Description |
| GET |
/api/v1/general/upload-file/gcs/get-signed-url |
Generate signed URL for direct file upload |
| POST |
/api/v1/general/upload-file/gcs/upload-history |
Store upload history metadata |
| GET |
/api/v1/general/upload-file/gcs/histories/list |
Get paginated list of upload histories |
| GET |
/api/v1/general/upload-file/gcs/histories/{id} |
Get specific upload history by ID |
| GET |
/api/v1/general/upload-file/gcs/histories/{id}/import-errors |
Get import errors for specific history |
| GET |
/api/v1/general/upload-file/gcs/histories/{id}/download-errors |
Download error CSV file |
Database Schema
erDiagram
review_upload_histories {
bigint id PK
bigint user_id FK "Reference to users table"
bigint group_id FK "Reference to groups table"
string file_name "Name of the uploaded file"
string gcs_path "Google Cloud Storage path where file is stored"
tinyInteger status "Upload status: 0=Notyet, 1=processing, 2=success, 3=fail"
string error_reason "Error message if upload failed (nullable)"
timestamp validated_at "Timestamp when file was validated (nullable)"
timestamp created_at
timestamp updated_at
}
review_upload_errors {
bigint id PK
bigint review_upload_history_id FK "Reference to review_upload_histories table"
string header "Field header that caused the error (nullable)"
string value "Problematic data value (nullable)"
integer error_line "Line number where error occurred (nullable)"
json error_messages "Array of error messages for the field"
timestamp created_at
timestamp updated_at
}
users {
bigint id PK
string name "User's full name"
string email "User's email address"
}
groups {
bigint id PK
string name "Group name"
}
review_upload_histories ||--o{ users : belongs_to
review_upload_histories ||--o{ groups : belongs_to
review_upload_histories ||--o{ review_upload_errors : has_many
Key Features
- Direct Upload Support: Generate signed URLs for direct client-to-GCS uploads
- Upload Tracking: Comprehensive history tracking with status and error information
- Error Management: Detailed error tracking with field-level validation errors
- CSV Export: Download error reports in CSV format for data correction
- Pagination: Support for large datasets with configurable pagination
- Group-Based Access: Automatic filtering by user's group for data security
- Resource Transformation: Consistent API responses using Laravel resources
- Group-Based Path Structure: Automatic path generation based on user's group and date
Security Considerations
- Group Isolation: Users can only access upload histories from their own group
- Signed URL Expiration: Generated URLs expire after 15 minutes
- Input Validation: All endpoints include comprehensive input validation
- Error Logging: Failed operations are logged for monitoring and debugging
- File Path Security: Files are stored in group-specific directories with date-based organization