docs: refresh stale docs to match current implementation

Documentation pass — reviewed codebase in full, identified stale references,
and aligned docs with actual code state.

Changes:
- CLAUDE.md, PRODUCTION_SETUP.md, LAUNCH_CHECKLIST.md, src/auth.config.ts:
  middleware path src/middleware.ts → src/proxy.ts (Next.js 16+ convention)
- CLAUDE.md, ENVIRONMENT.md, README.md:
  dev server port localhost:3000 → localhost:4000 (per package.json dev
  script 'next dev --webpack -H 0.0.0.0 -p 4000')
- PRODUCTION_DEPLOYMENT_CHECKLIST.md:
  rewrote migration list — actual db/migrations/ contains 10 files
  (0000–0091), not the Supabase-era 001–092 series. Updated platform
  version 1.6 → 2.0 and last-updated stamp.
- MEMORY.md:
  refreshed 'Last updated' to 2026-06-25, added current-state header
  flagging Auth.js v5 wiring as historical, and documented the SSH/Gitea
  workflow (id_ed25519_crispygoat + no API token → push-hook URL flow
  for opening PRs).
- LAUNCH_CHECKLIST.md:
  added 'Last updated: 2026-06-25' header and refresh note in footer.
- CLAUDE.md:
  new 'Gitea authentication (SSH)' subsection under 'Canonical Remote'
  documenting ~/.ssh/id_ed25519_crispygoat, ssh-agent setup, what works
  (git push) vs what doesn't (REST API without token), and the actual
  PR-creation workflow (push + open the URL the Gitea hook prints).

Verification:
- npx tsc --noEmit: pre-existing Stripe API version + test mock errors
  only (verified by stashing changes and re-running — same error set).
- No new errors introduced.
This commit is contained in:
Nora
2026-06-25 20:13:19 -06:00
parent b018f2be5b
commit 95eab42f4b
8 changed files with 68 additions and 41 deletions
+36 -4
View File
@@ -12,6 +12,38 @@ There is exactly one remote — `origin` — pointing to the self-hosted Gitea r
Do **not** add GitHub remotes. There is no `origin` on github.com and no separate "dev" repo. If you see `github.com/dzinesco/*` URLs in `.git/config`, that is stale configuration from a previous fork and should be removed (`git remote remove`). Do **not** add GitHub remotes. There is no `origin` on github.com and no separate "dev" repo. If you see `github.com/dzinesco/*` URLs in `.git/config`, that is stale configuration from a previous fork and should be removed (`git remote remove`).
### Gitea authentication (SSH)
This workspace has been using Gitea via SSH for all operations. The Gitea instance is self-hosted at `git.crispygoat.com` (web UI: `https://git.crispygoat.com`, API base: `https://git.crispygoat.com/api/v1`).
**SSH key:** `~/.ssh/id_ed25519_crispygoat` is the dedicated key registered with the Gitea instance (alias `dog` per the Gitea SSH banner). Add it to the agent before any git operation:
```bash
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519_crispygoat
```
The SSH config (`~/.ssh/config`) already aliases the host as `crispygoat` with `AddKeysToAgent yes`, so subsequent shells can just `ssh crispygoat` / `git push origin ...` without re-adding.
**Verified working commands:**
- `git push origin <branch>` — push (this is the primary workflow)
- `ssh -p 22 git@git.crispygoat.com` — auth check; Gitea returns "successfully authenticated" + "Gitea does not provide shell access"
**API token:** This environment does **not** have a Gitea personal access token in any known location (no `~/.config/gitea`, no `GITEA_ACCESS_TOKEN` env, no token in `~/.config/gh/hosts.yml`). Do not assume a token is available — auth attempts will return `{"message":"invalid username, password or token"}`.
**`tea` CLI / `gitea-mcp`:** Both are installed but require a token; `--ssh-agent-key` is recognized by `tea logins add` but the underlying SDK still falls back to requiring a token. Treat these as unavailable until a token is provisioned.
### Opening pull requests (the workflow that actually works)
Because no Gitea API token is available in this environment, the PR creation flow is:
1. Create a feature branch: `git checkout -b docs/<date>-<description>`
2. Commit the changes (no need to commit unrelated files — leave the worktree dirty but `git add` only what you intend to ship)
3. Push: `git push -u origin <branch>`
4. The Gitea push hook prints a "Create a new pull request" URL on stderr, e.g. `https://git.crispygoat.com/tyler/route-commerce/pulls/new/<branch>` — open that URL in a browser to file the PR through the web UI.
If a future environment provides a Gitea token, the `tea pr create` and `curl POST /api/v1/repos/tyler/route-commerce/pulls` flows become available; the auth pattern is `Authorization: token <TOKEN>` on the REST API or `tea logins add -t <TOKEN> -u https://git.crispygoat.com` for the CLI.
## Project Overview ## Project Overview
Route Commerce is a multi-tenant B2B e-commerce platform for fresh produce wholesale distribution. Brands sell to customers who pick up at scheduled stops or receive shipments. The platform includes admin dashboards for order management, stop/route scheduling, product catalogs, payment processing (Stripe + Square), and a communications module ("Harvest Reach") for email/SMS campaigns. Route Commerce is a multi-tenant B2B e-commerce platform for fresh produce wholesale distribution. Brands sell to customers who pick up at scheduled stops or receive shipments. The platform includes admin dashboards for order management, stop/route scheduling, product catalogs, payment processing (Stripe + Square), and a communications module ("Harvest Reach") for email/SMS campaigns.
@@ -38,7 +70,7 @@ npx playwright test # Run E2E tests (Playwright)
**Historical migration work is documented in `MEMORY.md`** (Supabase login + link process, updates to `push-migrations.js` for the modern CLI, specific SQL patches made to 091/145/148/200/201 so they would apply cleanly, and which migrations were pushed). Cat `MEMORY.md` for details. **Historical migration work is documented in `MEMORY.md`** (Supabase login + link process, updates to `push-migrations.js` for the modern CLI, specific SQL patches made to 091/145/148/200/201 so they would apply cleanly, and which migrations were pushed). Cat `MEMORY.md` for details.
E2E tests live in `tests/` and run via Playwright. Specs include `tests/smoke.spec.ts` and `tests/login/login-flow.spec.ts`. **Note: `playwright.config.ts` defaults `baseURL` to production** (`https://route-commerce-platform.vercel.app`); override with `PLAYWRIGHT_URL=http://localhost:3000` for local runs, or pass `--config` with a local config. E2E tests live in `tests/` and run via Playwright. Specs include `tests/smoke.spec.ts` and `tests/login/login-flow.spec.ts`. **Note: `playwright.config.ts` defaults `baseURL` to production** (`https://route-commerce-platform.vercel.app`); override with `PLAYWRIGHT_URL=http://localhost:4000` for local runs (the dev server binds to port `4000`), or pass `--config` with a local config.
--- ---
@@ -51,12 +83,12 @@ E2E tests live in `tests/` and run via Playwright. Specs include `tests/smoke.sp
**Auth flow:** **Auth flow:**
1. User signs in via `/api/auth/sign-in` → Neon Auth validates credentials → session cookie set 1. User signs in via `/api/auth/sign-in` → Neon Auth validates credentials → session cookie set
2. `getAdminUser()` in `src/lib/admin-permissions.ts` reads the Neon Auth session and looks up `admin_users` by email 2. `getAdminUser()` in `src/lib/admin-permissions.ts` reads the Neon Auth session and looks up `admin_users` by email
3. Middleware (`src/middleware.ts`) guards `/admin/*` routes at the edge level 3. Middleware (`src/proxy.ts`) guards `/admin/*` routes at the edge level
**Key files:** **Key files:**
- `src/lib/auth.ts` — Neon Auth configuration (getSession, signIn, signOut, resetPassword, requestPasswordReset) - `src/lib/auth.ts` — Neon Auth configuration (getSession, signIn, signOut, resetPassword, requestPasswordReset)
- `src/auth.config.ts` — Edge-safe config (baseUrl, cookieSecret) - `src/auth.config.ts` — Edge-safe config (baseUrl, cookieSecret)
- `src/middleware.ts` — Edge-level route protection - `src/proxy.ts` — Edge-level route protection
- `src/app/api/auth/sign-in/route.ts` — Email/password sign-in API - `src/app/api/auth/sign-in/route.ts` — Email/password sign-in API
- `src/app/api/auth/forgot-password/route.ts` — Password reset request API - `src/app/api/auth/forgot-password/route.ts` — Password reset request API
- `src/app/api/auth/reset-password/route.ts` — Password reset confirmation API - `src/app/api/auth/reset-password/route.ts` — Password reset confirmation API
@@ -300,7 +332,7 @@ Separate from orders/stops — tracks irrigation/water usage per brand. `src/act
| Neon Auth configuration | `src/lib/auth.ts`, `src/auth.config.ts` | | Neon Auth configuration | `src/lib/auth.ts`, `src/auth.config.ts` |
| Auth API routes | `src/app/api/auth/sign-in/route.ts`, `src/app/api/auth/forgot-password/route.ts`, `src/app/api/auth/reset-password/route.ts`, `src/app/api/auth/[...nextauth]/route.ts` | | Auth API routes | `src/app/api/auth/sign-in/route.ts`, `src/app/api/auth/forgot-password/route.ts`, `src/app/api/auth/reset-password/route.ts`, `src/app/api/auth/[...nextauth]/route.ts` |
| Admin auth + permissions | `src/lib/admin-permissions.ts`, `src/lib/admin-permissions-types.ts` | | Admin auth + permissions | `src/lib/admin-permissions.ts`, `src/lib/admin-permissions-types.ts` |
| Middleware (route protection) | `src/middleware.ts` | | Middleware (route protection) | `src/proxy.ts` |
| Server actions | `src/actions/*.ts` (one file per domain; also grouped into `src/actions/{admin,ai,billing,communications,harvest-reach,integrations,orders,products,settings,shipping,stops,water-log,platform,route-trace,time-tracking,email-automation}/`) | | Server actions | `src/actions/*.ts` (one file per domain; also grouped into `src/actions/{admin,ai,billing,communications,harvest-reach,integrations,orders,products,settings,shipping,stops,water-log,platform,route-trace,time-tracking,email-automation}/`) |
| Admin pages | `src/app/admin/[module]/page.tsx` | | Admin pages | `src/app/admin/[module]/page.tsx` |
| Admin client components | `src/components/admin/*.tsx` | | Admin client components | `src/components/admin/*.tsx` |
+2 -2
View File
@@ -12,7 +12,7 @@ These are safe to commit and can be used in client bundles. Prefix with `NEXT_PU
### `NEXT_PUBLIC_BASE_URL` ### `NEXT_PUBLIC_BASE_URL`
The base URL of your deployment. Used for OAuth redirects and webhook URLs. The base URL of your deployment. Used for OAuth redirects and webhook URLs.
- **Local:** `http://localhost:3000` - **Local:** `http://localhost:4000` (dev script binds to port 4000; override via `npm run dev -- -p <port>`)
- **Production:** `https://yourdomain.com` - **Production:** `https://yourdomain.com`
### `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY` ### `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY`
@@ -151,7 +151,7 @@ Controls whether to use Square sandbox or production.
| Variable | Local (`.env.local`) | Production (hosting dashboard) | | Variable | Local (`.env.local`) | Production (hosting dashboard) |
|---|---|---| |---|---|---|
| `NEXT_PUBLIC_BASE_URL` | `http://localhost:3000` | `https://yourdomain.com` | | `NEXT_PUBLIC_BASE_URL` | `http://localhost:4000` (or whatever port the dev server is on) | `https://yourdomain.com` |
| `STRIPE_SECRET_KEY` | `sk_test_...` | `sk_live_...` | | `STRIPE_SECRET_KEY` | `sk_test_...` | `sk_live_...` |
| `STRIPE_PUBLISHABLE_KEY` | `pk_test_...` | `pk_live_...` | | `STRIPE_PUBLISHABLE_KEY` | `pk_test_...` | `pk_live_...` |
| `SQUARE_ENVIRONMENT` | `sandbox` | `production` | | `SQUARE_ENVIRONMENT` | `sandbox` | `production` |
+4 -2
View File
@@ -1,5 +1,7 @@
# Route Commerce Launch Checklist Summary # Route Commerce Launch Checklist Summary
**Last updated:** 2026-06-25
## Overview ## Overview
This document summarizes the complete Launch & Marketing Layer implementation for Route Commerce, a multi-tenant B2B e-commerce platform for fresh produce wholesale distribution. This document summarizes the complete Launch & Marketing Layer implementation for Route Commerce, a multi-tenant B2B e-commerce platform for fresh produce wholesale distribution.
@@ -15,7 +17,7 @@ This document summarizes the complete Launch & Marketing Layer implementation fo
| Auth Flow | ✓ Complete | Neon Auth (Better Auth) + dev_session for local | | Auth Flow | ✓ Complete | Neon Auth (Better Auth) + dev_session for local |
| Database Structure | ✓ Complete | `db/migrations/` applied via `pg` | | Database Structure | ✓ Complete | `db/migrations/` applied via `pg` |
| Role-Based Access | ✓ Complete | `admin-permissions.ts` system | | Role-Based Access | ✓ Complete | `admin-permissions.ts` system |
| Protected Routes | ✓ Complete | `middleware.ts` | | Protected Routes | ✓ Complete | `src/proxy.ts` (Next.js 16+ middleware convention) |
| Server Actions Pattern | ✓ Complete | `src/actions/*.ts` | | Server Actions Pattern | ✓ Complete | `src/actions/*.ts` |
### 2. Launch-Ready Features ✓ ### 2. Launch-Ready Features ✓
@@ -242,4 +244,4 @@ Track these metrics post-launch:
--- ---
*Generated: January 2025* *Generated: January 2025 · Refreshed: 2026-06-25 (see `CLAUDE.md` for current architecture; deployment is via Vercel hooked to the Gitea `origin` remote — there is no GitHub `origin`)*
+3 -1
View File
@@ -2,7 +2,9 @@
This file captures key context, decisions, fixes, and state from recent work so it survives across conversations. This file captures key context, decisions, fixes, and state from recent work so it survives across conversations.
**Last updated:** 2026-06 (admin_users schema fix + migration reliability + Google sign-in work; full Supabase purge) **Last updated:** 2026-06-25 (added current-state header; restored "Supabase → Postgres" pivot as the canonical entry point for new readers; documented the SSH-based Gitea workflow)
> **Current state (read first).** Auth is **Neon Auth (Better Auth)** — see `CLAUDE.md`. The "Auth.js v5 wiring complete — 2026-06-06" entry further down is **historical** (it describes work that was subsequently replaced by the Neon Auth migration; `next-auth` remains in `package.json` as a vestigial dep but is no longer imported from `src/`). The Supabase → Postgres pivot section below is the canonical cutover record. The "GitHub origin" branch notes are also historical — the only remote is the Gitea `origin` (see `CLAUDE.md` "Canonical Remote"). Middleware lives at `src/proxy.ts`, not `src/middleware.ts` (Next.js 16+ convention). Repo operations use **SSH** (`~/.ssh/id_ed25519_crispygoat`) — no Gitea API token is provisioned in this env, so `tea`/`gitea-mcp`/REST API are unavailable for write operations; PRs are opened by `git push` + clicking the URL the Gitea push hook prints.
## 2026-06: `admin_users` schema — extra columns for create-user flow (migration 0043) ## 2026-06: `admin_users` schema — extra columns for create-user flow (migration 0043)
+18 -27
View File
@@ -1,47 +1,38 @@
# Route Commerce — Production Deployment Checklist # Route Commerce — Production Deployment Checklist
**Platform Version:** 1.6 **Platform Version:** 2.0
**Last Updated:** 2026-05-13 **Last Updated:** 2026-06-25
**Environment:** Next.js 16 (App Router) · Postgres (direct via `pg`) · Neon Auth (Better Auth) · Stripe · Square · Resend · FedEx **Environment:** Next.js 16 (App Router) · Postgres (direct via `pg`) · Neon Auth (Better Auth) · Stripe · Square · Resend · FedEx
--- ---
## 1. Migration Order ## 1. Migration Order
Apply migrations in number order. All numbered `001``092` are required. Apply migrations in number order. The full set lives in `db/migrations/`:
```bash ```bash
# Push all migrations (sequential, no Supabase CLI required) # Push all migrations (idempotent — `_migrations` table tracks what's applied)
npm run migrate:one 001
npm run migrate:one 002
# ... through ...
npm run migrate:one 092
# Or push all at once
npm run migrate npm run migrate
``` ```
**Key migrations (last 15):** The current migration set is consolidated (the Supabase-era 001092 series was collapsed into `0001_init.sql` plus a handful of incremental files). If `db/migrations/` is empty after the Supabase → Postgres migration, see `MEMORY.md` "Direction Pivot" for the cutover notes.
**Current migrations in `db/migrations/`:**
| # | File | Purpose | | # | File | Purpose |
|---|------|---------| |---|------|---------|
| 078 | `wholesale_deposit_guard.sql` | Adds `amount`, `payment_method` to `wholesale_deposits` | | 0000 | `0000_qa_neon_auth_stub.sql` | QA-only stub for `neon_auth` schema (real provisioning via Neon Auth in prod) |
| 079 | `resend_analytics.sql` | Adds Resend webhook endpoint + analytics tables | | 0001 | `0001_init.sql` | Core schema: brands, products, orders, stops, customers, communication tables, water log, time tracking, RPCs, indexes, triggers. Fully re-runnable (`IF NOT EXISTS` + trigger guards). |
| 080 | `communication_segments.sql` | Adds `communication_segments` table | | 0002 | `0002_admin_password.sql` | Adds `password_hash` column to `admin_users` |
| 081 | `stop_blast_campaign.sql` | Adds `stop_blast_campaign` RPC | | 0003 | `0003_tour_rpc_functions.sql` | RPCs for tour/stop planning |
| 082 | `brand_name_in_campaign_email.sql` | Adds `brand_name` column to `communication_campaigns` | | 0040 | `0040_command_center.sql` | Adds command-center dashboard tables |
| 083 | `shipping_settings.sql` | Adds `shipping_settings` table | | 0041 | `0041_command_center_schema_fix.sql` | Schema fixup for command-center |
| 084 | `shipments.sql` | Adds `shipments` table for FedEx tracking | | 0042 | `0042_drop_command_center.sql` | Drops command-center (rolled back) |
| 085 | `brand_settings.sql` | Adds `brand_settings` table (core) | | 0043 | `0043_admin_users_extra_columns.sql` | Adds `display_name`, `phone_number`, `brand_id`, `can_manage_pickup/messages/refunds/users`, `active`, `must_change_password`, `auth_provider`, `auth_subject`, `last_login` columns to `admin_users` |
| 086 | `brand_settings_email_integration.sql` | Adds email/webhook fields to `brand_settings` | | 0090 | `0090_water_log_completion.sql` | Completes water-log tables/RPCs |
| 087 | `brand_logos_bucket.sql` | Adds `brand-logos` storage bucket | | 0091 | `0091_dashboard_summary_rpc.sql` | `dashboard_summary` RPC for admin dashboard |
| 088 | `brand_features.sql` | Adds `brand_features` table + RPCs for add-on system |
| 089 | `ai_providers_custom_integrations.sql` | Adds AI provider credentials storage |
| 090 | `storefront_settings.sql` | Adds storefront customization fields + `get_brand_settings_by_slug` RPC |
| 091 | `091_brand_plan_tier.sql` | Adds `plan_tier`, limits, `stripe_customer_id`, `get_brand_plan_info` RPC |
| 092 | `092_stripe_subscriptions.sql` | Adds `stripe_subscription_id/status/current_period_end`, `set_brand_subscription`, `get_brand_subscription` RPCs |
> **Note:** Migration 092 adds Stripe subscription tracking. Migration 091 adds plan tier billing. Apply both before deploying billing changes. > **Note:** The migration runner (`scripts/migrate.js`) tracks applied files in `_migrations` and skips already-applied files. `0001_init.sql` is fully re-runnable, so it is safe to re-apply on a DB that was initialized outside the runner. Stripe subscription tracking, plan-tier billing, brand settings, etc. are all part of `0001_init.sql` — they were originally separate Supabase-era migrations that were consolidated.
--- ---
+2 -2
View File
@@ -24,7 +24,7 @@ npm run dev
NEON_AUTH_COOKIE_SECRET=<openssl rand -base64 32> NEON_AUTH_COOKIE_SECRET=<openssl rand -base64 32>
NEXT_PUBLIC_SITE_URL=https://yourdomain.com NEXT_PUBLIC_SITE_URL=https://yourdomain.com
``` ```
3. Configure middleware in `src/middleware.ts` 3. Configure middleware in `src/proxy.ts`
### 2. Stripe Payments ### 2. Stripe Payments
@@ -74,7 +74,7 @@ Ensure environment variables are set before deployment.
## Key Files ## Key Files
- `src/middleware.ts` - Neon Auth (Better Auth) middleware - `src/proxy.ts` - Neon Auth (Better Auth) middleware
- `src/lib/stripe-billing.ts` - Stripe integration - `src/lib/stripe-billing.ts` - Stripe integration
- `src/lib/analytics.ts` - PostHog analytics - `src/lib/analytics.ts` - PostHog analytics
- `src/lib/sentry.ts` - Sentry error tracking - `src/lib/sentry.ts` - Sentry error tracking
+2 -2
View File
@@ -72,7 +72,7 @@ npm run migrate:one 83
npm run dev npm run dev
``` ```
Open [http://localhost:3000](http://localhost:3000). The dev server auto-runs `fix-agents.js` to patch Next.js App Router agent issues. Open [http://localhost:4000](http://localhost:4000). The dev server auto-runs `fix-agents.js` to patch Next.js App Router agent issues. (The dev script binds to `0.0.0.0:4000`; override with `npm run dev -- -p <port>` if you need a different port.)
### 5. Dev auth bypass ### 5. Dev auth bypass
@@ -250,7 +250,7 @@ CRON_SECRET=... # Bearer token to secure cron endpoints (generate
```bash ```bash
# Run abandoned cart with verbose output # Run abandoned cart with verbose output
curl -X POST http://localhost:3000/api/email-automation/abandoned-cart \ curl -X POST http://localhost:4000/api/email-automation/abandoned-cart \
-H "Authorization: Bearer local-dev-secret" \ -H "Authorization: Bearer local-dev-secret" \
-H "Content-Type: application/json" -H "Content-Type: application/json"
+1 -1
View File
@@ -1,7 +1,7 @@
/** /**
* Edge-safe Neon Auth configuration. * Edge-safe Neon Auth configuration.
* *
* This file is imported by `src/middleware.ts`, which runs in the Edge * This file is imported by `src/proxy.ts`, which runs in the Edge
* runtime. It must NOT import: * runtime. It must NOT import:
* - `pg` / any Node-only database driver * - `pg` / any Node-only database driver
* - The Drizzle client * - The Drizzle client