Add delivery cleanup design document
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
3ebb63dc6c
commit
23f623db2c
1 changed files with 134 additions and 0 deletions
134
docs/plans/2026-02-22-delivery-cleanup-design.md
Normal file
134
docs/plans/2026-02-22-delivery-cleanup-design.md
Normal file
|
|
@ -0,0 +1,134 @@
|
||||||
|
# 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-<timestamp>/`
|
||||||
|
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-<date>.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
|
||||||
Loading…
Add table
Reference in a new issue