# QR-Invoice Service

Swiss QR-Bill PDF Generation Service für Schweizer Zahlscheine nach SIX-Spezifikation.

## Projektübersicht

Ein Node.js/TypeScript HTTP-Service, der JSON-Daten über einen Webhook empfängt und eine PDF mit Swiss QR-Zahlteil generiert.

## Tech Stack

- **Runtime**: Node.js 18+
- **Sprache**: TypeScript
- **HTTP Framework**: Fastify 4
- **PDF-Generierung**: swissqrbill + pdfkit
- **Validierung**: Zod

## Projektstruktur

```
src/
├── index.ts              # Entry Point, startet Server
├── app.ts                # Fastify App Konfiguration
├── config/index.ts       # Umgebungsvariablen (PORT, HOST, LOG_LEVEL)
├── types/                # TypeScript Interfaces
├── schemas/              # Zod Validierungsschemas
├── services/             # Business Logic (QR-Bill Generierung)
├── routes/               # API Endpoints
└── errors/               # Error Handler
```

## Wichtige Befehle

```bash
npm run dev       # Entwicklungsserver mit Hot-Reload (tsx watch)
npm run build     # TypeScript kompilieren nach dist/
npm run start     # Produktionsserver starten
npm run typecheck # TypeScript Typprüfung
```

## API Endpoints

| Method | Path | Beschreibung |
|--------|------|--------------|
| POST | `/api/v1/invoice/qr-bill` | Generiert QR-Bill PDF |
| GET | `/health` | Health Check |
| GET | `/health/ready` | Readiness Probe |

## Request Format (POST /api/v1/invoice/qr-bill)

```json
{
  "creditor": {
    "iban": "CH4431999123000889012",
    "address": {
      "name": "Firma AG",
      "street": "Strasse",
      "buildingNumber": "123",
      "postalCode": "8000",
      "city": "Zürich",
      "country": "CH"
    }
  },
  "amount": 1949.75,
  "currency": "CHF",
  "reference": {
    "type": "QRR",
    "value": "210000000003139471430009017"
  },
  "debtor": {
    "address": { ... }
  },
  "additionalInformation": {
    "message": "Rechnung Nr. 123"
  },
  "options": {
    "language": "de",
    "separate": true
  }
}
```

## Validierungsregeln (SIX-Spezifikation)

- **QRR** (QR-Referenz): 27 Ziffern, Modulo 10 rekursiv, erfordert QR-IBAN (IID 30000-31999)
- **SCOR** (Creditor Reference): ISO 11649, erfordert normale IBAN
- **NON** (Ohne Referenz): Erfordert normale IBAN
- **Strukturierte Adressen**: Pflicht seit November 2025
- **Betrag**: 0.01 - 999'999'999.99, max. 2 Dezimalstellen
- **Währung**: CHF oder EUR

## Umgebungsvariablen

| Variable | Default | Beschreibung |
|----------|---------|--------------|
| PORT | 3000 | Server Port |
| HOST | 0.0.0.0 | Server Host |
| LOG_LEVEL | info | Pino Log Level |

## Testen

```bash
# Server starten
npm run dev

# Test-Request senden
curl -X POST http://localhost:3000/api/v1/invoice/qr-bill \
  -H "Content-Type: application/json" \
  -d @test-request.json \
  -o output.pdf
```

## Wichtige Dateien

- `src/schemas/qr-invoice.schema.ts` - Zod Schema mit Cross-Validation für IBAN/Referenz
- `src/services/qr-bill.service.ts` - PDF-Generierung mit swissqrbill
- `src/routes/invoice.routes.ts` - API Endpoint Implementation
- `test-request.json` - Beispiel-Request für Tests

## Externe Ressourcen

- [SIX QR-Bill Spezifikation](https://www.six-group.com/dam/download/banking-services/standardization/qr-bill/ig-qr-bill-v2.3-en.pdf)
- [swissqrbill Dokumentation](https://github.com/schoero/swissqrbill)
