> ## Documentation Index
> Fetch the complete documentation index at: https://docs.myfundingmachine.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Cloud agent starter skill

# Cloud Agent Starter Skill

Use this file when you need to run or test the repo in Cursor Cloud. It is intentionally short and practical.

## Read this first

1. Read `convex/_generated/ai/guidelines.md` before touching Convex code.
2. Check existing terminal sessions before starting long-running processes so you do not duplicate `bun run dev` or `bun run convex:dev`.
3. Use Bun for installs, dev servers, linting, and tests.

## Repo-wide setup

### Install and env

* Install dependencies with `bun install --frozen-lockfile` when `node_modules` is missing or stale.
* When secrets are injected into the shell (Cursor Cloud) but `.env.local` is missing, run `bun run env:sync-local -- --dev` to materialize the file from `process.env` without logging secret values. Use `--force` to overwrite an existing file, or `--dry-run` to preview which keys would be filled.
* Start Convex with `bun run convex:dev`. This is the normal way to generate or refresh `NEXT_PUBLIC_CONVEX_URL` in `.env.local`.
* Start Next.js with `bun run dev`.
* `bun run dev` uses `scripts/next-dev-with-fallback.ts`, so the app may start on port `3000` through `3010`. Read the server output to see which port won.
* If both servers are not already running, `bun run dev:all` starts Next + Convex together. Avoid `bun run dev:reset`; it uses a blanket process kill pattern that Cloud agents should not rely on.

### Minimum `.env.local` checklist

Copy values from `.env.example` or from the task context. The most common values agents need are:

* `NEXT_PUBLIC_CONVEX_URL`
* `CONVEX_SITE_URL` when HTTP actions need a non-default Convex host
* `NEXT_PUBLIC_APP_URL`
* `CONVEX_INTERNAL_SECRET`
* `ENCRYPTION_KEY`
* `GHL_APP_CLIENT_ID`
* `GHL_APP_CLIENT_SECRET`
* `GHL_APP_SSO_KEY`
* `GHL_API_DOMAIN`
* `GHL_ADMIN_LOCATION_ID`
* `CRON_SECRET`

### Fast smoke checks

* `curl http://127.0.0.1:<port>/api/auth/status` should return JSON, even when unauthenticated.
* If `/` does not redirect where you expect in dev, set `DEV_DEFAULT_LOCATION_ID` because `app/page.tsx` and `proxy.ts` both use it for localhost redirects.
* No Next.js route uses Clerk, so the Clerk keys are not needed in `.env.local`. `CLERK_JWT_ISSUER_DOMAIN` is still required as a **Convex** env var (`bunx convex env set CLERK_JWT_ISSUER_DOMAIN <value>`) because `convex/auth.config.ts` reads it; without it the Convex push fails.

## Codebase areas

### 1. Main app and admin (`app/(main)`, `app/admin`, `components/contact`, `components/funding-queue`)

#### Login and local bypass

* These areas normally expect a Lead Built / GHL session.
* For localhost-only Cloud testing without a real iframe session, set:
  * `ALLOW_LOCAL_DEV_AUTH_BYPASS=true`
  * `DEV_DEFAULT_LOCATION_ID=<real location id>`
* The bypass only works in development and only for localhost requests. It is implemented in `components/contact/contactLocalDevAuth.ts`.
* `useAuth` first checks `/api/auth/status`, then tries `POST /api/auth/location-session`, and redirects to `/setup-required` when the location is missing an installation.

#### Start and verify

* Open `/dashboard?location_id=<location>` for the main app.
* Open `/admin/metrics?locationId=<location>` or another admin route if you are testing admin-only behavior.
* If the app redirects unexpectedly, inspect `proxy.ts` before changing auth code.

#### Targeted test workflow

* Auth and routing:
  * `bun test tests/adminAuth.test.ts tests/adminLocation360Auth.test.ts tests/contactRedirectDomain.test.ts`
* Processing and funding queue:
  * `bun test tests/processingQueueFilters.test.ts tests/internalContactProcessingStatus.test.ts tests/fundingPlanAutosave.test.ts tests/fundingQueueBulkActions.test.ts`
* Credit reports and underwriting:
  * `bun test tests/adminCreditReportQuery.test.ts tests/creditReportHistory.test.ts tests/underwriting.test.ts tests/stitchCreditReportAccountFiltering.test.ts`

### 2. API routes and webhooks (`app/api/**`, `lib/auth`, `lib/utils`, `proxy.ts`)

#### Practical workflow

* Use `curl` for routes that do not require a browser.
* `GET /api/auth/status` is the easiest reachability check.
* `POST /api/auth/location-session` is the main session bootstrap path when a `location_id` is available but no stored session exists yet.
* Many API routes are blocked by the proxy unless the request has a valid session, an allowed origin, or is listed in `EXEMPT_PATHS` inside `proxy.ts`.
* Admin endpoints also validate origin + installation + `GHL_ADMIN_LOCATION_ID` in `lib/utils/admin-auth.ts`.

#### Targeted test workflow

* Auth and impersonation:
  * `bun test tests/adminAuth.test.ts tests/impersonationGuards.test.ts`
* Credit pull and history paths:
  * `bun test tests/creditPullContactSync.test.ts tests/creditPullNormalization.test.ts tests/creditReportErrors.test.ts tests/creditReportDownload.test.ts`
* Webhook-style behavior:
  * `bun test tests/appointmentStatus.test.ts`

### 3. Partner portal — removed (`convex/auth.config.ts` only)

* The Clerk-authenticated partner portal UI was removed in July 2026. There are no
  `/partner-portal` routes, components, or API endpoints, and `proxy.ts` no longer
  runs Clerk middleware. See `docs/archive/partner-portal.md`.
* Its Convex backend (`partnerOrganizations`, `partnerReferralLinks`,
  `partnerEarnings`) and `convex/auth.config.ts` are retained. `CLERK_JWT_ISSUER_DOMAIN`
  must still be set in Convex (`bunx convex env set CLERK_JWT_ISSUER_DOMAIN <value>`)
  or the Convex push fails at module-analysis time.
* Do not confuse this with the operator-facing Partner module at `/partners`, which is
  fully live.

### 4. Convex backend and data scripts (`convex/**`, `scripts/**`)

#### Practical workflow

* Keep `bun run convex:dev` running while editing Convex functions.
* `convex/auth.config.ts` still reads `CLERK_JWT_ISSUER_DOMAIN` from the Convex deployment; if a push fails at module-analysis time, check that value first.
* `scripts/seed-cards.ts` reads `.env.local` directly and requires `NEXT_PUBLIC_CONVEX_URL` plus a CSV path argument.
* `scripts/seed-demo-data.ts` loads `.env.local` with `dotenv` and uses:
  * `SEED_LOCATION_ID` (required — the script exits with instructions if it is missing, because seeding and `--clean` write to and delete from the real CRM location you name)
  * `SEED_ADMIN_EMAIL` (optional)

#### Targeted test workflow

* For shared Convex/UI behavior that already has Bun coverage:
  * `bun test tests/underwriting.test.ts tests/processingSubmissionStatusBackfill.test.ts tests/operatorInvoicesReadOnly.test.ts`
* For script runs:
  * `npx tsx scripts/seed-cards.ts ./data/cards.csv` # `seed-cards.ts` expects `tsx`, not `bun run`
  * `SEED_LOCATION_ID=<locationId> bun run scripts/seed-demo-data.ts` (or set it in `.env.local`)
* Prefer seeding only when the task needs realistic data; otherwise stick to targeted tests.

## Common gotchas

* There is no obvious central runtime feature flag system in the repo. The most useful local testing toggle is the auth bypass pair `ALLOW_LOCAL_DEV_AUTH_BYPASS=true` plus `DEV_DEFAULT_LOCATION_ID=<id>`.
* Every remaining route expects GHL/Lead Built context. The Clerk-authenticated partner portal was the one exception and it no longer exists.
* The app may not use port `3000`; read the dev server output before curling or opening localhost URLs.
* If a task only changes docs or small non-runtime strings, do not start the full app just to look busy. Validate the affected commands, file references, and nearby checks instead.

## Default quality gate

Use this when the area-specific tests are unclear or when you touched shared code:

* `bunx tsc --noEmit`
* `bun run lint`
* `bun test`

## How to update this skill

When you discover a useful testing trick, setup shortcut, or runbook fact:

1. Add it to the relevant codebase-area section instead of creating a random notes dump.
2. Prefer exact commands, routes, env vars, or file paths over prose.
3. Delete stale steps when the repo changes; do not leave multiple conflicting workflows.
4. If the new knowledge is required on every task, also add a one-line pointer in `AGENTS.md` and `CLAUDE.md`.
