# AWS S3 Image Storage Integration Plan

## Overview

Integrate AWS S3 for image storage using **direct-to-S3 uploads with presigned URLs**. Frontend will upload directly to S3, reducing backend load. Images will use a **hybrid access model**: public URLs for profiles/items/forum, private signed URLs for messages and condition-checks.

## Architecture

```
Frontend                          Backend                         AWS S3
   │                                 │                               │
   │  1. POST /api/upload/presign    │                               │
   │────────────────────────────────>│                               │
   │                                 │  2. Generate presigned URL    │
   │  3. Return {uploadUrl, key}     │                               │
   │<────────────────────────────────│                               │
   │                                 │                               │
   │  4. PUT file directly to S3     │                               │
   │────────────────────────────────────────────────────────────────>│
   │                                 │                               │
   │  5. POST /api/upload/confirm    │                               │
   │────────────────────────────────>│  6. Verify object exists      │
   │                                 │──────────────────────────────>│
   │  7. Return confirmation         │                               │
   │<────────────────────────────────│                               │
```

## S3 Bucket Structure

```
s3://village-share-{env}/
├── profiles/{uuid}.{ext}           # Public access
├── items/{uuid}.{ext}              # Public access
├── forum/{uuid}.{ext}              # Public access
├── messages/{uuid}.{ext}           # Private (signed URLs)
└── condition-checks/{uuid}.{ext}   # Private (signed URLs)
```

---

### AWS S3 Bucket Setup

#### Bucket Policy (Hybrid: Public + Private)

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicRead",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": [
        "arn:aws:s3:::village-share-dev/profiles/*",
        "arn:aws:s3:::village-share-dev/items/*",
        "arn:aws:s3:::village-share-dev/forum/*"
      ]
    }
  ]
}
```

Note: `messages/*` and `condition-checks/*` are NOT included - require signed URLs.

#### CORS Configuration

```json
[
  {
    "AllowedHeaders": [
      "Content-Type",
      "Content-Length",
      "Content-Disposition",
      "Cache-Control",
      "x-amz-content-sha256",
      "x-amz-date",
      "x-amz-security-token"
    ],
    "AllowedMethods": ["PUT", "GET"],
    "AllowedOrigins": ["http://localhost:3000"],
    "ExposeHeaders": ["ETag"],
    "MaxAgeSeconds": 3600
  }
]
```

#### IAM Policy for Backend

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:PutObject", "s3:GetObject"],
      "Resource": "arn:aws:s3:::village-share-dev/*"
    }
  ]
}
```

**Security Note:** `s3:DeleteObject` is intentionally NOT included. File deletion is not exposed via the API to prevent unauthorized deletion attacks. Use S3 lifecycle policies for cleanup instead.

## Environment Variables to Add

```bash
# Backend (.env)
S3_ENABLED=true                       # Set to "true" to enable S3
S3_BUCKET=village-share-{env}

# Frontend (.env)
REACT_APP_S3_BUCKET=village-share-{env}
REACT_APP_AWS_REGION=us-east-1
```

---

## Deployment Checklist

1. Create S3 buckets for each environment (dev, qa, prod)
2. Apply bucket policies (public folders + private messages)
3. Configure CORS on each bucket
4. Attach IAM policy to EC2/ECS role
5. Add environment variables
6. Deploy backend changes
7. Deploy frontend changes
