# GCP Cloud Storage - Production Setup Guide

## Overview

This guide provides step-by-step instructions for setting up Google Cloud Storage (GCS) for the **Royal Enfield Workflow System** in **Production** environment. This document focuses specifically on production deployment requirements, folder structure, and environment configuration.

---

## Table of Contents

1. [Production Requirements](#1-production-requirements)
2. [GCP Bucket Configuration](#2-gcp-bucket-configuration)
3. [Service Account Setup](#3-service-account-setup)
4. [Environment Variables Configuration](#4-environment-variables-configuration)
5. [Folder Structure in GCS](#5-folder-structure-in-gcs)
6. [Security & Access Control](#6-security--access-control)
7. [CORS Configuration](#7-cors-configuration)
8. [Lifecycle Management](#8-lifecycle-management)
9. [Monitoring & Alerts](#9-monitoring--alerts)
10. [Verification & Testing](#10-verification--testing)

---

## 1. Production Requirements

### 1.1 Application Details

| Item | Production Value |
|------|------------------|
| **Application** | Royal Enfield Workflow System |
| **Environment** | Production |
| **Domain** | `https://reflow.{{APP_DOMAIN}}` |
| **Purpose** | Store workflow documents, attachments, invoices, and credit notes |
| **Storage Type** | Google Cloud Storage (GCS) |
| **Region** | `asia-south1` (Mumbai) |

### 1.2 Storage Requirements

The application stores:
- **Workflow Documents**: Initial documents uploaded during request creation
- **Work Note Attachments**: Files attached during approval workflow
- **Invoice Files**: Generated e-invoice PDFs
- **Credit Note Files**: Generated credit note PDFs
- **Dealer Claim Documents**: Proposal documents, completion documents

---

## 2. GCP Bucket Configuration

### 2.1 Production Bucket Settings

| Setting | Production Value |
|---------|------------------|
| **Bucket Name** | `reflow-documents-prod` |
| **Location Type** | Region |
| **Region** | `asia-south1` (Mumbai) |
| **Storage Class** | Standard (for active files) |
| **Access Control** | Uniform bucket-level access |
| **Public Access Prevention** | Enforced (Block all public access) |
| **Versioning** | Enabled (for recovery) |
| **Lifecycle Rules** | Configured (see section 8) |

### 2.2 Create Production Bucket

```bash
# Create production bucket
gcloud storage buckets create gs://reflow-documents-prod \
  --project=re-platform-workflow-dealer \
  --location=asia-south1 \
  --uniform-bucket-level-access \
  --public-access-prevention

# Enable versioning
gcloud storage buckets update gs://reflow-documents-prod \
  --versioning

# Verify bucket creation
gcloud storage buckets describe gs://reflow-documents-prod
```

### 2.3 Bucket Naming Convention

| Environment | Bucket Name | Purpose |
|-------------|-------------|---------|
| Development | `reflow-documents-dev` | Development testing |
| UAT | `reflow-documents-uat` | User acceptance testing |
| Production | `reflow-documents-prod` | Live production data |

---

## 3. Service Account Setup

### 3.1 Create Production Service Account

```bash
# Create service account for production
gcloud iam service-accounts create reflow-storage-prod-sa \
  --display-name="RE Workflow Production Storage Service Account" \
  --description="Service account for production file storage operations" \
  --project=re-platform-workflow-dealer
```

### 3.2 Assign Required Roles

The service account needs the following IAM roles:

| Role | Purpose | Required For |
|------|---------|--------------|
| `roles/storage.objectAdmin` | Full control over objects | Upload, delete, update files |
| `roles/storage.objectViewer` | Read objects | Download and preview files |
| `roles/storage.legacyBucketReader` | Read bucket metadata | List files and check bucket status |

```bash
# Grant Storage Object Admin role
gcloud projects add-iam-policy-binding re-platform-workflow-dealer \
  --member="serviceAccount:reflow-storage-prod-sa@re-platform-workflow-dealer.iam.gserviceaccount.com" \
  --role="roles/storage.objectAdmin"

# Grant Storage Object Viewer role (for read operations)
gcloud projects add-iam-policy-binding re-platform-workflow-dealer \
  --member="serviceAccount:reflow-storage-prod-sa@re-platform-workflow-dealer.iam.gserviceaccount.com" \
  --role="roles/storage.objectViewer"
```

### 3.3 Generate Service Account Key

```bash
# Generate JSON key file for production
gcloud iam service-accounts keys create ./config/gcp-key-prod.json \
  --iam-account=reflow-storage-prod-sa@re-platform-workflow-dealer.iam.gserviceaccount.com \
  --project=re-platform-workflow-dealer
```

⚠️ **Security Warning:**
- Store the key file securely (not in Git)
- Use secure file transfer methods
- Rotate keys periodically (every 90 days recommended)
- Restrict file permissions: `chmod 600 ./config/gcp-key-prod.json`

---

## 4. Environment Variables Configuration

### 4.1 Required Environment Variables

Add the following environment variables to your production `.env` file:

```env
# ============================================
# Google Cloud Storage (GCP) Configuration
# ============================================
# GCP Project ID - Must match the project_id in your service account key file
GCP_PROJECT_ID=re-platform-workflow-dealer

# GCP Bucket Name - Production bucket name
GCP_BUCKET_NAME=reflow-documents-prod

# GCP Service Account Key File Path
# Can be relative to project root or absolute path
# Example: ./config/gcp-key-prod.json
# Example: /etc/reflow/config/gcp-key-prod.json
GCP_KEY_FILE=./config/gcp-key-prod.json
```

### 4.2 Environment Variable Details

| Variable | Description | Example Value | Required |
|----------|-------------|---------------|----------|
| `GCP_PROJECT_ID` | Your GCP project ID. Must match the `project_id` field in the service account JSON key file. | `re-platform-workflow-dealer` | ✅ Yes |
| `GCP_BUCKET_NAME` | Name of the GCS bucket where files will be stored. Must exist in your GCP project. | `reflow-documents-prod` | ✅ Yes |
| `GCP_KEY_FILE` | Path to the service account JSON key file. Can be relative (from project root) or absolute path. | `./config/gcp-key-prod.json` | ✅ Yes |

### 4.3 File Path Configuration

**Relative Path (Recommended for Development):**
```env
GCP_KEY_FILE=./config/gcp-key-prod.json
```

**Absolute Path (Recommended for Production):**
```env
GCP_KEY_FILE=/etc/reflow/config/gcp-key-prod.json
```

### 4.4 Verification

After setting environment variables, verify the configuration:

```bash
# Check if variables are set
echo $GCP_PROJECT_ID
echo $GCP_BUCKET_NAME
echo $GCP_KEY_FILE

# Verify key file exists
ls -la $GCP_KEY_FILE

# Verify key file permissions (should be 600)
stat -c "%a %n" $GCP_KEY_FILE
```

---

## 5. Folder Structure in GCS

### 5.1 Production Bucket Structure

```
reflow-documents-prod/
│
├── requests/                          # All workflow-related files
│   ├── REQ-2025-12-0001/             # Request-specific folder
│   │   ├── documents/                 # Initial request documents
│   │   │   ├── 1701234567890-abc123-proposal.pdf
│   │   │   ├── 1701234567891-def456-specification.docx
│   │   │   └── 1701234567892-ghi789-budget.xlsx
│   │   │
│   │   ├── attachments/                # Work note attachments
│   │   │   ├── 1701234567893-jkl012-approval_note.pdf
│   │   │   ├── 1701234567894-mno345-signature.png
│   │   │   └── 1701234567895-pqr678-supporting_doc.pdf
│   │   │
│   │   ├── invoices/                   # Generated invoice files
│   │   │   └── 1701234567896-stu901-invoice_REQ-2025-12-0001.pdf
│   │   │
│   │   └── credit-notes/               # Generated credit note files
│   │       └── 1701234567897-vwx234-credit_note_REQ-2025-12-0001.pdf
│   │
│   ├── REQ-2025-12-0002/
│   │   ├── documents/
│   │   ├── attachments/
│   │   ├── invoices/
│   │   └── credit-notes/
│   │
│   └── REQ-2025-12-0003/
│       └── ...
│
└── temp/                               # Temporary uploads (auto-deleted after 24h)
    └── (temporary files before processing)
```

### 5.2 File Path Patterns

| File Type | Path Pattern | Example |
|-----------|--------------|---------|
| **Documents** | `requests/{requestNumber}/documents/{timestamp}-{hash}-{filename}` | `requests/REQ-2025-12-0001/documents/1701234567890-abc123-proposal.pdf` |
| **Attachments** | `requests/{requestNumber}/attachments/{timestamp}-{hash}-{filename}` | `requests/REQ-2025-12-0001/attachments/1701234567893-jkl012-approval_note.pdf` |
| **Invoices** | `requests/{requestNumber}/invoices/{timestamp}-{hash}-{filename}` | `requests/REQ-2025-12-0001/invoices/1701234567896-stu901-invoice_REQ-2025-12-0001.pdf` |
| **Credit Notes** | `requests/{requestNumber}/credit-notes/{timestamp}-{hash}-{filename}` | `requests/REQ-2025-12-0001/credit-notes/1701234567897-vwx234-credit_note_REQ-2025-12-0001.pdf` |

### 5.3 File Naming Convention

Files are automatically renamed with the following pattern:
```
{timestamp}-{randomHash}-{sanitizedOriginalName}
```

**Example:**
- Original: `My Proposal Document (Final).pdf`
- Stored: `1701234567890-abc123-My_Proposal_Document__Final_.pdf`

**Benefits:**
- Prevents filename conflicts
- Maintains original filename for reference
- Ensures unique file identifiers
- Safe for URL encoding

---

## 6. Security & Access Control

### 6.1 Bucket Security Settings

```bash
# Enforce public access prevention
gcloud storage buckets update gs://reflow-documents-prod \
  --public-access-prevention

# Enable uniform bucket-level access
gcloud storage buckets update gs://reflow-documents-prod \
  --uniform-bucket-level-access
```

### 6.2 Access Control Strategy

**Production Approach:**
- **Private Bucket**: All files are private by default
- **Signed URLs**: Generate time-limited signed URLs for file access (recommended)
- **Service Account**: Only service account has direct access
- **IAM Policies**: Restrict access to specific service accounts only

### 6.3 Signed URL Configuration (Recommended)

For production, use signed URLs instead of public URLs:

```typescript
// Example: Generate signed URL (valid for 1 hour)
const [url] = await file.getSignedUrl({
  action: 'read',
  expires: Date.now() + 60 * 60 * 1000, // 1 hour
});
```

### 6.4 Security Checklist

- [ ] Public access prevention enabled
- [ ] Uniform bucket-level access enabled
- [ ] Service account has minimal required permissions
- [ ] JSON key file stored securely (not in Git)
- [ ] Key file permissions set to 600
- [ ] CORS configured for specific domains only
- [ ] Bucket versioning enabled
- [ ] Access logging enabled
- [ ] Signed URLs used for file access (if applicable)

---

## 7. CORS Configuration

### 7.1 Production CORS Policy

Create `cors-config-prod.json`:

```json
[
  {
    "origin": [
      "https://reflow.{{APP_DOMAIN}}",
      "https://www.{{APP_DOMAIN}}"
    ],
    "method": ["GET", "PUT", "POST", "DELETE", "HEAD", "OPTIONS"],
    "responseHeader": [
      "Content-Type",
      "Content-Disposition",
      "Content-Length",
      "Cache-Control",
      "x-goog-meta-*"
    ],
    "maxAgeSeconds": 3600
  }
]
```

### 7.2 Apply CORS Configuration

```bash
gcloud storage buckets update gs://reflow-documents-prod \
  --cors-file=cors-config-prod.json
```

### 7.3 Verify CORS

```bash
# Check CORS configuration
gcloud storage buckets describe gs://reflow-documents-prod \
  --format="value(cors)"
```

---

## 8. Lifecycle Management

### 8.1 Lifecycle Rules Configuration

Create `lifecycle-config-prod.json`:

```json
{
  "lifecycle": {
    "rule": [
      {
        "action": { "type": "Delete" },
        "condition": {
          "age": 1,
          "matchesPrefix": ["temp/"]
        },
        "description": "Delete temporary files after 24 hours"
      },
      {
        "action": { "type": "SetStorageClass", "storageClass": "NEARLINE" },
        "condition": {
          "age": 90,
          "matchesPrefix": ["requests/"]
        },
        "description": "Move old files to Nearline storage after 90 days"
      },
      {
        "action": { "type": "SetStorageClass", "storageClass": "COLDLINE" },
        "condition": {
          "age": 365,
          "matchesPrefix": ["requests/"]
        },
        "description": "Move archived files to Coldline storage after 1 year"
      }
    ]
  }
}
```

### 8.2 Apply Lifecycle Rules

```bash
gcloud storage buckets update gs://reflow-documents-prod \
  --lifecycle-file=lifecycle-config-prod.json
```

### 8.3 Lifecycle Rule Benefits

| Rule | Purpose | Cost Savings |
|------|---------|--------------|
| Delete temp files | Remove temporary uploads after 24h | Prevents storage bloat |
| Move to Nearline | Archive files older than 90 days | ~50% cost reduction |
| Move to Coldline | Archive files older than 1 year | ~70% cost reduction |

---

## 9. Monitoring & Alerts

### 9.1 Enable Access Logging

```bash
# Create logging bucket (if not exists)
gcloud storage buckets create gs://reflow-logs-prod \
  --project=re-platform-workflow-dealer \
  --location=asia-south1

# Enable access logging
gcloud storage buckets update gs://reflow-documents-prod \
  --log-bucket=gs://reflow-logs-prod \
  --log-object-prefix=reflow-storage-logs/
```

### 9.2 Set Up Monitoring Alerts

**Recommended Alerts:**

1. **Storage Quota Alert**
   - Trigger: Storage exceeds 80% of quota
   - Action: Notify DevOps team

2. **Unusual Access Patterns**
   - Trigger: Unusual download patterns detected
   - Action: Security team notification

3. **Failed Access Attempts**
   - Trigger: Multiple failed authentication attempts
   - Action: Immediate security alert

4. **High Upload Volume**
   - Trigger: Upload volume exceeds normal threshold
   - Action: Performance team notification

### 9.3 Cost Monitoring

Monitor storage costs via:
- GCP Console → Billing → Reports
- Set up budget alerts at 50%, 75%, 90% of monthly budget
- Review storage class usage (Standard vs Nearline vs Coldline)

---

## 10. Verification & Testing

### 10.1 Pre-Deployment Verification

```bash
# 1. Verify bucket exists
gcloud storage buckets describe gs://reflow-documents-prod

# 2. Verify service account has access
gcloud storage ls gs://reflow-documents-prod \
  --impersonate-service-account=reflow-storage-prod-sa@re-platform-workflow-dealer.iam.gserviceaccount.com

# 3. Test file upload
echo "test file" > test-upload.txt
gcloud storage cp test-upload.txt gs://reflow-documents-prod/temp/test-upload.txt

# 4. Test file download
gcloud storage cp gs://reflow-documents-prod/temp/test-upload.txt ./test-download.txt

# 5. Test file delete
gcloud storage rm gs://reflow-documents-prod/temp/test-upload.txt

# 6. Clean up
rm test-upload.txt test-download.txt
```

### 10.2 Application-Level Testing

1. **Upload Test:**
   - Upload a document via API
   - Verify file appears in GCS bucket
   - Check database `storage_url` field contains GCS URL

2. **Download Test:**
   - Download file via API
   - Verify file is accessible
   - Check response headers

3. **Delete Test:**
   - Delete file via API
   - Verify file is removed from GCS
   - Check database record is updated

### 10.3 Production Readiness Checklist

- [ ] Bucket created and configured
- [ ] Service account created with correct permissions
- [ ] JSON key file generated and stored securely
- [ ] Environment variables configured in `.env`
- [ ] CORS policy applied
- [ ] Lifecycle rules configured
- [ ] Versioning enabled
- [ ] Access logging enabled
- [ ] Monitoring alerts configured
- [ ] Upload/download/delete operations tested
- [ ] Backup and recovery procedures documented

---

## 11. Troubleshooting

### 11.1 Common Issues

**Issue: Files not uploading to GCS**
- ✅ Check `.env` configuration matches credentials
- ✅ Verify service account has correct permissions
- ✅ Check bucket name exists and is accessible
- ✅ Review application logs for GCS errors
- ✅ Verify key file path is correct

**Issue: Files uploading but not accessible**
- ✅ Verify bucket permissions (private vs public)
- ✅ Check CORS configuration if accessing from browser
- ✅ Ensure `storage_url` is being saved correctly in database
- ✅ Verify signed URL generation (if using private bucket)

**Issue: Permission denied errors**
- ✅ Verify service account has `roles/storage.objectAdmin`
- ✅ Check bucket IAM policies
- ✅ Verify key file is valid and not expired

### 11.2 Log Analysis

Check application logs for GCS-related messages:
```bash
# Search for GCS initialization
grep "GCS.*Initialized" logs/app.log

# Search for GCS errors
grep "GCS.*Error" logs/app.log

# Search for upload failures
grep "GCS.*upload.*failed" logs/app.log
```

---

## 12. Production Deployment Steps

### 12.1 Deployment Checklist

1. **Pre-Deployment:**
   - [ ] Create production bucket
   - [ ] Create production service account
   - [ ] Generate and secure key file
   - [ ] Configure environment variables
   - [ ] Test upload/download operations

2. **Deployment:**
   - [ ] Deploy application with new environment variables
   - [ ] Verify GCS initialization in logs
   - [ ] Test file upload functionality
   - [ ] Monitor for errors

3. **Post-Deployment:**
   - [ ] Verify files are being stored in GCS
   - [ ] Check database `storage_url` fields
   - [ ] Monitor storage costs
   - [ ] Review access logs

---

## 13. Cost Estimation (Production)

| Item | Monthly Estimate | Notes |
|------|------------------|-------|
| **Storage (500GB)** | ~$10.00 | Standard storage class |
| **Operations (100K)** | ~$0.50 | Upload/download operations |
| **Network Egress** | Variable | Depends on download volume |
| **Nearline Storage** | ~$5.00 | Files older than 90 days |
| **Coldline Storage** | ~$2.00 | Files older than 1 year |

**Total Estimated Monthly Cost:** ~$17.50 (excluding network egress)

---

## 14. Support & Contacts

| Role | Responsibility | Contact |
|------|----------------|---------|
| **DevOps Team** | GCP infrastructure setup | [DevOps Email] |
| **Application Team** | Application configuration | [App Team Email] |
| **Security Team** | Access control and permissions | [Security Email] |

---

## 15. Quick Reference

### 15.1 Essential Commands

```bash
# Create bucket
gcloud storage buckets create gs://reflow-documents-prod \
  --project=re-platform-workflow-dealer \
  --location=asia-south1 \
  --uniform-bucket-level-access \
  --public-access-prevention

# Create service account
gcloud iam service-accounts create reflow-storage-prod-sa \
  --display-name="RE Workflow Production Storage" \
  --project=re-platform-workflow-dealer

# Generate key
gcloud iam service-accounts keys create ./config/gcp-key-prod.json \
  --iam-account=reflow-storage-prod-sa@re-platform-workflow-dealer.iam.gserviceaccount.com

# Set CORS
gcloud storage buckets update gs://reflow-documents-prod \
  --cors-file=cors-config-prod.json

# Enable versioning
gcloud storage buckets update gs://reflow-documents-prod \
  --versioning
```

### 15.2 Environment Variables Template

```env
# Production GCP Configuration
GCP_PROJECT_ID=re-platform-workflow-dealer
GCP_BUCKET_NAME=reflow-documents-prod
GCP_KEY_FILE=./config/gcp-key-prod.json
```

---

## Appendix: File Structure Reference

### Database Storage Fields

The application stores file information in the database:

| Table | Field | Description |
|-------|-------|-------------|
| `documents` | `file_path` | GCS path: `requests/{requestNumber}/documents/{filename}` |
| `documents` | `storage_url` | Full GCS URL: `https://storage.googleapis.com/bucket/path` |
| `work_note_attachments` | `file_path` | GCS path: `requests/{requestNumber}/attachments/{filename}` |
| `work_note_attachments` | `storage_url` | Full GCS URL |
| `claim_invoices` | `invoice_file_path` | GCS path: `requests/{requestNumber}/invoices/{filename}` |
| `claim_credit_notes` | `credit_note_file_path` | GCS path: `requests/{requestNumber}/credit-notes/{filename}` |

---

**Document Version:** 1.0  
**Last Updated:** December 2024  
**Maintained By:** RE Workflow Development Team

