Files
tilbudgivern/CLAUDE.md
2026-08-24 08:31:55 +02:00

161 lines
7.0 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Tilbudgivern is an AI-powered quote calculator for the carpentry trade (tømrerfaget). It generates detailed professional quotes based on project descriptions, using OpenAI GPT-4 for AI-powered quote generation.
**Tech Stack:**
- Frontend: React 18 with Material-UI, served as static build
- Backend: Node.js/Express unified server (~400K lines in `backend/unified-server.js`)
- Database: MariaDB/MySQL (running on host, not containerized)
- AI: OpenAI GPT-4 API (default budget: $9/month)
- Process Manager: PM2 (process name: `tilbudgivern-unified`)
## Common Commands
### Development
```bash
npm run dev # Start development server with hot reload
npm run build # Build frontend for production
pm2 restart tilbudgivern-unified # Restart PM2 after changes
pm2 logs tilbudgivern-unified # View logs
```
### Testing
```bash
npm run test:pw # Playwright UI tests against production
npm run test:pw:local # Playwright tests against local server
npm run test:pw:ui # Playwright interactive UI mode
npm run test:pw:headed # Playwright with visible browser
npm run test:selenium # Selenium UI tests
cd backend && npm test # Backend unit tests (Jest)
```
### Single Test Execution
```bash
cd tests && PLAYWRIGHT_BASE_URL=https://tilbudsgiveren.alw.dk playwright test <test-file>.spec.js
cd tests && PLAYWRIGHT_BASE_URL=https://tilbudsgiveren.alw.dk playwright test <test-file>.spec.js --headed
```
## Architecture
### Unified Server Pattern
The application uses a unified server (`backend/unified-server.js`) that:
- Serves the React frontend build from `frontend/build/`
- Provides all API endpoints on port 4032 (configured in `.env`)
- Handles WebSocket connections via Socket.IO
- Includes structured logging with correlation IDs
### Key Backend Services (`backend/src/services/`)
- `openaiService.js` - AI quote generation via GPT-4, budget tracking
- `databaseService.js` - MariaDB connection pool and queries
- `smartPackageManagementService.js` - Smart package CRUD (15 carpenter packages)
- `ordrestyringSyncService.js` - GraphQL integration with Ordrestyring API
- `pdfGenerationService.js` - Quote PDF generation via Puppeteer
- `roofGeometryService.js` - Roof area calculations for 7 roof types
- `starkImportService.js` - Stark material catalog import
- `bygmaPrisbogImportService.js` - Bygma price book import
### Key Backend Routes (`backend/src/routes/`)
- `smartPackagesRoutes.js` - Smart package management API
- `customerProjects.js` - Customer and project CRUD
- `quotes.js` - Quote generation and management
- `pricing.js` - Price database endpoints
- `starkImport.js` - Stark CSV import endpoint
### Key Frontend Components (`frontend/src/components/`)
- `InlineSmartPackage.js` - Smart package wizard with step-by-step flow
- `EnhancedGeometry.js` - Roof geometry input with SVG visualizations for 7 roof types
- `MaterialsManager.js` - Material selection with cached API searches
- `PlanningDashboard.js` - Project planning calendar
- `FinalReview.js` - Quote review and Ordrestyring offer creation
- `ProjectCreation.js` - Project form with autosave, validation, tooltips
### Smart Packages System
15 pre-configured carpenter packages for roofing work:
- Auto-calculation based on geometry (tagareal, rygningslængde, facadelængde)
- Includes materials with prices and labor hours
- Categories: Tagdækning, Tagrende/Nedløb, Tagvinduer, Brædder, Specialarbejde
### Roof Types (7 supported)
1. Sadeltag (pitched roof) - default
2. Valmtag (hip roof)
3. Københavnertag (Copenhagen roof)
4. Fladtag (flat roof)
5. Pulttag (shed roof)
6. Tag med Kviste (roof with dormers)
7. Mansardtag (mansard roof)
## External Integrations
### Ordrestyring API
- GraphQL endpoint: `https://beta7-api.ordrestyring.dk/graphql`
- Used for: customers, cases, offers, calendar, hours tracking
- Token: `ORDRESTYRING_API_TOKEN` in `.env`
- API test scripts: `apitest/examples/`
### Material Suppliers
- **Bygma**: Price book import, installation manuals
- **Stark**: CSV catalog import via `/api/stark/upload`
## Database
- MariaDB on localhost:3306
- Database: `tilbudgivern`
- Key tables: `smart_packages`, `package_tasks`, `package_materials`, `materials`, `customers`, `projects`
- Schema files: `database/schema_system_logs.sql`
- Migrations: `database/migrations/`, `backend/migrations/`
## Environment Configuration
- Main config: `backend/.env`
- Required:
- `OPENAI_API_KEY` - for AI features
- `DB_HOST`, `DB_USER`, `DB_PASSWORD`, `DB_NAME` - database
- Optional:
- `ORDRESTYRING_API_TOKEN` - order management integration
- `OPENAI_ADMIN_KEY` - for cost tracking API
## Logging System
- Structured JSON logs with correlation IDs
- Database persistence in `system_logs` table
- Error codes: DB_001 (connection), DB_002 (query), VAL_001 (validation), API_001 (Ordrestyring), etc.
- Admin endpoints: `/api/admin/logs`
## Deployment
**This machine is the production server.** There is no separate deploy target: `backend/unified-server.js` runs directly out of this git working directory via PM2, serving the built frontend from `frontend/build/`. There is no CI/CD pipeline that deploys automatically on merge — deploying means running these steps here, on this host, after `main` has the commit you want live.
```bash
git checkout main && git pull # Get the commit you want live
cd frontend && npm ci && npm run build # Sync frontend deps and rebuild static assets
cd ../backend && npm ci --omit=dev # Sync backend deps (skip if unchanged)
pm2 restart tilbudgivern-unified # Restart the running process
pm2 logs tilbudgivern-unified --lines 30 --nostream # Confirm a clean startup (no errors)
curl -sf http://localhost:4032/api/health # Should return {"status":"ok",...}
curl -sI https://tilbudsgiveren.alw.dk # Should return HTTP/2 200
```
Other useful commands:
```bash
pm2 status # Check process status
pm2 logs tilbudgivern-unified # Tail live logs
```
Daily database backups configured via cron at 02:00, retention: 7 days.
Note: `.github/workflows/deploy-prod.yml` (an SSH/rsync-to-a-remote-server pipeline) was removed — it targeted a `PROD_SERVER_HOST`/`PROD_SERVER_USER`/`PROD_SERVER_PATH`/`PROD_SSH_PRIVATE_KEY` setup that was never configured (no repo or `production`-environment secrets ever existed), and every historical run of it failed. If a real separate deploy target is ever set up, that pipeline's steps (versioned releases dir, atomic symlink swap, pre-deploy DB backup, health-check retries, smoke tests) are a reasonable starting point to resurrect from git history.
## Danish Terminology
- Tilbud = Quote/Offer
- Tømrer = Carpenter
- Materiale = Material
- Pakke = Package
- Pris = Price
- Tag = Roof
- Spær = Rafters
- Tagrende = Rain gutter
- Nedløb = Downspout
- Vindsked = Barge board
- Sternbræt = Fascia board