Update CLAUDE.md with R2 storage learnings
This commit is contained in:
parent
1495b9f88e
commit
070293498b
1 changed files with 69 additions and 13 deletions
82
CLAUDE.md
82
CLAUDE.md
|
|
@ -7,8 +7,8 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
||||||
```bash
|
```bash
|
||||||
# Development
|
# Development
|
||||||
pnpm dev # Start dev server at http://localhost:3000
|
pnpm dev # Start dev server at http://localhost:3000
|
||||||
pnpm build # Production build
|
pnpm build # Production build
|
||||||
pnpm start # Start production server
|
pnpm start # Start production server
|
||||||
|
|
||||||
# Database (drizzle)
|
# Database (drizzle)
|
||||||
pnpm db:push # Push schema to database
|
pnpm db:push # Push schema to database
|
||||||
|
|
@ -43,11 +43,12 @@ src/
|
||||||
│ ├── medical/ # Vaccination tracking
|
│ ├── medical/ # Vaccination tracking
|
||||||
│ ├── growth/ # Growth charts
|
│ ├── growth/ # Growth charts
|
||||||
│ ├── memories/ # Photo gallery
|
│ ├── memories/ # Photo gallery
|
||||||
│ ├── menu/ # Navigation menu
|
│ ├── menu/ # Navigation menu
|
||||||
│ ├── onboarding/ # First-time setup
|
│ ├── onboarding/ # First-time setup
|
||||||
│ └── login/ # Magic link login
|
│ ├── settings/ # Settings with theme picker
|
||||||
├── libs/ # Shared utilities (if any)
|
│ └── login/ # Magic link login
|
||||||
└── styles/ # Global styles
|
├── ThemeProvider.tsx # Theme context (light/dark/system/time)
|
||||||
|
├── ThemeProvider
|
||||||
drizzle/ # Database migrations
|
drizzle/ # Database migrations
|
||||||
docs/ # Design docs
|
docs/ # Design docs
|
||||||
```
|
```
|
||||||
|
|
@ -66,15 +67,24 @@ docs/ # Design docs
|
||||||
- **Logs:** Feed, sleep, diaper entries with timestamps
|
- **Logs:** Feed, sleep, diaper entries with timestamps
|
||||||
- **Vaccinations:** IAP schedule tracking
|
- **Vaccinations:** IAP schedule tracking
|
||||||
- **Growth:** Weight/height over time
|
- **Growth:** Weight/height over time
|
||||||
- **Memories:** Photos with vision AI tags
|
- **Memories:** Photos with R2 storage
|
||||||
|
|
||||||
### Key Patterns
|
### Key Patterns
|
||||||
|
|
||||||
|
**ThemeProvider:** Wrap app in ThemeProvider from layout.tsx. Use `useTheme()` hook in components.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { useTheme } from "./ThemeProvider";
|
||||||
|
const { theme, toggle, setMode } = useTheme();
|
||||||
|
// theme: "light" | "dark"
|
||||||
|
// mode: "light" | "dark" | "system" | "time"
|
||||||
|
```
|
||||||
|
|
||||||
**Offline Queue:** Uses localStorage (`tia_offline_queue`) for failed API calls, retries when online.
|
**Offline Queue:** Uses localStorage (`tia_offline_queue`) for failed API calls, retries when online.
|
||||||
|
|
||||||
**Chat Sessions:** Stored in localStorage (`tia_chat_sessions`) as array of sessions with messages. Shared between home page AI card and /ai page.
|
**Chat Sessions:** Stored in localStorage (`tia_chat_sessions`) - shared between home page AI card and /ai page.
|
||||||
|
|
||||||
**API Routes:** Return standard JSON `{ entries: [...] }` format for lists.
|
**API Routes:** Return standard JSON `{ success: true, items: [...] }` format for lists.
|
||||||
|
|
||||||
**AI Integration:**
|
**AI Integration:**
|
||||||
|
|
||||||
|
|
@ -82,17 +92,63 @@ docs/ # Design docs
|
||||||
- Model: `minimax-2.7`
|
- Model: `minimax-2.7`
|
||||||
- See `/docs/debugging.md` for troubleshooting
|
- See `/docs/debugging.md` for troubleshooting
|
||||||
|
|
||||||
|
## R2 Storage (Cloudflare)
|
||||||
|
|
||||||
|
### Setup
|
||||||
|
|
||||||
|
1. **Create bucket** in Cloudflare Dashboard → R2
|
||||||
|
2. **Create API token** with "Object Read & Write" permissions
|
||||||
|
3. **Enable Public Development URL** in bucket settings (gives pub-*.r2.dev URL)
|
||||||
|
|
||||||
|
### API Endpoint Format
|
||||||
|
|
||||||
|
The S3 API endpoint is: `https://<accountId>.r2.cloudflarestorage.com`
|
||||||
|
|
||||||
|
For your bucket named "tia":
|
||||||
|
- Account ID: `e71f22a2f8614fb3ba6d9b28a264d8ce`
|
||||||
|
- S3 Endpoint: `https://e71f22a2f8614fb3ba6d9b28a264d8ce.r2.cloudflarestorage.com`
|
||||||
|
- Public URL: `https://pub-37a76fd657c94d1dbc521a109c087a11.r2.dev` (no bucket name in path!)
|
||||||
|
|
||||||
|
### Code Example
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const client = new S3Client({
|
||||||
|
region: "auto",
|
||||||
|
endpoint: `https://${accountId}.r2.cloudflarestorage.com`,
|
||||||
|
credentials: { accessKeyId, secretAccessKey },
|
||||||
|
});
|
||||||
|
|
||||||
|
// List objects
|
||||||
|
const command = new ListObjectsV2Command({ Bucket: "tia" });
|
||||||
|
const res = await client.send(command);
|
||||||
|
|
||||||
|
// Get presigned upload URL
|
||||||
|
const command = new PutObjectCommand({ Bucket: "tia", Key: key, ContentType });
|
||||||
|
const url = await getSignedUrl(client, command, { expiresIn: 3600 });
|
||||||
|
```
|
||||||
|
|
||||||
|
### Key Learnings
|
||||||
|
|
||||||
|
1. **S3 API endpoint** does NOT include bucket name: `https://...r2.cloudflarestorage.com`
|
||||||
|
2. **Public URL** does NOT include bucket path: `https://pub-...r2.dev` (NOT `/tia/...`)
|
||||||
|
3. **CORS** needs GET and PUT methods for uploads
|
||||||
|
4. ListObjects needs bucket name in command, not endpoint
|
||||||
|
|
||||||
## Environment Variables
|
## Environment Variables
|
||||||
|
|
||||||
Set in `.env.local` for development, or in Dokploy dashboard for production.
|
Set in `.env.local` for development, or in Dokploy dashboard for production.
|
||||||
|
|
||||||
See `.env.example` for all required vars. Key ones:
|
Required:
|
||||||
|
|
||||||
- `DATABASE_URL` - PostgreSQL connection
|
- `DATABASE_URL` - PostgreSQL connection
|
||||||
- `AUTH_SECRET` - NextAuth secret
|
- `AUTH_SECRET` - NextAuth secret
|
||||||
- `LITELLM_BASE_URL` - AI gateway URL
|
|
||||||
- `LITELLM_API_KEY` - AI API key
|
|
||||||
- `R2_ACCOUNT_ID` - Cloudflare R2 account ID
|
- `R2_ACCOUNT_ID` - Cloudflare R2 account ID
|
||||||
- `R2_ACCESS_KEY_ID` - R2 access key
|
- `R2_ACCESS_KEY_ID` - R2 access key
|
||||||
- `R2_SECRET_ACCESS_KEY` - R2 secret key
|
- `R2_SECRET_ACCESS_KEY` - R2 secret key
|
||||||
- `R2_BUCKET_NAME` - R2 bucket name
|
- `R2_BUCKET_NAME` - R2 bucket name (e.g., "tia")
|
||||||
|
- `R2_PUBLIC_URL` - Public R2 URL (e.g., `https://pub-...r2.dev`)
|
||||||
|
|
||||||
|
Optional for AI:
|
||||||
|
|
||||||
|
- `LITELLM_BASE_URL` - AI gateway URL
|
||||||
|
- `LITELLM_API_KEY` - AI API key
|
||||||
Loading…
Add table
Reference in a new issue