# GreenLens Expo app for plant scanning, care tracking, lexicon browsing, and profile settings. ## Run locally 1. Install dependencies: - `npm install` 2. Start Expo: - `npm run start` ## iOS TestFlight (EAS) Use these three commands in order: 1. Set iOS build number: - `npx eas-cli build:version:set -p ios` 2. Create production iOS build: - `npx eas-cli build -p ios --profile production` 3. Submit latest iOS build to TestFlight: - `npx eas-cli submit -p ios --latest` ## Lexicon SQLite maintenance The server now uses a persistent SQLite database (`server/data/greenlns.sqlite`) and supports validated rebuilds. 1. Install server dependencies: - `cd server && npm install` 2. Run the server: - `npm run start` 3. Rebuild plants from the local lexicon batch constants: - `npm run rebuild:batches` 4. Check duplicates and import audits: - `npm run diagnostics` For protected rebuild endpoints, set `PLANT_IMPORT_ADMIN_KEY` and send `x-admin-key` in requests. ### Local plant images The lexicon now supports storing plant image paths in SQLite as local public paths instead of external URLs. Recommended structure: - Database field: `imageUri` - Value example: `/plants/monstera-deliciosa.webp` - File location on disk: `server/public/plants/monstera-deliciosa.webp` Notes: - The Express server serves `server/public/plants` at `/plants/*`. - Remote `https://...` image URLs still work, so migration can be incremental. - Keep the database focused on metadata and store only the image path, not binary blobs. ## Billing and backend simulation The app now uses a backend API contract for paid AI features: - Scan AI (`/v1/scan`) - Semantic AI search (`/v1/search/semantic`) - Billing summary (`/v1/billing/summary`) - Health check AI (`/v1/health-check`) The Node server in `server/index.js` now implements these `/v1` routes directly and uses: - `server/lib/openai.js` for OpenAI calls - `server/lib/billing.js` for credit/billing/idempotency state If `EXPO_PUBLIC_BACKEND_URL` is not set, the app uses an in-app mock backend simulation for `/v1/*` API calls. `EXPO_PUBLIC_PAYMENT_SERVER_URL` is used only for Stripe PaymentSheet calls (`/api/payment-sheet`). The in-app mock backend provides: - Server-side style credit enforcement - Atomic `consumeCredit()` behavior - Idempotency-key handling - Free and Pro monthly credit buckets - Top-up purchase simulation - RevenueCat/Stripe webhook simulation This makes it possible to build UI and flow now, then replace mock endpoints with a real backend later. ## Production integration notes - Keep OpenAI keys only on the backend. - Use app-store billing via RevenueCat or StoreKit/Play Billing. - Forward entitlement updates to backend webhooks. - Enforce credits on backend only; app should only display UX quota. - Recommended backend env vars: - `OPENAI_API_KEY` - `OPENAI_SCAN_MODEL` (for example `gpt-5`) - `OPENAI_HEALTH_MODEL` (for example `gpt-5`) - `STRIPE_SECRET_KEY` - `STRIPE_PUBLISHABLE_KEY`