Files
tilbudgivern/.github/copilot-instructions.md
T
alexpolo1 bbb75ccce2 feat: Add Advanced Dashboard and perform repo cleanup
This commit introduces a new Advanced Dashboard feature, which provides enhanced analytics and system health monitoring.

Additionally, this commit includes a general repository cleanup, which consists of:

- Removal of a duplicate  file from the root directory.
- Addition of temporary report and documentation files to .
- Relocation of several test files from the root to the  directory.
- Staging of various other modified files that were previously uncommitted.

The new Advanced Dashboard feature includes:
-  and  for the UI.
-  for the backend API.
-  for API documentation.

New tests for smart packages and autosave functionality have also been added.
2026-02-28 17:38:23 +00:00

237 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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)
## Copilot Agent Optimization
Use these focused patterns so Copilot generates changes that fit the repo’s architecture, style, and workflows.
### Prompt Patterns (copy/paste-ready)
- Implement API route: "Create `POST /api/smart-packages/recalculate` in backend unified server with `asyncHandler`, correlation ID logging, `{ success, data/error }` response, and unit + Playwright tests."
- Add service method: "Add `calculateRoofMetrics({ roofType, geometry })` in `backend/src/services/geometryService.js` with input validation and structured logging."
- React component change: "Update `frontend/src/components/InlineSmartPackage` to display recalculated prices, using Material-UI and existing hook patterns."
- Database migration: "Create migration to add `package_materials.extra_cost_pct` with default 0, update service to include it in totals, and write a rollback."
- Playwright test: "Write a test for selecting `Valmtag` and verifying ridge length and price recalculation on the quote page."
- Ordrestyring integration: "Add GraphQL query for cases with token from `.env` `ORDRESTYRING_API_TOKEN`, wrap with retry and error types."
### Task Playbooks
- New API endpoint
1. Add route in `backend/src/routes/` using `asyncHandler` and correlation IDs from request.
2. Implement logic in `backend/src/services/` with pure, testable functions.
3. Return `{ success: true/false, data/error }` and Danish error messages.
4. Add Jest unit tests for service + route.
5. Add Playwright E2E covering happy path and error states.
- Smart Package update (pricing/logic)
1. Adjust schema in `migrations/` and ensure MariaDB compatibility.
2. Update `openaiService`, `databaseService`, or `smartPackagesService` accordingly.
3. Reflect changes in React components under `frontend/src/components/`.
4. Seed/update fixtures for tests; verify totals and materials.
- Roof geometry calculators
1. Add calculator functions per roof type in `geometryService`.
2. Validate inputs (tagareal, rygningslængde, facadelængde).
3. Log with correlation IDs; return deterministic results for tests.
4. UI: expose selectors and results in existing components.
- Ordrestyring API usage
1. Create GraphQL client wrapper with token from `.env`.
2. Add typed responses and error typing.
3. Backoff/retry for transient failures.
4. Map into internal DTOs; log external request IDs.
### Coding Guardrails
- **Async/await:** Use `asyncHandler` for all route handlers; no raw `try/catch` without logging.
- **Structured logging:** Always call `logger.logInfo()`/`logger.logError()` with correlation IDs and contextual fields.
- **Response format:** Strictly return `{ success: true/false, data/error }` with Danish user-facing errors.
- **Naming:** Prefer domain names (quote, roof-type, smart-package, carpenter) and avoid cross-cutting helpers.
- **React:** Functional components + hooks with Material-UI; follow patterns in `frontend/src/components/`.
- **DB:** Keep services small, pure, and tested; avoid coupling route logic with DB queries.
- **AI costs:** Respect budget; avoid unnecessary OpenAI calls. Cache or batch when feasible.
### Testing Expectations
- **Unit (Jest):** Add tests per service and route; aim for deterministic outputs and 80%+ coverage for new modules.
- **E2E (Playwright):** Cover critical user flows (select roof type, calculate, save quote) and common error states.
- **Local runs:** Ensure unified server on port 4032; use env vars from `backend/.env`.
- **Artifacts:** Attach screenshots and logs for failures in `playwright-report/`.
### Danish Terminology & UX
- Use domain-correct Danish terms (Tag, Spær, Tagrende, Nedløb, Vindsked, Sternbræt, Tagareal, Rygningslængde, Facadelængde).
- Keep UI labels concise and professional; prioritize carpenters’ workflows.
- Error messages in Danish; logs in English/Danish mixed are acceptable if consistent.
### Security & Secrets
- Read secrets from `backend/.env` only; never commit credentials.
- Validate all user inputs for endpoints; sanitize query params and payloads.
- Use the logging + correlation ID checklist for sensitive operations (customers, offers, materials pricing).
### Pull Requests & Commits
- Favor Conventional Commits (e.g., `feat: smart package recalculation endpoint`).
- Include a summary, test evidence (commands + results), and UI screenshots for relevant changes.
## 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
```
### Test & Dev Helpers
```bash
# Local Playwright against unified server
npm run test:pw:local
# Selenium UI tests against localhost
npm run test:selenium:local
# Full test + build + PM2 restart
./test-build-deploy.sh
# Quick deploy for small changes
./quick-deploy.sh
```
## 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
## Custom Agents
### carpenter-user-tester
**When to use:** Need realistic user testing from a carpenter's perspective, evaluating UI/UX for trade professionals, validating that carpentry terminology and workflows make sense, or getting feedback on features from the viewpoint of a busy tømrer (carpenter) running their own business.
**Persona:** Lars, a 47-year-old Danish master carpenter (tømrermester) with 22 years of business experience in Jylland, specializing in roofing work.
**Expertise:**
- Expert in all 7 roof types (sadeltag, valmtag, københavnertag, fladtag, pulttag, tag med kviste, mansardtag)
- Deep knowledge of materials and suppliers (Bygma, Stark)
- Creates 5-10 quotes weekly, often after long workdays
- Prefers simple, practical software that "just works"
**Testing Focus:**
1. **Praktisk anvendelighed** - Can I use this after a long day on the roof?
2. **Faglig korrekthed** - Is the terminology correct for Danish carpenters?
3. **Forretningsforståelse** - Will this help win jobs without losing money?
4. **Hverdagssituationer** - How does it handle real-world scenarios?
**Use Examples:**
- After implementing new UI components for quote generation
- When adding or changing Danish carpentry terminology
- Testing workflow changes to Smart Packages
- Validating roof geometry calculators
- Reviewing quote presentation to customers
**Output Format:**
- Førsteindtryk (First Impression)
- Det der virker (What Works)
- Udfordringer (Challenges)
- Forslag (Suggestions)
- Faglig vurdering (Professional Assessment)
- Samlet dom (Overall Verdict)
**Invoke with:** "@carpenter-user-tester" or mention need for trade-professional UX feedback