# FoamKing Delivery Cleanup Design Date: 2026-02-22 ## Goal Prepare the FoamKing calculator for zip delivery to customer. Clean up routes, security, auth, DB, and strip debug/dev artifacts. Customer will integrate into their own infrastructure. ## 1. Route Restructure | Before | After | Access | |--------|-------|--------| | `/` | `/` | Public — calculator | | `/tilbud/[slug]` | `/tilbud/[slug]` | Public — quote view | | `/admin` | `/intern/beregner` | Protected — detailed calculator breakdown | | `/dashboard` | `/intern` | Protected — quote management (kanban) | | `/historik` | `/intern/historik` | Protected — quote archive | | `/login` | `/intern/login` | Public — login page | Middleware protects `/intern/*` except `/intern/login`. ## 2. Authentication **Replace DB-based auth with env-based single admin user.** `lib/auth.ts` exports: - `checkAuth(request)` — single function, clear comments for JWT/OAuth swap - `login(email, password)` — compares against `ADMIN_EMAIL`/`ADMIN_PASSWORD` env vars - `logout(token)` — clears session Implementation: in-memory session Map or signed cookie. No DB tables for users/sessions. Remove: - `users` table - `sessions` table - `/api/auth/setup` endpoint - `bcrypt` dependency `.env` config: ``` ADMIN_EMAIL=admin@example.com ADMIN_PASSWORD=changeme ``` ## 3. Database Cleanup **Keep SQLite (`better-sqlite3`), clean schema, add seed script.** Single table: ```sql CREATE TABLE quotes ( id INTEGER PRIMARY KEY AUTOINCREMENT, postal_code TEXT NOT NULL, address TEXT, area REAL NOT NULL, height REAL NOT NULL, include_floor_heating INTEGER DEFAULT 1, flooring_type TEXT DEFAULT 'STANDARD', customer_name TEXT NOT NULL, customer_email TEXT NOT NULL, customer_phone TEXT NOT NULL, remarks TEXT, total_excl_vat REAL NOT NULL, total_incl_vat REAL NOT NULL, status TEXT DEFAULT 'new', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, email_opened_at TEXT ); ``` - Quote IDs start at 1000 - No migration hacks (clean CREATE TABLE only) - `lib/db.ts` opens DB and exports connection — no schema creation on import **Seed script** (`npm run setup`): - Creates `data/` directory - Creates quotes table - Sets auto-increment start to 1000 - Prints success message ## 4. Security Hardening - Remove all hardcoded credentials from codebase - Remove `docs/mail.txt` from delivery - Rate limiting on `/api/quote-request` and `/api/auth/login` (simple in-memory counter) - Validate/sanitize all inputs server-side - Cookies: `httpOnly`, `secure`, `sameSite: strict` - Remove `/api/auth/setup` endpoint ## 5. Debug Stripping - Remove all `console.log` statements - Remove "Admin Mode" toggle from public pages - Remove dev-only comments and TODO markers ## 6. Distance Calculation Unchanged — dual approach: - **Default:** Hardcoded postal code lookup table (no API key needed) - **Optional:** OpenRouteService API for precise driving distances (free tier, 2000 req/day) ## 7. Build & Zip Delivery **`scripts/build-release.sh`:** 1. Create temp directory `/tmp/foamking-release-/` 2. Copy shipping files: - `app/`, `components/`, `lib/`, `public/`, `scripts/setup.js` - `middleware.ts` - `package.json`, `tsconfig.json`, `tailwind.config.ts` - `postcss.config.mjs`, `eslint.config.mjs`, `next.config.ts` - `.env.example`, `OPSÆTNING.md`, `SETUP.md` 3. Run `npm install` + `npm run build` to verify compilation 4. Remove `node_modules/` and `.next/` from temp dir 5. Zip as `foamking-beregner-.zip` **Excluded from zip:** - `.git/`, `docs/`, `node_modules/`, `.next/`, `data/` - `.env.local`, `CLAUDE.md`, `README.md`, `package-lock.json` ## 8. Setup Documentation **`OPSÆTNING.md`** (Danish) + **`SETUP.md`** (English) covering: 1. Prerequisites (Node.js, npm) 2. Install dependencies (`npm install`) 3. Configure `.env.local`: - `ADMIN_EMAIL` / `ADMIN_PASSWORD` (required) - SMTP: Office 365 — `smtp.office365.com:587` with STARTTLS, enable SMTP AUTH for `tilbud@foamking.dk` in Exchange Admin Center (required) - `OPENROUTE_API_KEY` (optional — for precise distance calculation) 4. Run `npm run setup` (creates database) 5. Build and start (`npm run build && npm start`) 6. Route overview: `/` = public calculator, `/intern` = admin dashboard 7. Auth customization: how to replace `checkAuth()` in `lib/auth.ts` for JWT/OAuth