# GCS (Google Cloud Storage) Configuration Guide

## Overview
All document uploads (workflow documents, work note attachments) are now configured to use Google Cloud Storage (GCS) instead of local file storage.

## Configuration Steps

### 1. Update `.env` File

Add or update the following environment variables in your `.env` file:

```env
# Cloud Storage (GCP)
GCP_PROJECT_ID=re-platform-workflow-dealer
GCP_BUCKET_NAME=your-bucket-name-here
GCP_KEY_FILE=./credentials/re-platform-workflow-dealer-3d5738fcc1f9.json
```

**Important Notes:**
- `GCP_PROJECT_ID`: Should match the `project_id` in your credentials JSON file (currently: `re-platform-workflow-dealer`)
- `GCP_BUCKET_NAME`: The name of your GCS bucket (create one in GCP Console if needed)
- `GCP_KEY_FILE`: Path to your service account credentials JSON file (relative to project root or absolute path)

### 2. Create GCS Bucket (if not exists)

1. Go to [Google Cloud Console](https://console.cloud.google.com/)
2. Navigate to **Cloud Storage** > **Buckets**
3. Click **Create Bucket**
4. Choose a unique bucket name (e.g., `re-workflow-documents`)
5. Select a location for your bucket
6. Set permissions:
   - Make bucket publicly readable (for public URLs) OR
   - Keep private and use signed URLs (more secure)

### 3. Grant Service Account Permissions

Your service account (`re-bridge-workflow@re-platform-workflow-dealer.iam.gserviceaccount.com`) needs:
- **Storage Object Admin** role (to upload/delete files)
- **Storage Object Viewer** role (to read files)

### 4. Verify Configuration

The system will:
- ✅ Automatically detect if GCS is configured
- ✅ Fall back to local storage if GCS is not configured
- ✅ Upload files to GCS when configured
- ✅ Store GCS URLs in the database
- ✅ Redirect downloads/previews to GCS URLs

## File Storage Structure

Files are organized in GCS by request number with subfolders for documents and attachments:

```
reflow-documents-uat/
├── requests/
│   ├── REQ-2025-12-0001/
│   │   ├── documents/
│   │   │   ├── {timestamp}-{hash}-{filename}
│   │   │   └── ...
│   │   └── attachments/
│   │       ├── {timestamp}-{hash}-{filename}
│   │       └── ...
│   ├── REQ-2025-12-0002/
│   │   ├── documents/
│   │   └── attachments/
│   └── ...
```

- **Documents**: `requests/{requestNumber}/documents/{timestamp}-{hash}-{filename}`
- **Work Note Attachments**: `requests/{requestNumber}/attachments/{timestamp}-{hash}-{filename}`

This structure makes it easy to:
- Track all files for a specific request
- Organize documents vs attachments separately
- Navigate and manage files in GCS console

## How It Works

### Upload Flow
1. File is received via multer (memory storage)
2. File buffer is uploaded to GCS
3. GCS returns a public URL
4. URL is stored in database (`storage_url` field)
5. Local file is deleted (if it existed)

### Download/Preview Flow
1. System checks if `storage_url` is a GCS URL
2. If GCS URL: Redirects to GCS public URL
3. If local path: Serves file from local storage

## Troubleshooting

### Files not uploading to GCS
- Check `.env` configuration matches your credentials
- Verify service account has correct permissions
- Check bucket name exists and is accessible
- Review application logs for GCS errors

### Files uploading but not accessible
- Verify bucket permissions (public read or signed URLs)
- Check CORS configuration if accessing from browser
- Ensure `storage_url` is being saved correctly in database

### Fallback to Local Storage
If GCS is not configured or fails, the system will:
- Log a warning
- Continue using local file storage
- Store local paths in database

## Testing

After configuration:
1. Upload a document via API
2. Check database - `storage_url` should contain GCS URL
3. Try downloading/previewing the document
4. Verify file is accessible at GCS URL

## Security Notes

- **Public Buckets**: Files are publicly accessible via URL
- **Private Buckets**: Consider using signed URLs for better security
- **Service Account**: Keep credentials file secure, never commit to git
- **Bucket Policies**: Configure bucket-level permissions as needed

