# AWS account migration — `lambda/bedrock_analysis`

Planning document for moving this stack to a new AWS account with a new Supabase project and S3-backed image storage. **No code changes are included here** — this file inventories what must change and which functions are affected.

---

## Summary

| Area | Current pattern | Migration action |
|------|-----------------|------------------|
| Supabase connection | SSM `/supabase/url`, `/supabase/anon` | Create new SSM params in new account with new project URL + keys |
| Product/shelf images | Supabase Storage API + HTTP fallback on public URLs | **Code change required** — use `boto3` S3 SDK when images live in S3 |
| GenAI debug artifacts | S3 bucket `datafy-bedrock-artifacts` (hardcoded in `app.py`) | Create bucket in new account; fix hardcoded name to use env/SSM |
| IAM / ARNs | Account `587594388832` hardcoded in `template.yaml` | Replace with new account ID or `!Sub` / `!GetAtt` |
| VPC | Defaults `vpc-0ada1e5366ad5c132`, subnets in template | Set new VPC/subnet parameters at deploy |
| Bedrock | Inference profiles + model access in `eu-west-1` | Enable models in new account; re-request quotas |

---

## SSM Parameter Store (new account)

Create these before deploying Lambdas:

| Parameter | Used by | Notes |
|-----------|---------|-------|
| `/supabase/url` | All functions below | New Supabase project API URL |
| `/supabase/anon` | All functions below | Anon key (sufficient for read + storage in current code) |

Optional (not used in this stack today, but relevant if RLS blocks writes):

| Parameter | Notes |
|-----------|-------|
| `/supabase/service_role` | Not referenced in bedrock_analysis; add only if anon key is insufficient |

---

## SAM / infrastructure (`template.yaml`)

### Must update

1. **AWS account ID** — every `arn:aws:ssm:eu-west-1:587594388832:parameter/...` → new account ID (5 Lambdas × multiple statements).
2. **VPC parameters** — `VpcId`, `PrivateSubnet1Id`, `PrivateSubnet2Id` defaults point at old VPC.
3. **Artifacts S3 bucket**
   - Parameter `ArtifactsBucketName` (default `datafy-bedrock-artifacts`)
   - IAM policy hardcodes `arn:aws:s3:::datafy-bedrock-artifacts` — should reference `!Ref ArtifactsBucketName` after migration
   - Env var `GENAI_ARTIFACTS_S3_BUCKET` is set from template, but **`app/app.py` ignores it** and hardcodes `"datafy-bedrock-artifacts"` — must fix in code during migration
4. **Bedrock** — ensure `bedrock:InvokeModel` on foundation models and inference profiles is granted in the new account (same region `eu-west-1` assumed).
5. **API Gateway** — new stack produces new `/analyze-image` and `/analyze-image-test` URLs; update any callers (frontend, cron, Step Functions outside this repo).
6. **Step Functions** — `BedrockRetryWorkflow`, `BedrockBatchWorkflow` ARNs change on redeploy; update EventBridge rule target if stack name changes.
7. **Lambda security group** — recreated in new VPC; ensure NAT egress for Supabase/S3/Bedrock HTTPS.

### Redeploy checklist

- [ ] Create S3 bucket for artifacts (or pass empty `ArtifactsBucketName` to disable)
- [ ] Populate SSM Supabase params
- [ ] Deploy SAM with new VPC/subnet parameters
- [ ] Request Bedrock model access + quotas in new account
- [ ] Smoke-test `/analyze-image` with one `image_id` and one `task_id`
- [ ] Run Bedrock retry/batch workflows manually once

---

## Lambda functions — impact matrix

### 1. `BedrockImageAnalysis` (`app/app.py`)

**Role:** Main GenAI analysis — reads task/product/image from Supabase, downloads shelf + product images, calls Bedrock, writes results back.

| Concern | Detail |
|---------|--------|
| Supabase tables | `product_images`, `product`, `task` |
| Image download | `download_image()` — Supabase Storage API, URL parser for `/storage/v1/object/public/{bucket}/{key}`, HTTP fallback |
| S3 write | `save_artifacts_to_s3()` — optional debug artifacts |
| **Must update for S3 images** | `download_image()`, `_supabase_public_url_bucket_key()` — add S3 path/URL branch using `boto3.client('s3').get_object()` |
| **Must update for artifacts** | Replace hardcoded `bucket = "datafy-bedrock-artifacts"` with `os.environ.get('GENAI_ARTIFACTS_S3_BUCKET')` |
| SSM | `/supabase/url`, `/supabase/anon` |
| IAM | SSM, Bedrock, `s3:PutObject` on artifacts bucket |

**DB data migration note:** Existing `image_path` / `pref_url` values may still be old Supabase public URLs (`https://{old-ref}.supabase.co/storage/v1/object/public/...`). After storage move, either backfill URLs/paths in Postgres or teach `download_image()` to map legacy URLs to new S3 keys.

---

### 2. `BedrockImageAnalysisTest` (`app/test_app.py`)

**Role:** Dry-run Bedrock test endpoint; reads from Supabase for image bytes but does not write analysis results.

| Concern | Detail |
|---------|--------|
| Supabase | Same client + `download_image()` as production |
| **Must update for S3 images** | Same as `BedrockImageAnalysis` if test handler shares `download_image()` |
| SSM / IAM | Same Supabase + Bedrock permissions |

---

### 3. `BedrockBatchAnalyze` (`bedrock_batch_analyze/app.py`)

**Role:** Batch variant — one product reference image + multiple shelf images per Bedrock call.

| Concern | Detail |
|---------|--------|
| Supabase | Same tables as above |
| Image download | Duplicate `download_image()` / `_supabase_public_url_bucket_key()` logic |
| **Must update for S3 images** | Same changes as `app/app.py` (consider shared module to avoid drift) |
| SSM / IAM | `/supabase/url`, `/supabase/anon`, Bedrock |

---

### 4. `ListBedrockRetryTasks` (`list_retry_tasks/app.py`)

**Role:** Lists tasks needing GenAI retry for Step Functions.

| Concern | Detail |
|---------|--------|
| Supabase | `task` table queries only |
| Storage / S3 | **No code change** for image storage migration (SSM URL/key only) |
| SSM / IAM | `/supabase/url`, `/supabase/anon` |

---

### 5. `ListBedrockBatchGroups` (`list_bedrock_batch_groups/app.py`)

**Role:** Lists product-grouped batch items for Step Functions.

| Concern | Detail |
|---------|--------|
| Supabase | `task` table queries only |
| Storage / S3 | **No code change** for image storage migration |
| SSM / IAM | `/supabase/url`, `/supabase/anon` |

---

## Supabase Storage → S3 SDK (image functions)

These functions **read binary image data** today. If product/shelf images move from Supabase Storage to S3, update download logic (not just SSM):

| File | Function | Current storage access |
|------|----------|------------------------|
| `app/app.py` | `download_image()` | `supabase.storage.from_(bucket).download()` + HTTP |
| `bedrock_batch_analyze/app.py` | `download_image()` | Same |
| `app/test_app.py` | Uses `analysis_app.download_image()` | Same |

### Recommended S3 download approach

1. **Convention for DB values** — e.g. store `s3://bucket/key` or `key` + env `IMAGES_S3_BUCKET`.
2. **Parse legacy URLs** — keep `_supabase_public_url_bucket_key()` during transition, or run a one-time DB backfill.
3. **IAM** — add `s3:GetObject` on the images bucket to `BedrockImageAnalysis`, `BedrockBatchAnalyze`, and test function policies.
4. **Remove HTTP fallback** where possible — S3 SDK avoids CDN/WAF issues already handled for Supabase URLs.

### Supabase storage buckets referenced in code

| Bucket name in code | Usage |
|---------------------|--------|
| `public` | Default bucket for relative image paths |
| Dynamic from URL | Parsed from `/storage/v1/object/public/{bucket}/{key}` |

---

## Files to touch (when implementing migration)

| File | Why |
|------|-----|
| `template.yaml` | Account ARNs, VPC, S3 IAM, optional images bucket parameter |
| `app/app.py` | S3 image download, artifacts bucket env var |
| `bedrock_batch_analyze/app.py` | S3 image download |
| `app/test_app.py` | Inherits `download_image` changes |
| `README.md` / `BEDROCK_SETUP.md` | Deploy URLs and setup steps |

**Copy / dead code (low priority):** `app/app copy.py` — duplicate of `app.py`; update or delete during cleanup.

---

## External dependencies (outside this folder)

- **Supabase project** — new URL, keys, replicated schema/RPCs, storage buckets (`public`, etc.) or deliberate move to S3-only
- **Postgres data** — `product_images.image_path`, `product.pref_url` (or equivalent) must point at reachable storage
- **Callers** of API Gateway analyze endpoints
- **EventBridge** — daily retry schedule re-created by template if `EnableBedrockRetrySchedule=true`

---

## Suggested migration order

1. Stand up new Supabase (or restore dump) + SSM params in new AWS account.
2. Migrate/copy image objects to S3; backfill or dual-read paths in DB.
3. Update `download_image()` + IAM for S3 reads; fix artifacts bucket env usage.
4. Deploy `template.yaml` to new account with new VPC params.
5. Enable Bedrock models; run test endpoint then production analyze.
6. Switch DNS/API callers to new API Gateway URL.
7. Decommission old account resources after soak period.

---

*Generated for infrastructure migration planning. Application code unchanged in this commit.*
