93 lines
2.9 KiB
Markdown
93 lines
2.9 KiB
Markdown
# 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`
|