# GreenLens

Expo app for plant scanning, care tracking, billing, and profile management, backed by an Express API.

## App development

```bash
npm install
npm run start
```

## Backend development

The backend now targets PostgreSQL instead of SQLite.

```bash
cd server
npm install
npm run start
```

Required backend environment:

- `DATABASE_URL` or `POSTGRES_HOST` + `POSTGRES_PORT` + `POSTGRES_DB` + `POSTGRES_USER` + `POSTGRES_PASSWORD`
- `JWT_SECRET`

Optional integrations:

- `OPENAI_API_KEY`
- `REVENUECAT_WEBHOOK_SECRET`
- `PLANT_IMPORT_ADMIN_KEY`
- `MINIO_ENDPOINT`
- `MINIO_ACCESS_KEY`
- `MINIO_SECRET_KEY`
- `MINIO_BUCKET`
- `MINIO_PUBLIC_URL`

## Docker Compose

For backend-only local infrastructure use [docker-compose.yml](/abs/path/C:/Users/a931627/Documents/apps/GreenLns/docker-compose.yml).

For the production-style self-hosted stack with landing page, API, PostgreSQL, and MinIO behind an external reverse proxy use [greenlns-landing/docker-compose.yml](/abs/path/C:/Users/a931627/Documents/apps/GreenLns/greenlns-landing/docker-compose.yml).

## Server deployment

Run the commands in this section from the repo root on your server:

```bash
cd /path/to/GreenLns
```

Example:

```bash
cd /var/www/GreenLns
```

### 1. Prepare environment

```bash
cp .env.example .env
```

Then fill at least:

- `SITE_DOMAIN`
- `SITE_URL`
- `POSTGRES_PASSWORD`
- `JWT_SECRET`
- `MINIO_SECRET_KEY`
- optional: `OPENAI_API_KEY`, `REVENUECAT_*`

### 2. Start the full production stack

```bash
docker compose up --build -d
```

When you run this from the repo root, Docker Compose uses [docker-compose.yml](/abs/path/C:/Users/a931627/Documents/apps/GreenLns/docker-compose.yml).

What gets built:

- `landing` is built from `./greenlns-landing/Dockerfile`
- `api` is built from `./server/Dockerfile`

What is not built locally, but pulled as ready-made images:

- `postgres` uses `postgres:16-alpine`
- `minio` uses `minio/minio:latest`

So yes: `docker compose up --build -d` builds the landing page container and the API container, and it starts PostgreSQL as a container. PostgreSQL is not "built" from your code, it is started from the official Postgres image.

This starts:

- `landing`
- `api`
- `postgres`
- `minio`

Host ports for an external reverse proxy:

- `3000` -> `landing`
- `3003` -> `api`
- `9000` -> `minio` S3 API
- `9001` -> `minio` console

### 3. Useful server commands

Check running containers:

```bash
docker compose ps
```

Follow all logs:

```bash
docker compose logs -f
```

Follow only API logs:

```bash
docker compose logs -f api
```

Follow only landing logs:

```bash
docker compose logs -f landing
```

Restart one service:

```bash
docker compose restart api
docker compose restart landing
```

Rebuild and restart after code changes:

```bash
docker compose up --build -d
```

Stop the stack:

```bash
docker compose down
```

Stop the stack and remove volumes:

```bash
docker compose down -v
```

### 4. Health checks after deploy

```bash
curl https://greenlenspro.com/health
curl https://greenlenspro.com/
curl https://greenlenspro.com/sitemap.xml
```

### 5. Production compose file location

If you want to run the same stack from inside the landing directory instead:

```bash
cd greenlns-landing
docker compose up --build -d
```

In that case Docker Compose uses [greenlns-landing/docker-compose.yml](/abs/path/C:/Users/a931627/Documents/apps/GreenLns/greenlns-landing/docker-compose.yml).

There, too:

- `landing` is built from `greenlns-landing/Dockerfile`
- `api` is built from `../server/Dockerfile`
- `postgres` and `minio` are started from official images

## iOS TestFlight

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