# Local Development Guide

## Overview

The `dev.sh` script manages the local development environment for the Orchard Insights platform. It starts services in a tmux session with named windows, resolves dependencies automatically, and runs health checks to confirm services are responding.

## Prerequisites

Install the following tools before using the script:

```bash
brew install tmux node yarn pnpm python3 curl
```

Minimum versions:
- **Node.js** >= 20.11.1 (graphql-user requires this; graphql-product requires >= 24.0.0)
- **pnpm** 9.x (enforced by orchard-suite)
- **Python** 3.11+ (OWS services)
- **Rust** 1.94 (graphql-router only, install via `rustup`)

## First-Time Setup

Each service needs a `.env` file. The script will auto-copy `.env.shadow` to `.env` when missing, but you may need to add credentials manually:

```bash
# For each service you plan to run:
cd ~/Documents/Sony/<service-name>
cp .env.shadow .env
# Edit .env with your credentials (Snowflake keys, API tokens, etc.)
```

**Snowflake access** (required by OWS services):
- Place your private key at `~/.ssh/snowflake/rsa_key.p8`
- Set `SNOWFLAKE_USER`, `SNOWFLAKE_ACCOUNT`, etc. in each OWS `.env`

**VPN** is required for `frontend-insights` dev server.

## Quick Start

### Start a feature development stack

The most common workflow is developing a feature that touches an OWS service, a GraphQL subgraph, and the frontend:

```bash
./dev.sh --stack graphql-product
```

This resolves to: `ows-analytics` -> `graphql-product` -> `graphql-router` -> `frontend-insights`

### Start specific services manually

```bash
./dev.sh ows-analytics graphql-product graphql-router frontend-insights
```

### Check status

```bash
./dev.sh --status
```

### Stop everything

```bash
./dev.sh --stop
```

### List all services

```bash
./dev.sh --list
```

## Usage Reference

```
./dev.sh <service> [<service> ...]     Start specific services
./dev.sh --stack <service>             Start service + auto-resolved deps
./dev.sh --stop                        Stop all running services
./dev.sh --status                      Show status of running services
./dev.sh --list                        List all available services
./dev.sh --help                        Show help with examples
```

## Dependency Resolution

The `--stack` flag walks the dependency graph in both directions:

| Seed Service | Resolved Stack |
|--------------|----------------|
| `graphql-product` | ows-analytics, graphql-product, graphql-router, frontend-insights |
| `graphql-analytics` | ows-analytics, ows-charts, ows-playlist, graphql-analytics, graphql-router, frontend-insights |
| `graphql-knowledge-search` | graphql-knowledge-search, graphql-router, frontend-insights |
| `graphql-knowledge` | graphql-knowledge, graphql-router, frontend-insights |
| `graphql-user` | graphql-user, graphql-router, frontend-insights |
| `graphql-router` | graphql-router, frontend-insights |
| `frontend-insights` | graphql-router, frontend-insights |
| `ows-analytics` | ows-analytics (no downstream auto-add) |

**Upstream** dependencies are services that the seed service calls (e.g., graphql-product calls ows-analytics).

**Downstream** dependencies are added so you can test end-to-end (the router and frontend).

## Port Assignments

Several services share default ports. When running multiple services simultaneously, configure unique ports in each service's `.env` file:

| Service | Default Port | Recommended Local Port |
|---------|-------------|----------------------|
| frontend-insights | 8080 | 8080 |
| orchard-suite (Storybook) | 6006 | 6006 |
| graphql-router | 4000 | 4000 |
| graphql-analytics | 8084 | 8084 |
| graphql-knowledge-search | 8085 | 8085 |
| graphql-knowledge | 8086 | 8086 |
| graphql-product | 8087 | 8087 |
| graphql-user | 8088 | 8088 |
| ows-analytics | 5000 | 5001 |
| ows-charts | 5000 | 5002 |
| ows-playlist | 5000 | 5003 |

After changing ports in `.env` files, update `graphql-router/config-local.yaml` so the router knows where to find each subgraph.

The script detects port conflicts at startup and prompts for confirmation before proceeding.

## tmux Navigation

Once services are running, attach to the session:

```bash
tmux attach -t orchard-dev
```

| Shortcut | Action |
|----------|--------|
| `Ctrl-b n` | Next window |
| `Ctrl-b p` | Previous window |
| `Ctrl-b w` | List all windows (interactive picker) |
| `Ctrl-b d` | Detach (services keep running in background) |
| `Ctrl-b &` | Kill current window (stops that service) |

Each window is named after the service it runs, so `Ctrl-b w` gives you a clear list.

## Health Checks

After launching services, the script polls each service's health endpoint for up to 120 seconds:

| Status | Meaning |
|--------|---------|
| **running** | Health endpoint responded successfully |
| **listening** | Port is bound but health check failed (still starting) |
| **starting** | Not yet responding (within timeout) |
| **down** | Not responding after timeout |
| **batch** | Not a server (e.g., dbt-analytics) |

## Troubleshooting

### Service fails to start

1. Attach to tmux and check the service window for error output:
   ```bash
   tmux attach -t orchard-dev
   ```
2. Verify `.env` file exists and has the required variables.
3. For Node.js services: run `yarn install` in the service directory.
4. For Python services: run `pip install -r requirements.txt` or `pipenv install`.
5. For graphql-router: ensure Rust toolchain is installed and run `make supergraph`.

### Port already in use

```bash
# Find what is using a port
lsof -iTCP:8080 -sTCP:LISTEN

# Kill it
kill -9 <PID>
```

### tmux session already exists

```bash
./dev.sh --stop                    # Kill the existing session
./dev.sh --stack graphql-product   # Start fresh
```

### Health checks time out but service is running

Some services take longer than 120 seconds to start (especially on first run when installing dependencies). Attach to tmux to see progress. The services continue running even if health checks time out.

### graphql-router cannot compose supergraph

The router needs all referenced subgraphs' schemas. For local development:

1. Run `make supergraph` inside the graphql-router directory.
2. Ensure `config-local.yaml` points to the correct local ports for each subgraph.
3. Only the subgraphs you are running need to be reachable; others can point to QA URLs.
