Merge pull request #1 from Kenearos/claude/add-claude-documentation-xG5RA
docs: Add comprehensive CLAUDE.md for AI assistant guidance
This commit is contained in:
commit
5887243355
1 changed files with 282 additions and 0 deletions
282
CLAUDE.md
Normal file
282
CLAUDE.md
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
# CLAUDE.md - AI Assistant Guide for Dienstplan-Pro
|
||||
|
||||
## Project Overview
|
||||
|
||||
**Dienstplan-Pro** is a German-language Progressive Web App (PWA) for calculating bonus payments for weekend and holiday duty shifts according to NRW (Nordrhein-Westfalen) regulations. The application is designed for healthcare or similar organizations that need to track employee on-call duties and calculate corresponding bonuses.
|
||||
|
||||
**Primary Language**: German (UI, comments, and documentation)
|
||||
**Tech Stack**: Vanilla JavaScript, HTML5, CSS3, LocalStorage API
|
||||
**Deployment**: Docker container with Node.js `serve`, designed for Railway hosting
|
||||
|
||||
## Architecture
|
||||
|
||||
### File Structure
|
||||
|
||||
```
|
||||
Dienstplan-Pro/
|
||||
├── index.html # Main HTML entry point with tab-based UI
|
||||
├── app.js # Main application class (DienstplanApp) - UI management
|
||||
├── calculator.js # BonusCalculator class - core business logic
|
||||
├── holidays.js # HolidayProvider class - NRW holiday data 2025-2030
|
||||
├── storage.js # DataStorage class - LocalStorage persistence
|
||||
├── styles.css # All CSS styles (responsive, gradient theme)
|
||||
├── sw.js # Service Worker for PWA offline support
|
||||
├── manifest.json # PWA manifest configuration
|
||||
├── test-suite.js # Comprehensive test runner with assertions
|
||||
├── test.html # Browser-based test interface
|
||||
├── Dockerfile # Production deployment configuration
|
||||
├── README.md # User documentation (German)
|
||||
└── TEST_GUIDE.md # Testing documentation (German)
|
||||
```
|
||||
|
||||
### Module Responsibilities
|
||||
|
||||
| Module | Class | Purpose |
|
||||
|--------|-------|---------|
|
||||
| `app.js` | `DienstplanApp` | UI orchestration, event handling, user interactions |
|
||||
| `calculator.js` | `BonusCalculator` | Bonus calculation logic, day type classification |
|
||||
| `holidays.js` | `HolidayProvider` | NRW public holiday lookup (2025-2030) |
|
||||
| `storage.js` | `DataStorage` | LocalStorage CRUD operations, import/export |
|
||||
|
||||
### Global Dependencies
|
||||
|
||||
All classes are attached to `window` for cross-module access:
|
||||
- `window.DienstplanApp` (instantiated as global `app`)
|
||||
- `window.BonusCalculator`
|
||||
- `window.HolidayProvider`
|
||||
- `window.DataStorage`
|
||||
|
||||
Script loading order in `index.html` is critical:
|
||||
1. `holidays.js`
|
||||
2. `calculator.js`
|
||||
3. `storage.js`
|
||||
4. `app.js`
|
||||
|
||||
## Business Logic
|
||||
|
||||
### Qualifying Days (WE/Feiertag)
|
||||
|
||||
A day is "qualifying" (eligible for higher bonus rate) if ANY of:
|
||||
- **Weekend**: Friday (5), Saturday (6), or Sunday (0)
|
||||
- **Public Holiday**: Any NRW state holiday
|
||||
- **Day Before Holiday**: The calendar day preceding a public holiday
|
||||
|
||||
### Bonus Calculation Rules
|
||||
|
||||
```
|
||||
Constants:
|
||||
- RATE_NORMAL = 250€ (normal weekday rate)
|
||||
- RATE_WEEKEND = 450€ (qualifying day rate)
|
||||
- MIN_QUALIFYING_DAYS = 2.0 (threshold)
|
||||
- DEDUCTION_AMOUNT = 2.0 (deducted from qualifying days)
|
||||
|
||||
Algorithm:
|
||||
1. Count qualifying days (Friday, Sat, Sun, holidays, day-before-holiday)
|
||||
2. Count normal days (Mon-Thu, not holiday-related)
|
||||
3. If qualifyingDays < 2.0: NO BONUS (total = 0€)
|
||||
4. If qualifyingDays >= 2.0:
|
||||
- Deduct 2.0 from qualifying days (Friday priority)
|
||||
- Bonus = (normalDays × 250€) + (remainingQualifyingDays × 450€)
|
||||
```
|
||||
|
||||
### Friday Priority Deduction
|
||||
|
||||
When deducting the 2.0 qualifying days, Fridays are deducted first before Saturday/Sunday/holidays. This is tracked via `qualifyingDaysFriday` and `qualifyingDaysOther` in the calculator.
|
||||
|
||||
### Duty Shares
|
||||
|
||||
Duties can be full (1.0) or half (0.5). Half duties count as 0.5 toward all calculations.
|
||||
|
||||
## Data Storage
|
||||
|
||||
### LocalStorage Keys
|
||||
|
||||
```javascript
|
||||
STORAGE_KEY_EMPLOYEES = 'dienstplan_employees' // Array of employee names
|
||||
STORAGE_KEY_DUTIES = 'dienstplan_duties' // Nested duty object
|
||||
```
|
||||
|
||||
### Data Structure
|
||||
|
||||
```javascript
|
||||
// Employees: string[]
|
||||
["Max Mustermann", "Anna Schmidt"]
|
||||
|
||||
// Duties: { employeeName: { "YYYY-MM": duties[] } }
|
||||
{
|
||||
"Max Mustermann": {
|
||||
"2025-11": [
|
||||
{ "date": "2025-11-22T11:00:00.000Z", "share": 1.0 },
|
||||
{ "date": "2025-11-23T11:00:00.000Z", "share": 0.5 }
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Date Handling
|
||||
|
||||
- Dates are stored as ISO strings in LocalStorage
|
||||
- Use `T12:00:00` when creating dates to avoid timezone edge cases
|
||||
- Dates are converted back to Date objects when retrieved
|
||||
|
||||
## UI Structure
|
||||
|
||||
The app uses a tab-based interface with 4 sections:
|
||||
1. **Dienste eintragen** (Enter Duties) - Add/remove shifts
|
||||
2. **Berechnung** (Calculation) - Calculate and view bonuses
|
||||
3. **Mitarbeiter verwalten** (Manage Employees) - CRUD for employees
|
||||
4. **Einstellungen** (Settings) - Export/import, rules info, data clearing
|
||||
|
||||
### Toast Notifications
|
||||
|
||||
Use `app.showToast(message, type)` where type is:
|
||||
- `'success'` - Green
|
||||
- `'error'` - Red
|
||||
- `'info'` - Blue
|
||||
|
||||
## Testing
|
||||
|
||||
### Running Tests
|
||||
|
||||
1. Serve the app: `python3 -m http.server 8000` or use the Docker container
|
||||
2. Open `http://localhost:8000/test.html`
|
||||
3. Click "Alle Tests ausführen"
|
||||
|
||||
### Test Categories
|
||||
|
||||
- **HolidayProvider**: Holiday detection, day-before-holiday
|
||||
- **Calculator - Tag-Klassifizierung**: Day type classification
|
||||
- **Calculator - Bonusberechnung**: Bonus calculation scenarios
|
||||
- **Storage**: CRUD operations, import/export
|
||||
- **Edge Cases**: Rounding, performance, leap years
|
||||
|
||||
### Adding Tests
|
||||
|
||||
```javascript
|
||||
runner.test('Test Name', (t) => {
|
||||
const calculator = new BonusCalculator(new HolidayProvider());
|
||||
const duties = [{ date: new Date('2025-11-22T12:00:00'), share: 1.0 }];
|
||||
const result = calculator.calculateMonthlyBonus(duties);
|
||||
|
||||
t.assertEqual(result.totalBonus, 450, 'Expected bonus');
|
||||
t.assertTrue(result.thresholdReached, 'Threshold should be reached');
|
||||
t.assertAlmostEqual(result.qualifyingDays, 1.0, 0.01, 'Qualifying days');
|
||||
});
|
||||
```
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### Local Development
|
||||
|
||||
```bash
|
||||
# Option 1: Python server
|
||||
python3 -m http.server 8000
|
||||
|
||||
# Option 2: Node.js
|
||||
npx http-server -p 8000
|
||||
|
||||
# Option 3: Docker
|
||||
docker build -t dienstplan-pro .
|
||||
docker run -p 3000:3000 -e PORT=3000 dienstplan-pro
|
||||
```
|
||||
|
||||
### Making Changes
|
||||
|
||||
1. All JavaScript is vanilla ES6+ classes
|
||||
2. No build step required
|
||||
3. Refresh browser to see changes
|
||||
4. Run test suite after changes
|
||||
|
||||
### Deployment (Railway)
|
||||
|
||||
The Dockerfile uses `serve` from npm to serve static files:
|
||||
```dockerfile
|
||||
FROM node:20-alpine
|
||||
RUN npm install -g serve
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
CMD serve -s . -l tcp://0.0.0.0:${PORT:-3000}
|
||||
```
|
||||
|
||||
## Code Conventions
|
||||
|
||||
### Language
|
||||
|
||||
- All user-facing text: **German**
|
||||
- Code comments: **German** (existing pattern)
|
||||
- Variable/function names: **English** (existing pattern)
|
||||
|
||||
### Naming
|
||||
|
||||
- Classes: PascalCase (`BonusCalculator`, `DataStorage`)
|
||||
- Methods/functions: camelCase (`calculateMonthlyBonus`, `isHoliday`)
|
||||
- Constants: UPPER_SNAKE_CASE (`RATE_NORMAL`, `STORAGE_KEY_DUTIES`)
|
||||
- DOM IDs: kebab-case (`employee-select-duty`, `calc-month-select`)
|
||||
|
||||
### Error Handling
|
||||
|
||||
- Storage operations include try/catch with German console.error messages
|
||||
- User-facing errors shown via toast notifications
|
||||
- Invalid data returns empty arrays/objects rather than throwing
|
||||
|
||||
### Date Format
|
||||
|
||||
- Display: German locale `toLocaleDateString('de-DE')`
|
||||
- Storage: ISO string
|
||||
- Internal: JavaScript Date objects with noon time (`T12:00:00`)
|
||||
|
||||
## Common Tasks
|
||||
|
||||
### Adding a New Holiday
|
||||
|
||||
Edit `holidays.js`, add to the appropriate year array:
|
||||
```javascript
|
||||
{ date: 'YYYY-MM-DD', name: 'Holiday Name' }
|
||||
```
|
||||
|
||||
### Modifying Calculation Rules
|
||||
|
||||
Edit `calculator.js` constants:
|
||||
```javascript
|
||||
this.RATE_NORMAL = 250;
|
||||
this.RATE_WEEKEND = 450;
|
||||
this.MIN_QUALIFYING_DAYS = 2.0;
|
||||
this.DEDUCTION_AMOUNT = 2.0;
|
||||
```
|
||||
|
||||
### Adding Export Formats
|
||||
|
||||
The app supports multiple export formats in `app.js`:
|
||||
- `exportData()` - JSON backup
|
||||
- `exportCSV()` - Excel-compatible CSV with BOM
|
||||
- `exportBonusReport()` - HTML report for printing/PDF
|
||||
- `generateEmailReport()` - Copyable email text
|
||||
|
||||
### Extending the UI
|
||||
|
||||
1. Add HTML in `index.html` within appropriate tab-content div
|
||||
2. Add event listener in `setupEventListeners()` in `app.js`
|
||||
3. Implement handler method in `DienstplanApp` class
|
||||
4. Style in `styles.css` following existing patterns
|
||||
|
||||
## PWA Features
|
||||
|
||||
- **Service Worker** (`sw.js`): Caches all assets for offline use
|
||||
- **Manifest** (`manifest.json`): Enables "Add to Home Screen"
|
||||
- **Cache Version**: `dienstplan-pro-v1` (increment when updating assets)
|
||||
|
||||
## Key Gotchas
|
||||
|
||||
1. **Timezone Issues**: Always use `T12:00:00` when creating dates from strings to avoid midnight edge cases
|
||||
2. **LocalStorage Limits**: ~5MB, sufficient for typical use but no warning when approaching limit
|
||||
3. **Float Precision**: Use `assertAlmostEqual` in tests for floating-point comparisons
|
||||
4. **Script Order**: `holidays.js` must load before `calculator.js`
|
||||
5. **Employee Deletion**: Removes all associated duties automatically
|
||||
6. **Duty Updates**: Adding a duty on existing date replaces (not duplicates)
|
||||
|
||||
## Git Conventions
|
||||
|
||||
Recent commit patterns:
|
||||
- `feat:` New features
|
||||
- `fix:` Bug fixes
|
||||
- Keep commit messages concise and descriptive
|
||||
Loading…
Add table
Add a link
Reference in a new issue