# LysnrAI — Environment Variable Audit

> **Date:** 2026-02-12
> **Repo:** `learning_voice_ai_agent`
> **Method:** Scanned all `process.env.*` / `os.getenv()` usage in code and cross-referenced with each project's `.env` file.
> **Scan keyword:** `MISSING_ENV_VALUE` — grep across all `.env` files to find gaps.

---

## 1. Project → Env File Map

| # | Project | Env File | Port |
|---|---------|----------|------|
| 1 | Desktop app (`src/`) | `.env` (root) | — |
| 2 | Backend API (`backend/`) | `backend/.env` | 8000 |
| 3 | Admin Dashboard (`admin-dashboard-web/`) | `admin-dashboard-web/.env.local` | 3001 |
| 4 | User Dashboard (`user-dashboard-web/`) | `user-dashboard-web/.env.local` | 3002 |
| 5 | Tracker Dashboard (`tracker-dashboard-web/`) | `tracker-dashboard-web/.env.local` | 3003 |
| 6 | Billing Service (`services/billing-service/`) | `services/billing-service/.env` | 4002 |
| 7 | Growth Service (`services/growth-service/`) | `services/growth-service/.env` | 4001 |
| 8 | Platform Service (`services/platform-service/`) | `services/platform-service/.env` | 4003 |
| 9 | Tracker Service (`services/tracker-service/`) | `services/tracker-service/.env` | 4004 |

---

## 2. Quick Scan Command

```bash
# Find all gaps across the repo
grep -rn 'MISSING_ENV_VALUE' --include='.env*' --include='*.env' . | grep -v node_modules
```

---

## 3. Gaps Found (MISSING_ENV_VALUE)

### 3.1 Root `.env` (Desktop App)

| Variable | Status | Action |
|----------|--------|--------|
| `APPLICATIONINSIGHTS_CONNECTION_STRING` | ❌ Empty | Get from Azure Portal → Application Insights → Overview |
| `ANH_CONNECTION_STRING` | ⚠️ Has `YOUR_KEY_HERE` placeholder | Replace with real SharedAccessKey from Azure Portal → Notification Hubs |

### 3.2 `backend/.env`

| Variable | Status | Action |
|----------|--------|--------|
| `AZURE_EMAIL_CONNECTION_STRING` | ❌ Empty | Get from Azure Portal → Communication Services → Keys |
| `SMTP_HOST` | ❌ Empty | Configure if using SMTP fallback instead of Azure Communication Services |
| `SMTP_USER` | ❌ Empty | Configure if using SMTP fallback |
| `SMTP_PASS` | ❌ Empty | Configure if using SMTP fallback |

### 3.3 `admin-dashboard-web/.env.local`

| Variable | Status | Action |
|----------|--------|--------|
| `NEXT_PUBLIC_POSTHOG_KEY` | ❌ Empty | Get from PostHog → Project Settings (optional — analytics) |
| `NEXT_PUBLIC_POSTHOG_HOST` | ❌ Empty | Get from PostHog → Project Settings (optional — analytics) |

### 3.4 `user-dashboard-web/.env.local`

| Variable | Status | Action |
|----------|--------|--------|
| `ENTERPRISE_EMAIL_DOMAINS` | ❌ Empty | Set comma-separated list of domains that qualify for Enterprise SSO |
| `MICROSOFT_CLIENT_ID` | ❌ Empty | Register app in Azure Portal → Entra ID → App registrations |
| `MICROSOFT_CLIENT_SECRET` | ❌ Empty | Same as above |
| `GOOGLE_CLIENT_ID` | ❌ Empty | Register app in Google Cloud Console → Credentials |
| `GOOGLE_CLIENT_SECRET` | ❌ Empty | Same as above |
| `NEXT_PUBLIC_POSTHOG_KEY` | ❌ Empty | PostHog analytics (optional) |
| `NEXT_PUBLIC_POSTHOG_HOST` | ❌ Empty | PostHog analytics (optional) |

### 3.5 `tracker-dashboard-web/.env.local`

| Variable | Status | Action |
|----------|--------|--------|
| `NEXT_PUBLIC_POSTHOG_KEY` | ❌ Empty | PostHog analytics (optional) |
| `NEXT_PUBLIC_POSTHOG_HOST` | ❌ Empty | PostHog analytics (optional) |

### 3.6 `services/growth-service/.env`

| Variable | Status | Action |
|----------|--------|--------|
| `WEBHOOK_INVITATION_REDEEMED_URL` | ❌ Empty | Set to backend or platform-service webhook callback endpoint |
| `WEBHOOK_REFERRAL_STATUS_URL` | ❌ Empty | Set to backend or platform-service webhook callback endpoint |

### 3.7 `services/billing-service/.env`

| Variable | Status | Action |
|----------|--------|--------|
| `PLAN_LIMITS_JSON` | ❌ Empty | Optional — set JSON with per-plan limits if overriding defaults |

### 3.8 `services/platform-service/.env`

| Variable | Status | Action |
|----------|--------|--------|
| `RATE_LIMIT_CONFIG_JSON` | ❌ Empty | Optional — set JSON with per-endpoint rate limits if overriding defaults |

### 3.9 `services/tracker-service/.env`

✅ **No gaps** — all referenced env vars are present.

---

## 4. Vars Added With Real Values (This Audit)

These were missing from `.env` files but had known values, so they were filled in:

| Project | Variable | Value Added |
|---------|----------|-------------|
| Root `.env` | `PLATFORM_SERVICE_URL` | `http://localhost:4003` |
| Root `.env` | `LYSNR_API_URL` | `http://localhost:8000` |
| Root `.env` | `LYSNR_ADMIN_URL` | `http://localhost:3001` |
| Root `.env` | `LYSNR_DASHBOARD_URL` | `http://localhost:3002` |
| `backend/.env` | `BILLING_SERVICE_URL` | `http://localhost:4002` |
| `backend/.env` | `PLATFORM_SERVICE_URL` | `http://localhost:4003` |
| `backend/.env` | `CORS_ORIGINS` | Expanded to include all dashboard ports |
| `admin-dashboard-web/.env.local` | `STRIPE_PUBLISHABLE_KEY` | Test key (was missing) |
| `admin-dashboard-web/.env.local` | `STRIPE_WEBHOOK_SECRET` | Test key (was missing) |
| `admin-dashboard-web/.env.local` | `STRIPE_PRICE_PRO` | `price_1Szl2z...` |
| `admin-dashboard-web/.env.local` | `STRIPE_PRICE_ENTERPRISE` | `price_1Szl3D...` |
| `user-dashboard-web/.env.local` | `ENTERPRISE_EMAIL_DOMAINS` | Empty (needs config) |
| `services/billing-service/.env` | `USAGE_WARN_THRESHOLD` | `80` |

---

## 5. Cleanup Done

- **5 leftover `.example` files deleted:** `.env.example`, `backend/.env.example`, `admin-dashboard-web/.env.example`, `user-dashboard-web/.env.example`, `tracker-dashboard-web/.env.example`
- **All `.gitignore` files updated** to allow `.env` / `.env.local` to be committed (user preference)

---

## 6. Shared Secrets (Must Match Across Services)

These values **must be identical** across all services that use them:

| Secret | Used By |
|--------|---------|
| `JWT_SECRET` | All 4 Fastify services + all 3 dashboards + backend |
| `COSMOS_ENDPOINT` | All 4 Fastify services + admin + user dashboards + backend + desktop |
| `COSMOS_KEY` | Same as above |
| `COSMOS_DATABASE` | Same as above (must be `lysnrai`) |
| `STRIPE_SECRET_KEY` | billing-service, growth-service, admin-dashboard, user-dashboard |
| `AZURE_BLOB_*` | platform-service, admin-dashboard, user-dashboard, desktop |

---

## 7. Production Deployment Notes

When deploying to **Vercel** (frontends) + **Railway** (backends):

1. **JWT_SECRET** — rotate to a new 64-char hex. Must match across ALL services.
2. **CORS_ORIGIN** — set on each Fastify service to restrict to Vercel domains (comma-separated).
3. **Stripe webhook** — create a new webhook in Stripe Dashboard pointing to production URL; update `STRIPE_WEBHOOK_SECRET`.
4. **SSO redirect URIs** — update `MICROSOFT_REDIRECT_URI` and `GOOGLE_REDIRECT_URI` to production Vercel domain.
5. **NEXTAUTH_URL** — set to production Vercel domain for user-dashboard.
6. **Service URLs** — replace all `localhost:*` with Railway public URLs.
