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.
237 lines
10 KiB
Markdown
237 lines
10 KiB
Markdown
# 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
|