# 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 the current stack:

- **Vercel** for public/front-end surfaces where applicable
- **Azure VM / shared infra** for backend and internal service hosting

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 the current production API and service URLs.
