# CLAUDE.md

This repository contains the GreenLens mobile app, the Express backend, and the self-hosted landing/deployment stack.

## Commands

### Mobile app
```bash
npm install
npm run start
npm run android
npm run ios
npm run test
```

### Backend
```bash
cd server
npm install
npm run start
npm run rebuild:batches
npm run diagnostics
```

### Production iOS builds
```bash
npx eas-cli build:version:set -p ios
npx eas-cli build -p ios --profile production
npx eas-cli submit -p ios --latest
```

## Architecture

### Mobile app
- Expo Router entrypoint: `app/_layout.tsx`
- Global app state: `context/AppContext.tsx`
- Backend HTTP client: `services/backend/backendApiClient.ts`
- In-app fallback mock: `services/backend/mockBackendService.ts`

### Backend
Single Express server in `server/index.js` with supporting modules in `server/lib/`:

- `postgres.js` for PostgreSQL access
- `sqlite.js` as a compatibility shim re-exporting the PostgreSQL layer
- `plants.js` for plant catalog persistence and diagnostics
- `auth.js` for JWT auth
- `billing.js` for credits, RevenueCat, Stripe, and idempotency
- `openai.js` for scan and health-check model calls
- `storage.js` for MinIO/S3 object uploads

Primary backend environment variables:

```bash
DATABASE_URL
POSTGRES_HOST
POSTGRES_PORT
POSTGRES_DB
POSTGRES_USER
POSTGRES_PASSWORD
JWT_SECRET
OPENAI_API_KEY
STRIPE_SECRET_KEY
MINIO_ENDPOINT
MINIO_ACCESS_KEY
MINIO_SECRET_KEY
MINIO_BUCKET
MINIO_PUBLIC_URL
```

### Landing and deployment
`greenlns-landing/` is a Next.js 16 app built with `output: 'standalone'`.

The production-style stack lives in `greenlns-landing/docker-compose.yml` and includes:

- `caddy` for TLS and reverse proxy
- `landing` for the Next.js app
- `api` for the Express backend
- `postgres` for persistent app data
- `minio` for object storage

`greenlns-landing/Caddyfile` routes:

- `/` to the landing app
- `/api/*`, `/auth/*`, `/v1/*`, `/health`, `/plants/*` to the Express API
- `/storage/*` to MinIO

## Data model notes

- PostgreSQL is the source of truth for server persistence.
- Nested plant metadata such as `categories` and `careInfo` uses `JSONB`.
- Billing idempotency responses also use `JSONB`.
- SQL placeholders use PostgreSQL syntax: `$1`, `$2`, ...
