7.0 KiB
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
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
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
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 trackingdatabaseService.js- MariaDB connection pool and queriessmartPackageManagementService.js- Smart package CRUD (15 carpenter packages)ordrestyringSyncService.js- GraphQL integration with Ordrestyring APIpdfGenerationService.js- Quote PDF generation via PuppeteerroofGeometryService.js- Roof area calculations for 7 roof typesstarkImportService.js- Stark material catalog importbygmaPrisbogImportService.js- Bygma price book import
Key Backend Routes (backend/src/routes/)
smartPackagesRoutes.js- Smart package management APIcustomerProjects.js- Customer and project CRUDquotes.js- Quote generation and managementpricing.js- Price database endpointsstarkImport.js- Stark CSV import endpoint
Key Frontend Components (frontend/src/components/)
InlineSmartPackage.js- Smart package wizard with step-by-step flowEnhancedGeometry.js- Roof geometry input with SVG visualizations for 7 roof typesMaterialsManager.js- Material selection with cached API searchesPlanningDashboard.js- Project planning calendarFinalReview.js- Quote review and Ordrestyring offer creationProjectCreation.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)
- Sadeltag (pitched roof) - default
- Valmtag (hip roof)
- Københavnertag (Copenhagen roof)
- Fladtag (flat roof)
- Pulttag (shed roof)
- Tag med Kviste (roof with dormers)
- 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_TOKENin.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 featuresDB_HOST,DB_USER,DB_PASSWORD,DB_NAME- database
- Optional:
ORDRESTYRING_API_TOKEN- order management integrationOPENAI_ADMIN_KEY- for cost tracking API
Logging System
- Structured JSON logs with correlation IDs
- Database persistence in
system_logstable - 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.
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:
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