diff --git a/CLAUDE.md b/CLAUDE.md index 6561bb9..3e10ff1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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`). +### 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 ` — 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/-` +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 ` +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/` — 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 ` on the REST API or `tea logins add -t -u https://git.crispygoat.com` for the CLI. + ## 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. @@ -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. -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:** 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 -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:** - `src/lib/auth.ts` — Neon Auth configuration (getSession, signIn, signOut, resetPassword, requestPasswordReset) - `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/forgot-password/route.ts` — Password reset request 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` | | 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` | -| 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}/`) | | Admin pages | `src/app/admin/[module]/page.tsx` | | Admin client components | `src/components/admin/*.tsx` | diff --git a/ENVIRONMENT.md b/ENVIRONMENT.md index b0da3d9..5991cc1 100644 --- a/ENVIRONMENT.md +++ b/ENVIRONMENT.md @@ -12,7 +12,7 @@ These are safe to commit and can be used in client bundles. Prefix with `NEXT_PU ### `NEXT_PUBLIC_BASE_URL` 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 `) - **Production:** `https://yourdomain.com` ### `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY` @@ -151,7 +151,7 @@ Controls whether to use Square sandbox or production. | 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_PUBLISHABLE_KEY` | `pk_test_...` | `pk_live_...` | | `SQUARE_ENVIRONMENT` | `sandbox` | `production` | diff --git a/LAUNCH_CHECKLIST.md b/LAUNCH_CHECKLIST.md index ee0104e..7c9bcc7 100644 --- a/LAUNCH_CHECKLIST.md +++ b/LAUNCH_CHECKLIST.md @@ -1,5 +1,7 @@ # Route Commerce Launch Checklist Summary +**Last updated:** 2026-06-25 + ## 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. @@ -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 | | Database Structure | ✓ Complete | `db/migrations/` applied via `pg` | | 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` | ### 2. Launch-Ready Features ✓ @@ -242,4 +244,4 @@ Track these metrics post-launch: --- -*Generated: January 2025* \ No newline at end of file +*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`)* \ No newline at end of file diff --git a/MEMORY.md b/MEMORY.md index 56883d5..630965f 100644 --- a/MEMORY.md +++ b/MEMORY.md @@ -2,7 +2,9 @@ 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) diff --git a/PRODUCTION_DEPLOYMENT_CHECKLIST.md b/PRODUCTION_DEPLOYMENT_CHECKLIST.md index 3f49b81..8bb51a7 100644 --- a/PRODUCTION_DEPLOYMENT_CHECKLIST.md +++ b/PRODUCTION_DEPLOYMENT_CHECKLIST.md @@ -1,47 +1,38 @@ # Route Commerce — Production Deployment Checklist -**Platform Version:** 1.6 -**Last Updated:** 2026-05-13 +**Platform Version:** 2.0 +**Last Updated:** 2026-06-25 **Environment:** Next.js 16 (App Router) · Postgres (direct via `pg`) · Neon Auth (Better Auth) · Stripe · Square · Resend · FedEx --- ## 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 -# Push all migrations (sequential, no Supabase CLI required) -npm run migrate:one 001 -npm run migrate:one 002 -# ... through ... -npm run migrate:one 092 - -# Or push all at once +# Push all migrations (idempotent — `_migrations` table tracks what's applied) npm run migrate ``` -**Key migrations (last 15):** +The current migration set is consolidated (the Supabase-era 001–092 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 | |---|------|---------| -| 078 | `wholesale_deposit_guard.sql` | Adds `amount`, `payment_method` to `wholesale_deposits` | -| 079 | `resend_analytics.sql` | Adds Resend webhook endpoint + analytics tables | -| 080 | `communication_segments.sql` | Adds `communication_segments` table | -| 081 | `stop_blast_campaign.sql` | Adds `stop_blast_campaign` RPC | -| 082 | `brand_name_in_campaign_email.sql` | Adds `brand_name` column to `communication_campaigns` | -| 083 | `shipping_settings.sql` | Adds `shipping_settings` table | -| 084 | `shipments.sql` | Adds `shipments` table for FedEx tracking | -| 085 | `brand_settings.sql` | Adds `brand_settings` table (core) | -| 086 | `brand_settings_email_integration.sql` | Adds email/webhook fields to `brand_settings` | -| 087 | `brand_logos_bucket.sql` | Adds `brand-logos` storage bucket | -| 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 | +| 0000 | `0000_qa_neon_auth_stub.sql` | QA-only stub for `neon_auth` schema (real provisioning via Neon Auth in prod) | +| 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). | +| 0002 | `0002_admin_password.sql` | Adds `password_hash` column to `admin_users` | +| 0003 | `0003_tour_rpc_functions.sql` | RPCs for tour/stop planning | +| 0040 | `0040_command_center.sql` | Adds command-center dashboard tables | +| 0041 | `0041_command_center_schema_fix.sql` | Schema fixup for command-center | +| 0042 | `0042_drop_command_center.sql` | Drops command-center (rolled back) | +| 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` | +| 0090 | `0090_water_log_completion.sql` | Completes water-log tables/RPCs | +| 0091 | `0091_dashboard_summary_rpc.sql` | `dashboard_summary` RPC for admin dashboard | -> **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. --- diff --git a/PRODUCTION_SETUP.md b/PRODUCTION_SETUP.md index 18a7e9c..c7effcc 100644 --- a/PRODUCTION_SETUP.md +++ b/PRODUCTION_SETUP.md @@ -24,7 +24,7 @@ npm run dev NEON_AUTH_COOKIE_SECRET= NEXT_PUBLIC_SITE_URL=https://yourdomain.com ``` -3. Configure middleware in `src/middleware.ts` +3. Configure middleware in `src/proxy.ts` ### 2. Stripe Payments @@ -74,7 +74,7 @@ Ensure environment variables are set before deployment. ## 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/analytics.ts` - PostHog analytics - `src/lib/sentry.ts` - Sentry error tracking diff --git a/README.md b/README.md index 799019b..f415837 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ npm run migrate:one 83 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 ` if you need a different port.) ### 5. Dev auth bypass @@ -250,7 +250,7 @@ CRON_SECRET=... # Bearer token to secure cron endpoints (generate ```bash # 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 "Content-Type: application/json" diff --git a/src/auth.config.ts b/src/auth.config.ts index 00ddea1..8dd14d7 100644 --- a/src/auth.config.ts +++ b/src/auth.config.ts @@ -1,7 +1,7 @@ /** * 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: * - `pg` / any Node-only database driver * - The Drizzle client