docs: Add AI agent configuration files for multiple AI assistants

- CLAUDE.md: Claude Code instructions
- .github/copilot-instructions.md: GitHub Copilot custom instructions
- .cursorrules: Cursor IDE project rules
- COPILOT_MEMORY.md: Active project context with documentation links
- AGENTS.md: General repository guidelines and coding standards
- GEMINI.md: Gemini AI detailed project overview

All files include: project overview, tech stack, architecture patterns,
Smart Packages system, roof types, Danish terminology, and common commands.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
alexpolo1
2026-01-20 11:02:21 +00:00
parent aa69197a2e
commit cf9b831e35
6 changed files with 721 additions and 0 deletions

107
.cursorrules Normal file
View File

@@ -0,0 +1,107 @@
# Tilbudgivern - Cursor Rules
## Project Context
This is **Tilbudgivern**, an AI-powered quote calculator for Danish carpenters (tømrere). The application generates professional quotes for roofing and construction work.
## Tech Stack
- Frontend: React 18 + Material-UI (served from `frontend/build/`)
- Backend: Node.js/Express unified server (`backend/unified-server.js`)
- Database: MariaDB on localhost:3306, database `tilbudgivern`
- AI: OpenAI GPT-4 API
- Process Manager: PM2 (`tilbudgivern-unified`)
- Tests: Playwright, Selenium, Jest
## Key Architecture
### Unified Server
Single server file `backend/unified-server.js` handles:
- Static frontend serving
- All API endpoints (port 4032)
- WebSocket connections (Socket.IO)
- Structured logging with correlation IDs
### Smart Packages
15 pre-configured roofing packages with:
- Auto-calculation from geometry (tagareal, rygningslængde)
- Materials with prices + labor hours
- Tables: `smart_packages`, `package_tasks`, `package_materials`
### 7 Roof Types
sadeltag, valmtag, koebenhavnertag, fladt_tag, pulttag, tag_med_kviste, mansard
## Code Patterns
### Backend Services
```javascript
// Use structured logging
const logger = require('./src/utils/logger');
logger.logInfo('Context', 'Message', { correlationId: req.correlationId, metadata: {} });
logger.logError('Context', error, { correlationId: req.correlationId });
// Use asyncHandler for routes
const { asyncHandler } = require('./src/middleware/errorHandler');
router.get('/endpoint', asyncHandler(async (req, res) => { ... }));
```
### API Response Format
```javascript
// Success
res.json({ success: true, data: result });
// Error
res.status(400).json({ success: false, error: { code: 'VAL_001', message: 'Danish error message' } });
```
### React Components
- Functional components with hooks
- Material-UI for UI consistency
- Follow patterns in `frontend/src/components/`
## Danish Language
UI and code comments are in Danish. Key terms:
- Tilbud = Quote, Tømrer = Carpenter, Tag = Roof
- Materiale = Material, Pakke = Package, Pris = Price
- Tagrende = Gutter, Nedløb = Downspout, Spær = Rafters
## Important Files
- `backend/unified-server.js` - Main server (~400K lines)
- `backend/src/services/openaiService.js` - AI quote generation
- `backend/src/services/smartPackageManagementService.js` - Package CRUD
- `backend/src/routes/smartPackagesRoutes.js` - Package API
- `frontend/src/components/InlineSmartPackage.js` - Package wizard
- `frontend/src/components/EnhancedGeometry.js` - Roof geometry with SVG
## External APIs
### Ordrestyring (GraphQL)
- Endpoint: `https://beta7-api.ordrestyring.dk/graphql`
- Token: `ORDRESTYRING_API_TOKEN`
- Used for: customers, cases, offers, calendar
### Material Imports
- Bygma: Price book import
- Stark: CSV import via `/api/stark/upload`
## Commands
```bash
npm run dev # Dev server with hot reload
npm run build # Build frontend
pm2 restart tilbudgivern-unified # Restart
npm run test:pw # Playwright tests
cd backend && npm test # Jest tests
```
## Environment
Required in `backend/.env`:
- OPENAI_API_KEY
- DB_HOST, DB_USER, DB_PASSWORD, DB_NAME
Optional:
- ORDRESTYRING_API_TOKEN
- OPENAI_ADMIN_KEY

116
.github/copilot-instructions.md vendored Normal file
View File

@@ -0,0 +1,116 @@
# GitHub Copilot Instructions for Tilbudgivern
## Project Overview
Tilbudgivern is an AI-powered quote calculator for the Danish carpentry trade (tømrerfaget). It generates detailed professional quotes for roofing and construction work using OpenAI GPT-4.
**Primary Users:** Danish carpenters creating quotes for roofing projects
## Tech Stack
- **Frontend:** React 18 with Material-UI, served as static build from `frontend/build/`
- **Backend:** Node.js/Express unified server (`backend/unified-server.js`)
- **Database:** MariaDB/MySQL on localhost:3306, database name `tilbudgivern`
- **AI:** OpenAI GPT-4 API (budget: $9/month)
- **Process Manager:** PM2 (process: `tilbudgivern-unified`)
- **Testing:** Playwright (primary), Selenium (backup), Jest (unit tests)
## Architecture
### Unified Server Pattern
The application uses a single server file (`backend/unified-server.js`) that:
- Serves React frontend from `frontend/build/`
- Provides all API endpoints on port 4032
- Handles WebSocket via Socket.IO
- Includes structured logging with correlation IDs
### Key Directories
```
backend/src/services/ # Business logic (openaiService, databaseService, etc.)
backend/src/routes/ # API endpoints (smartPackagesRoutes, customerProjects, etc.)
frontend/src/components/ # React components (InlineSmartPackage, EnhancedGeometry, etc.)
tests/ # Playwright and Selenium tests
docs/ # Project documentation
```
### Smart Packages System
15 pre-configured carpenter packages for roofing work:
- Auto-calculation based on geometry (tagareal, rygningslængde, facadelængde)
- Categories: Tagdækning, Tagrende/Nedløb, Tagvinduer, Brædder, Specialarbejde
- Database tables: `smart_packages`, `package_tasks`, `package_materials`
### 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`
### Material Suppliers
- **Bygma:** Price book import, installation manuals
- **Stark:** CSV catalog import via `/api/stark/upload`
## Code Style Guidelines
### JavaScript/Node.js
- Use async/await for asynchronous operations
- Use structured logging via `logger.logInfo()`, `logger.logError()`
- Include correlation IDs in log calls
- Wrap route handlers with `asyncHandler` for error handling
### React Components
- Use functional components with hooks
- Use Material-UI components for consistency
- Follow existing patterns in `frontend/src/components/`
### API Endpoints
- Return `{ success: true/false, data/error }` format
- Use Danish error messages for user-facing errors
- Log errors with context and correlation IDs
## Danish Language
The codebase and UI are in Danish. Key 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
- Tagareal = Roof area
- Rygningslængde = Ridge length
- Facadelængde = Facade length
## Common Commands
```bash
npm run dev # Development with hot reload
npm run build # Build frontend
pm2 restart tilbudgivern-unified # Restart server
npm run test:pw # Playwright tests
cd backend && npm test # Jest unit tests
```
## Environment Variables
Required in `backend/.env`:
- `OPENAI_API_KEY` - for AI features
- `DB_HOST`, `DB_USER`, `DB_PASSWORD`, `DB_NAME` - database
Optional:
- `ORDRESTYRING_API_TOKEN` - order management
- `OPENAI_ADMIN_KEY` - cost tracking

50
AGENTS.md Normal file
View File

@@ -0,0 +1,50 @@
# Repository Guidelines
## Project Structure & Module Organization
- `frontend/` is the React UI (entry: `frontend/src/`), built with `react-scripts`.
- `backend/` is the Express API and services (entry: `backend/src/`).
- `tests/` contains Playwright, Selenium, and API/integration test assets.
- `database/` and `migrations/` hold schema/data artifacts.
- `docs/` houses active documentation; `_archive/` and `archive/` capture historical fixes.
- Root `unified-server.js` and `package.json` wire the unified runtime.
## Documentation Map (Read First)
- `docs/README.md` and `README.md` describe product scope and local setup.
- `docs/UI_TESTING_SETUP.md` and `tests/selenium/README.md` explain UI test workflows.
- `docs/deployment/` covers PM2, DNS migration, and deployment pipeline.
- `docs/ENCRYPTED_ENV_*` and `docs/ENCRYPTED_ENV_SECURITY.md` explain secret handling.
- `docs/OPENAI_COSTS_API.md` and `docs/LOGGING_SYSTEM.md` describe cost tracking/logging.
- `docs/features/` and `docs/guides/` describe Smart Packages, ordrestyring, and quoting flows.
- `apitest/` documents GraphQL API test batches and integration notes.
## Build, Test, and Development Commands
```bash
npm run dev # Start unified server (nodemon)
npm run start # Start unified server (node)
npm run build # Build frontend assets
npm run test:ui # Playwright UI suite (headless)
npm run test:pw:local # Playwright against localhost:4032
npm run test:selenium:local # Selenium UI tests against localhost
./test-build-deploy.sh # Full test + build + PM2 restart
./quick-deploy.sh # Quick deploy for small changes
```
## Coding Style & Naming Conventions
- Follow existing JS/React/Node patterns per folder.
- Prefer domain naming (e.g., `quote`, `roof-type`, `smart-package`, `carpenter`).
- Keep modules focused and small; avoid cross-cutting helpers.
## Testing Guidelines
- Playwright config: `tests/playwright.config.js` (Chromium). Selenium uses Mocha.
- Use `PLAYWRIGHT_BASE_URL`/`SELENIUM_BASE_URL` for environment targeting.
- Local UI runs expect the unified server on port 4032 (see `docs/UI_TESTING_SETUP.md`).
- Name UI specs by intent (e.g., `roof-type-verification.spec.js`).
## Commit & Pull Request Guidelines
- Recent history favors Conventional Commits (e.g., `feat: ...`).
- PRs include a short summary, test evidence (commands + results), and UI screenshots when relevant.
## Configuration & Secrets
- Use `backend/.env` for local secrets (e.g., `OPENAI_API_KEY`).
- Start PostgreSQL via `docker-compose up -d` for local work.
- Never commit API keys or production credentials.

145
CLAUDE.md Normal file
View File

@@ -0,0 +1,145 @@
# 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
```bash
pm2 restart tilbudgivern-unified # Restart after code changes
pm2 logs tilbudgivern-unified # View live logs
pm2 status # Check process status
```
Daily database backups configured via cron at 02:00, retention: 7 days.
## 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

123
COPILOT_MEMORY.md Normal file
View File

@@ -0,0 +1,123 @@
# Tilbudgivern - Project Memory
Use this file to keep AI assistants (Copilot, Claude, Cursor) aligned on project context. Reference this file explicitly in chat sessions.
## Project Summary
**Tilbudgivern** is an AI-powered quote calculator for Danish carpenters, focused on roofing work. It uses OpenAI GPT-4 to generate professional quotes with auto-calculated materials and labor.
## Active Focus
- [ ] Smart Packages testing and refinement
- [ ] UI/UX improvements for quote creation flow
- [ ] Ordrestyring API GraphQL migration
## Tech Stack Quick Reference
| Component | Technology | Location |
|-----------|------------|----------|
| Frontend | React 18 + Material-UI | `frontend/` |
| Backend | Node.js/Express | `backend/unified-server.js` |
| Database | MariaDB | localhost:3306, db: `tilbudgivern` |
| AI | OpenAI GPT-4 | `backend/src/services/openaiService.js` |
| Process | PM2 | process: `tilbudgivern-unified` |
| Tests | Playwright, Jest | `tests/`, `backend/__tests__/` |
## Key Features
### Smart Packages (15 packages)
Pre-configured roofing packages with auto-calculation:
- Tagdækning (B7, undertag, rygning)
- Tagrende & Nedløb (Lindab system)
- Tagvinduer (Velux montering)
- Brædder (vindskeder, sternbrædder)
- Specialarbejde (nedrivning, skortrende)
### Roof Types (7 types)
1. Sadeltag (pitched) - default
2. Valmtag (hip)
3. Københavnertag
4. Fladtag (flat)
5. Pulttag (shed)
6. Tag med Kviste (dormers)
7. Mansardtag
## Key Context Links
### Architecture & Setup
- [CLAUDE.md](CLAUDE.md) - Claude Code instructions
- [docs/README.md](docs/README.md) - Documentation index
- [docs/deployment/PM2_GUIDE.md](docs/deployment/PM2_GUIDE.md) - PM2 management
### Features
- [docs/features/SMART_PACKAGES_COMPLETE_CATALOG.md](docs/features/SMART_PACKAGES_COMPLETE_CATALOG.md) - All 15 packages
- [docs/ROOF_TYPES_IMPLEMENTATION.md](docs/ROOF_TYPES_IMPLEMENTATION.md) - 7 roof types with SVG
- [docs/CARPENTER_UX_IMPROVEMENTS.md](docs/CARPENTER_UX_IMPROVEMENTS.md) - Recent UX work
### Integrations
- [docs/api/ORDRESTYRING_API_INVENTORY.md](docs/api/ORDRESTYRING_API_INVENTORY.md) - GraphQL API status
- [docs/STARK_IMPORT_IMPLEMENTATION.md](docs/STARK_IMPORT_IMPLEMENTATION.md) - Stark material import
- [docs/features/BYGMA_IMPORT_FEATURE.md](docs/features/BYGMA_IMPORT_FEATURE.md) - Bygma price book
### Testing
- [docs/UI_TESTING_SETUP.md](docs/UI_TESTING_SETUP.md) - Playwright & Selenium
- [docs/CARPENTER_AGENT_GUIDE.md](docs/CARPENTER_AGENT_GUIDE.md) - Test data generation
### System
- [docs/LOGGING_SYSTEM.md](docs/LOGGING_SYSTEM.md) - Structured logging
- [docs/DATABASE_BACKUP_SETUP.md](docs/DATABASE_BACKUP_SETUP.md) - Backup configuration
## Danish Terminology
| Danish | English |
|--------|---------|
| Tilbud | Quote/Offer |
| Tømrer | Carpenter |
| Tag | Roof |
| Materiale | Material |
| Pakke | Package |
| Pris | Price |
| Tagareal | Roof area |
| Rygning | Ridge |
| Tagrende | Rain gutter |
| Nedløb | Downspout |
| Spær | Rafters |
## Common Commands
```bash
npm run dev # Dev with hot reload
npm run build # Build frontend
pm2 restart tilbudgivern-unified # Restart server
pm2 logs tilbudgivern-unified # View logs
npm run test:pw # Playwright tests
cd backend && npm test # Jest tests
```
## Environment
Required in `backend/.env`:
- `OPENAI_API_KEY`, `DB_HOST`, `DB_USER`, `DB_PASSWORD`, `DB_NAME`
Optional:
- `ORDRESTYRING_API_TOKEN`, `OPENAI_ADMIN_KEY`
## How to Use with AI Assistants
**VS Code Copilot:**
```
@workspace use COPILOT_MEMORY.md for context. Help me with [task].
```
**Claude Code:**
```
Reference CLAUDE.md and COPILOT_MEMORY.md for project context.
```
**Cursor:**
```
See .cursorrules and COPILOT_MEMORY.md for project context.
```
---
*Last updated: January 2026*

180
GEMINI.md Normal file
View File

@@ -0,0 +1,180 @@
# GEMINI.md
This file provides a comprehensive overview of the Tilbudgivern project, its structure, and how to work with it.
## 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.
**Key Features:**
* **AI-generated quotes:** Utilizes OpenAI GPT-4 to generate detailed quotes.
* **Interactive feedback:** Allows for adjustments to quotes based on feedback.
* **Price database:** Built-in database with experience-based prices for carpentry work.
* **Responsive design:** Works on both desktop and mobile.
* **Audit trail:** Saves all quotes and feedback for analysis.
* **Smart Packages:** 15 pre-configured carpenter packages for roofing work that auto-calculate based on geometry.
* **Roof Geometry Calculation:** Supports 7 different roof types for accurate area calculations.
* **Ordrestyring Integration:** Integrates with the Ordrestyring GraphQL API for customer, case, and offer management.
## 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 Frontend Components (`frontend/src/components/`)
* `InlineSmartPackage.js`: Smart package wizard with a 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, and tooltips.
## Technologies
* **Frontend:** React 18 with Material-UI
* **Backend:** Node.js with Express
* **Database:** MariaDB/MySQL (running on host, not containerized)
* **AI:** OpenAI GPT-4 API
* **Containerization:** Docker (for PostgreSQL in older setups)
* **Process Manager:** PM2 (process name: `tilbudgivern-unified`)
* **Testing:** Playwright, Selenium, Jest
## Getting Started
### Prerequisites
* Node.js 18+
* Docker and Docker Compose (for older setups)
* MariaDB/MySQL
* OpenAI API key
* Ordrestyring API token
### Quick Start
1. **Install dependencies:**
```bash
# Root project
npm install
# Backend
cd backend
npm install
# Frontend
cd ../frontend
npm install
cd ..
```
2. **Set up the database:**
* The project uses a MariaDB/MySQL database. Ensure it is installed and running.
* The database name is `tilbudgivern`.
* Schema files can be found in `database/schema_system_logs.sql` and migrations in `database/migrations/` and `backend/migrations/`.
3. **Configure the environment:**
Create a `.env` file in the `backend` directory and add the following:
```
OPENAI_API_KEY=sk-your-actual-openai-api-key-here
DB_HOST=localhost
DB_USER=your-db-user
DB_PASSWORD=your-db-password
DB_NAME=tilbudgivern
ORDRESTYRING_API_TOKEN=your-ordrestyring-api-token
```
4. **Start the application:**
```bash
npm run dev
```
This command starts the unified server with hot reload.
## Building, Running, and Testing
### Development
* **Start development server:** `npm run dev`
* **Build frontend:** `npm run build`
* **Start unified server (production):** `npm run start`
### PM2 (Process Manager)
* **Restart application:** `pm2 restart tilbudgivern-unified`
* **View logs:** `pm2 logs tilbudgivern-unified`
* **Check status:** `pm2 status`
### Testing
* **Playwright UI tests (production):** `npm run test:pw`
* **Playwright UI tests (local):** `npm run test:pw:local`
* **Playwright interactive UI mode:** `npm run test:pw:ui`
* **Playwright with visible browser:** `npm run test:pw:headed`
* **Selenium UI tests:** `npm run test:selenium`
* **Backend unit tests (Jest):** `cd backend && npm test`
## Deployment
The application is deployed using PM2. A detailed deployment guide can be found in `docs/deployment/DEPLOYMENT.md`.
## Development Conventions
* **Coding Style:** Follow the existing patterns in each folder. The frontend uses `react-scripts` with the default ESLint config.
* **Commit Messages:** Use Conventional Commits (e.g., `feat: ...`).
* **Pull Requests:** PRs should include a brief summary, test evidence, and screenshots for UI changes.
## External Integrations
### Ordrestyring API
* **GraphQL endpoint:** `https://beta7-api.ordrestyring.dk/graphql`
* **Purpose:** Used for customers, cases, offers, calendar, and hours tracking.
* **Documentation:** A complete guide to the Ordrestyring API integration can be found in `apitest/README.md`.
### Material Suppliers
* **Bygma:** Price book import, installation manuals.
* **Stark:** CSV catalog import via `/api/stark/upload`.
## Database
* **Type:** MariaDB/MySQL
* **Database Name:** `tilbudgivern`
* **Key Tables:** `smart_packages`, `package_tasks`, `package_materials`, `materials`, `customers`, `projects`
* **Schema:** `database/schema_system_logs.sql`
* **Migrations:** `database/migrations/`, `backend/migrations/`
## Logging
The backend implements structured JSON logging with correlation IDs for end-to-end request tracing. Logs are persisted in the `system_logs` table. See `backend/LOGGING.md` for more details.
## 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