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

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 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.

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