mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-06-08 11:37:25 +00:00
98 lines
3.2 KiB
Markdown
98 lines
3.2 KiB
Markdown
# Bulk Address Upload — Implementation Tracker
|
|
|
|
## Overview
|
|
|
|
Upload CSV/XLSX to S3 (browser-direct via XHR with progress bar) → confirm in DB → redirect to upload list.
|
|
Portfolio shows all uploads ordered by date. User picks which to continue.
|
|
|
|
---
|
|
|
|
## DB Migration (manual — do this first)
|
|
|
|
```sql
|
|
CREATE TABLE bulk_address_uploads (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
portfolio_id TEXT NOT NULL,
|
|
user_id TEXT NOT NULL,
|
|
s3_bucket TEXT NOT NULL,
|
|
s3_key TEXT NOT NULL,
|
|
filename TEXT NOT NULL,
|
|
status TEXT NOT NULL DEFAULT 'ready_for_processing',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
```
|
|
|
|
Status values: `ready_for_processing` | `processing` | `complete` | `failed`
|
|
|
|
- [ ] Migration applied to dev
|
|
- [ ] Migration applied to staging
|
|
- [ ] Migration applied to prod
|
|
|
|
---
|
|
|
|
## Tasks
|
|
|
|
### 1. Drizzle Schema
|
|
- [ ] Create `src/app/db/schema/bulk_address_uploads.ts`
|
|
- [ ] Import + spread into `src/app/db/db.ts`
|
|
|
|
### 2. Confirm API Route
|
|
- [ ] Create `src/app/api/upload/bulk-addresses/confirm/route.ts`
|
|
- POST `{ fileKey, filename, portfolioId, userId }`
|
|
- Inserts into `bulk_address_uploads`, `s3Bucket` from `RETROFIT_PLAN_INPUT_BUCKET_NAME` env
|
|
- Returns `{ id, s3Key, s3Bucket, status }`
|
|
|
|
### 3. List API Route
|
|
- [ ] Create `src/app/api/portfolio/[portfolioId]/bulk-uploads/route.ts`
|
|
- GET → all uploads for portfolio ordered by `created_at DESC`
|
|
- Returns array of upload records
|
|
|
|
### 4. Modal — XHR Upload + Progress + Redirect to List
|
|
- [ ] Replace `fetch` PUT → `XMLHttpRequest` in `handleUpload`
|
|
- [ ] Add `progress: number | null` state
|
|
- [ ] Show progress bar in dropzone while uploading
|
|
- [ ] After XHR load: POST confirm → `router.push(/portfolio/[id]/bulk-upload)`
|
|
|
|
### 5. Upload List Page
|
|
- [ ] Create `src/app/portfolio/[portfolioId]/bulk-upload/page.tsx`
|
|
- Server component
|
|
- List all uploads: filename, status badge, created date, "Continue →" link
|
|
- Empty state if none
|
|
- Each row links to `/bulk-upload/[uploadId]`
|
|
|
|
### 6. Upload Detail Page
|
|
- [ ] Create `src/app/portfolio/[portfolioId]/bulk-upload/[uploadId]/page.tsx`
|
|
- Server component
|
|
- Shows: filename, `s3://bucket/key`, status, created date
|
|
- For now: "Your file is queued for processing"
|
|
|
|
---
|
|
|
|
## Flow
|
|
|
|
```
|
|
User drops/clicks file
|
|
→ validate (size, extension, headers)
|
|
→ GET presigned URL (/api/upload/bulk-addresses)
|
|
→ XHR PUT to S3 (progress bar shown)
|
|
→ POST confirm (/api/upload/bulk-addresses/confirm)
|
|
→ redirect to list (/portfolio/[id]/bulk-upload)
|
|
→ list page (all uploads, status badges, click to continue)
|
|
→ detail page (/portfolio/[id]/bulk-upload/[uploadId])
|
|
→ shows s3_uri + status
|
|
```
|
|
|
|
---
|
|
|
|
## Files Touched
|
|
|
|
| File | Status |
|
|
|------|--------|
|
|
| `src/app/db/schema/bulk_address_uploads.ts` | not started |
|
|
| `src/app/db/db.ts` | not started |
|
|
| `src/app/api/upload/bulk-addresses/confirm/route.ts` | not started |
|
|
| `src/app/api/portfolio/[portfolioId]/bulk-uploads/route.ts` | not started |
|
|
| `src/app/components/portfolio/BulkUploadComingSoonModal.tsx` | not started |
|
|
| `src/app/portfolio/[portfolioId]/bulk-upload/page.tsx` | not started |
|
|
| `src/app/portfolio/[portfolioId]/bulk-upload/[uploadId]/page.tsx` | not started |
|