managarten/docs/ENVIRONMENT_VARIABLES.md
Till JS c5aeaf5e7f feat(memoro): voice recording → mana-stt transcription pipeline
Adds end-to-end browser voice capture for the Memoro module, mirroring the
existing dreams pattern: MediaRecorder → SvelteKit server proxy → mana-stt
on the Windows GPU box via Cloudflare tunnel.

Recording UI lives in /memoro page header (mic button + live timer + cancel +
sticky-permission retry). Server proxy at /api/v1/memoro/transcribe forwards
the blob with the server-held X-API-Key. memosStore.createFromVoice creates a
placeholder memo with processingStatus='processing' and fires transcribeBlob
in the background, which writes the transcript and flips status on completion
(or 'failed' with error in metadata).

Also corrects the mana-stt hostname across the repo: stt-api.mana.how (which
never existed in DNS) → gpu-stt.mana.how (the actual Cloudflare tunnel route
to the Windows GPU box). Adds an ENVIRONMENT_VARIABLES.md section explaining
how to obtain MANA_STT_API_KEY and where the tunnel terminates. Adds tunnel
health probes to the mac-mini health-check script so we catch tunnel-side
breakage in addition to LAN-side.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 18:48:41 +02:00

258 lines
8.1 KiB
Markdown

# Environment Variables Guide
This document explains the centralized environment variable system for the Mana monorepo.
## Quick Start
```bash
# After cloning the repo, install dependencies (auto-generates .env files)
pnpm install
# Or manually generate .env files
pnpm setup:env
```
That's it! All app-specific `.env` files are generated from `.env.development`.
## How It Works
```
.env.development # Central config (committed)
scripts/generate-env.mjs # Transforms variables
apps/**/apps/**/.env # Generated files (gitignored)
```
The generator reads `.env.development` and creates app-specific `.env` files with the correct prefixes for each platform:
| Platform | Prefix | Example |
|----------|--------|---------|
| Expo (mobile) | `EXPO_PUBLIC_` | `EXPO_PUBLIC_SUPABASE_URL` |
| SvelteKit (web) | `PUBLIC_` | `PUBLIC_SUPABASE_URL` |
| Hono/Bun (server) | None | `DATABASE_URL` |
## File Locations
### Source File
- **`.env.development`** - Single source of truth, committed to git
### Generated Files (gitignored)
- `services/mana-auth/.env`
- `apps/chat/apps/server/.env`
- `apps/chat/apps/mobile/.env`
- `apps/chat/apps/web/.env`
- `apps/mana/apps/mobile/.env`
- `apps/mana/apps/web/.env`
- `apps/cards/apps/server/.env`
- `apps/cards/apps/web/.env`
- `apps/*/apps/server/.env` (all apps with compute servers)
- `apps/*/apps/web/.env` (all web apps)
- `apps/*/apps/mobile/.env` (all mobile apps)
## Variable Reference
### Shared Variables
| Variable | Description | Used By |
|----------|-------------|---------|
| `MANA_AUTH_URL` | Auth service URL | All apps |
| `JWT_PRIVATE_KEY` | JWT signing key | mana-auth |
| `JWT_PUBLIC_KEY` | JWT verification key | All backends |
| `POSTGRES_USER` | Database user | Docker, backends |
| `POSTGRES_PASSWORD` | Database password | Docker, backends |
| `REDIS_HOST` | Redis host | mana-auth |
| `REDIS_PORT` | Redis port | mana-auth |
| `REDIS_PASSWORD` | Redis password | mana-auth |
### Mana Auth Service
| Variable | Description | Default |
|----------|-------------|---------|
| `MANA_AUTH_PORT` | Service port | `3001` |
| `MANA_AUTH_DATABASE_URL` | PostgreSQL connection string | - |
| `JWT_ACCESS_TOKEN_EXPIRY` | Access token TTL | `15m` |
| `JWT_REFRESH_TOKEN_EXPIRY` | Refresh token TTL | `7d` |
| `JWT_ISSUER` | JWT issuer claim | `mana` |
| `JWT_AUDIENCE` | JWT audience claim | `mana` |
| `STRIPE_SECRET_KEY` | Stripe secret key | - |
| `STRIPE_PUBLISHABLE_KEY` | Stripe publishable key | - |
| `STRIPE_WEBHOOK_SECRET` | Stripe webhook secret | - |
| `CORS_ORIGINS` | Allowed CORS origins | - |
| `RATE_LIMIT_TTL` | Rate limit window (seconds) | `60` |
| `RATE_LIMIT_MAX` | Max requests per window | `100` |
### Chat Project
| Variable | Description | Default |
|----------|-------------|---------|
| `CHAT_BACKEND_PORT` | Backend service port | `3002` |
| `CHAT_DATABASE_URL` | PostgreSQL connection string | - |
| `AZURE_OPENAI_ENDPOINT` | Azure OpenAI endpoint URL | - |
| `AZURE_OPENAI_API_KEY` | Azure OpenAI API key | - |
| `AZURE_OPENAI_API_VERSION` | API version | `2024-12-01-preview` |
| `CHAT_SUPABASE_URL` | Supabase project URL | - |
| `CHAT_SUPABASE_ANON_KEY` | Supabase anonymous key | - |
### Mana Project
| Variable | Description |
|----------|-------------|
| `MANA_SUPABASE_URL` | Supabase project URL |
| `MANA_SUPABASE_ANON_KEY` | Supabase anonymous key |
### Cards Project
| Variable | Description | Default |
|----------|-------------|---------|
| `CARDS_BACKEND_PORT` | Backend service port | `3004` |
| `CARDS_SUPABASE_URL` | Supabase project URL | - |
| `CARDS_SUPABASE_ANON_KEY` | Supabase anonymous key | - |
### Speech-to-Text (mana-stt)
Used by the unified Mana web app's voice features (Memoro recording, Dreams voice capture, etc).
The browser never talks to mana-stt directly — requests go through the SvelteKit server-side proxy
(`/api/v1/memoro/transcribe`, `/api/v1/dreams/transcribe`) which attaches the API key from
`MANA_STT_API_KEY`. Keep that key out of the browser bundle.
| Variable | Description | Default |
|----------|-------------|---------|
| `STT_URL` | Public mana-stt URL — generates `MANA_STT_URL` for the web app | `https://gpu-stt.mana.how` |
| `MANA_STT_API_KEY` | API key for mana-stt. **Never commit a real value.** | _(empty)_ |
**Where to obtain a key:**
- Production deploy: set `MANA_STT_API_KEY` in the Mac Mini's `.env` (sourced by
`docker-compose.macmini.yml`, line ~1076). The key lives on the Windows GPU box in
`services/mana-stt/.env` under `API_KEYS=<key>:<name>` and is the source of truth.
- Local dev: paste the dev key into your local `apps/mana/apps/web/.env` after running
`pnpm setup:env` (the generator only writes an empty placeholder). Ask in `#mana-dev` or
pull from the team's password manager under `mana-stt → web-key`.
- New dev key: SSH to the Windows GPU box (`ssh mana-gpu`), append a new entry to
`C:\mana\services\mana-stt\.env` `API_KEYS` (format: `<random>:<name>`), restart the
`ManaSTT` scheduled task. Use a fresh key per consumer (`mana-web`, `chat-server`, etc.)
so we can revoke individually.
**Endpoint:** `https://gpu-stt.mana.how` — Cloudflare Tunnel `mana-gpu-server`
Windows GPU box (`192.168.178.11:3020`). Health: `curl https://gpu-stt.mana.how/health`.
## Adding New Variables
### Step 1: Add to `.env.development`
```bash
# In .env.development
MY_NEW_PROJECT_API_KEY=your-api-key
MY_NEW_PROJECT_URL=https://api.example.com
```
### Step 2: Update the Generator Script
Edit `scripts/generate-env.mjs` and add your app config:
```javascript
// In APP_CONFIGS array
{
path: 'apps/my-project/apps/mobile/.env',
vars: {
// For Expo, add EXPO_PUBLIC_ prefix
EXPO_PUBLIC_API_KEY: (env) => env.MY_NEW_PROJECT_API_KEY,
EXPO_PUBLIC_API_URL: (env) => env.MY_NEW_PROJECT_URL,
},
},
{
path: 'apps/my-project/apps/web/.env',
vars: {
// For SvelteKit, add PUBLIC_ prefix
PUBLIC_API_KEY: (env) => env.MY_NEW_PROJECT_API_KEY,
PUBLIC_API_URL: (env) => env.MY_NEW_PROJECT_URL,
},
},
{
path: 'apps/my-project/apps/server/.env',
vars: {
// For Hono/Bun servers, no prefix needed
API_KEY: (env) => env.MY_NEW_PROJECT_API_KEY,
API_URL: (env) => env.MY_NEW_PROJECT_URL,
},
},
```
### Step 3: Regenerate
```bash
pnpm setup:env
```
## Local Overrides
If you need to override variables locally without affecting others:
1. The generated `.env` files are gitignored
2. You can manually edit them after generation
3. Or create `.env.local` files (also gitignored) that some frameworks auto-load
**Note:** Running `pnpm setup:env` will overwrite your changes, so use `.env.local` for persistent overrides.
## Docker Integration
The root `.env.development` is also used by Docker Compose:
```bash
# Start all services with shared env
pnpm docker:up:all
```
Docker services read from:
- Root `.env.development` for shared values
- Service-specific `.env` files for service-specific values
## Troubleshooting
### "Variable is undefined" Error
1. Check if the variable exists in `.env.development`
2. Run `pnpm setup:env` to regenerate
3. Restart your dev server (env changes require restart)
### Generated File Has Wrong Value
1. Check the mapping in `scripts/generate-env.mjs`
2. Ensure the source variable name matches exactly
3. Run `pnpm setup:env` again
### New App Not Getting Generated
1. Add app config to `APP_CONFIGS` in `scripts/generate-env.mjs`
2. Ensure the target directory exists
3. Run `pnpm setup:env`
### Expo Not Picking Up Changes
Expo caches environment variables. Clear the cache:
```bash
cd apps/<project>/apps/mobile
npx expo start -c
```
## Security Notes
- `.env.development` contains **development-only** values
- Never put production secrets in this file
- The JWT keys in `.env.development` are for local development only
- Use separate secrets management for production (1Password, AWS Secrets Manager, etc.)
## Migration from Old System
If you have existing `.env` files with real values:
1. Copy important values to `.env.development`
2. Delete the old `.env` files
3. Run `pnpm setup:env`
4. Verify apps still work
The old `.env.example` files can remain as documentation.