tia/CLAUDE.md
Mannu 3e66b259f2 Migrate medical data from localStorage to database
- Add database tables: medicines, allergies, doctor_visits, illness_logs
- Create API endpoints: /api/medicines, /api/allergies, /api/visits, /api/illnesses
- Update medical page to use database APIs instead of localStorage
- All medical data now persists across sessions and devices

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 21:07:26 +05:30

6.6 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commands

# Development
pnpm dev          # Start dev server at http://localhost:3000
pnpm build         # Production build
pnpm start         # Start production server

# Database (drizzle)
pnpm db:push      # Push schema to database
pnpm db:generate  # Generate drizzle types
pnpm db:studio   # Open DB studio (or use direct SQL)

# Docker
docker-compose -f docker-compose.dev.yml up -d    # Start local Postgres

Note: Running from /Users/manohar_air/MyProjects/Tia/tia directory.

Architecture

Tech Stack

  • Framework: Next.js 16 with App Router (src/app/)
  • Database: PostgreSQL 16 with pgvector + Drizzle ORM
  • Auth: NextAuth v5 (beta) with magic links
  • AI: LiteLLM gateway → MiniMax model (minimax-2.7)
  • Storage: Cloudflare R2 for media uploads
  • Styling: Tailwind CSS v4

Project Structure

src/
├── app/                    # Next.js App Router pages
│   ├── api/               # API routes (auth, logs, ai, growth, etc.)
│   ├── page.tsx            # Home (Quick Log + AI card)
│   ├── ai/               # AI chat page with sidebar
│   ├── medical/           # Vaccination tracking
│   ├── growth/           # Growth charts
│   ├── memories/         # Photo gallery
│   ├── menu/             # Navigation menu
│   ├── onboarding/      # First-time setup
│   ├── settings/          # Settings with theme picker
│   └── login/            # Magic link login
├── ThemeProvider.tsx       # Theme context (light/dark/system/time)
├── ThemeProvider
drizzle/                  # Database migrations
docs/                     # Design docs

Database

  • Migrations: SQL files in drizzle/ (not using drizzle-kit push)
  • Apply: psql directly or via docker-compose exec
  • RLS: Row-level security for multi-family isolation

Data Models

  • Family: Parent account container
  • Members: Adults in family (mom, dad, etc.)
  • Children: Baby profiles with birth date
  • Logs: Feed, sleep, diaper entries with timestamps
  • Vaccinations: IAP schedule tracking
  • Growth: Weight/height over time
  • Memories: Photos with R2 storage

Key Patterns

ThemeProvider: Wrap app in ThemeProvider from layout.tsx. Use useTheme() hook in components.

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.

Chat Sessions: Stored in localStorage (tia_chat_sessions) - shared between home page AI card and /ai page.

API Routes: Return standard JSON { success: true, items: [...] } format for lists.

AI Integration:

  • Route: /api/ai → LiteLLM at https://llm.manohargupta.com
  • Model: minimax-2.7
  • See /docs/debugging.md for troubleshooting

Data Storage Consistency

RULE: All user data must persist to database, NOT localStorage

Data Type Storage API Key Persists After Refresh Persists After Logout
Children Database /api/children Yes Yes
Activity Logs Database /api/logs Yes Yes
Vaccinations Database /api/vaccinations Yes Yes
Growth Records Database /api/growth Yes Yes
User Profile Database /api/auth/profile Yes Yes
Memories/Photos Database + R2 /api/upload Yes Yes
Medicines Database /api/medicines ⚠️ TODO ⚠️ TODO
Allergies Database /api/allergies ⚠️ TODO ⚠️ TODO
Doctor Visits Database /api/visits ⚠️ TODO ⚠️ TODO
Illness Log Database /api/illnesses ⚠️ TODO ⚠️ TODO
Theme localStorage tia_theme Yes Yes
Chat Sessions localStorage tia_chat_sessions Yes No
Offline Queue localStorage tia_offline_queue Yes No

localStorage acceptable for:

  • Theme preference (user-specific display only)
  • Temporary cache (offline queue for retry)
  • Chat sessions (upcoming feature: move to database)

NEVER use localStorage for:

  • Medical/health data (medicines, allergies, visits, illnesses)
  • Any data that should persist across devices
  • Data important for pediatrician visits

Audit (2026-05-10)

Current status - needs migration to database:

  • tia_medicines/api/medicines
  • tia_allergies/api/allergies
  • tia_visits/api/visits
  • tia_illnesses/api/illnesses

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

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

Set in .env.local for development, or in Dokploy dashboard for production.

Required:

  • DATABASE_URL - PostgreSQL connection
  • AUTH_SECRET - NextAuth secret
  • R2_ACCOUNT_ID - Cloudflare R2 account ID
  • R2_ACCESS_KEY_ID - R2 access key
  • R2_SECRET_ACCESS_KEY - R2 secret key
  • 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