236 lines
7.7 KiB
Markdown
236 lines
7.7 KiB
Markdown
# Aufgabe 1 - Architekturentwurf
|
|
|
|
## Überblick
|
|
|
|
Ich hab mich für eine relativ klassische Architektur entschieden. Nichts fancy, aber sollte funktionieren. Der Gedanke war ein System zu bauen das:
|
|
- Beim Kunden einfach deployed werden kann (wer hat schon Lust auf kompliziertes Setup)
|
|
- Nicht overengineered ist (hab nur 4-6 Stunden)
|
|
- Aber trotzdem solid genug aussieht um damit zu arbeiten
|
|
|
|
## 1. Komponenten
|
|
|
|
### API Layer
|
|
**Was:** Express.js Backend mit TypeScript
|
|
**Warum Express?** Ehrlich gesagt weil ich's gut kenne. Hätte auch NestJS nehmen können aber das wäre für die Zeit zu viel gewesen. Express ist straightforward, es gibt Lösungen für alles auf StackOverflow, und ich kann schnell produktiv sein.
|
|
|
|
**Port:** 3990
|
|
|
|
Die API ist simpel:
|
|
- `POST /orders` - Hauptfunktion
|
|
- `GET /orders` - Hab ich als Bonus dazugemacht weil man ja die Orders auch sehen will
|
|
|
|
### Datenbank
|
|
**Was:** SQLite3
|
|
**Warum?** Ok, das war eine bewusste Entscheidung.
|
|
- Keine DB-Installation nötig
|
|
- Eine Datei, fertig
|
|
- Backup ist ein simple file copy
|
|
|
|
|
|
**Schema:**
|
|
Relativ simpel gehalten. Order hat die basics, Items und Address hab ich als JSON gespeichert. Ich weiß, manche Leute mögen kein JSON in der DB, aber für sowas ist's meiner Meinung nach ok - wir machen keine komplexen Joins darauf und es bleibt flexibel.
|
|
|
|
### Event-System
|
|
**Was:** Console Logs (Simulation)
|
|
**Warum so basic?** Weil ich zeigen wollte dass ich verstehe wie's funktionieren sollte, ohne jetzt ne ganze Message Queue aufzusetzen. In einem echten Projekt würde ich wahrscheinlich RabbitMQ nehmen (hab damit schon gearbeitet) oder wenn's viel Traffic ist Kafka, aber das ist dann halt ein anderes Level.
|
|
|
|
Das Prinzip ist klar: Order wird erstellt → Event wird gefeuert → andere Services können reagieren. Momentan logge ich nur:
|
|
- "Shipping System: neue Order"
|
|
- "Warehouse: Artikel vorbereiten"
|
|
- "Email: Bestätigung schicken"
|
|
|
|
Reicht glaub ich um die Idee rüberzubringen.
|
|
|
|
### Validierung
|
|
**Was:** Zod
|
|
**Warum?** Hab's in einem Tutorial gesehen und fand's gut. Du kriegst Runtime-Validation und die TypeScript-Types automatisch. Besser als alles manuell zu checken. Die Syntax ist auch relativ clean.
|
|
|
|
### Frontend
|
|
**Was:** React + Material UI + Vite
|
|
**Warum dieser Stack?**
|
|
- React weil ich's kann und's standard ist
|
|
- Material UI weil ich nicht alles selbst stylen wollte - in 30 min hab ich damit ein ok aussehendes UI
|
|
- Vite weil's schneller startet als Create React App und ich nicht ewig auf den dev server warten will
|
|
|
|
Nicht die perfekte Wahl für jedes Projekt aber für die Challenge vollkommen ok.
|
|
|
|
### Authentifizierung
|
|
**Was:** Nicht implementiert
|
|
**Warum?** Stand nicht in den Requirements und hätte echt Zeit gefressen. Wenn ich's machen müsste würde ich wahrscheinlich JWT nehmen, hab damit in anderen Projekten schon gearbeitet. Access token + refresh token pattern, standard halt.
|
|
|
|
## 2. Datenfluss beim Erstellen einer Bestellung
|
|
|
|
So läuft's ab (hoffe ich hab nichts vergessen):
|
|
|
|
```
|
|
1. User füllt Form aus
|
|
- React validiert schonmal das Basics (ist Email format ok, etc.)
|
|
|
|
2. Submit → POST /orders ans Backend
|
|
- CORS ist allowed (hab ich configured)
|
|
|
|
3. Backend: Zod Validation
|
|
- Checkt alle Felder
|
|
- Items array nicht leer?
|
|
- Prices sind numbers?
|
|
- etc.
|
|
- Wenn was fehlt → 400 zurück
|
|
|
|
4. Business Logic
|
|
- Ich rechne den total amount aus (reduce über items)
|
|
- Generiere eine Order Number (hab einfach timestamp + random number genommen)
|
|
- Status = 'pending'
|
|
|
|
5. Database Insert
|
|
- SQLite INSERT
|
|
- Items/Address werden zu JSON gestringified
|
|
- Wenn das fehlschlägt → 500 error
|
|
|
|
6. Events triggern
|
|
- Console.logs für die verschiedenen Services
|
|
- In echt würden hier Messages in Queues gehen
|
|
|
|
7. Response
|
|
- 201 Created
|
|
- Komplettes Order Object zurück
|
|
- Frontend zeigt Success Message
|
|
|
|
8. Frontend reagiert
|
|
- Form wird resettet
|
|
- Success Alert erscheint
|
|
- (Optional könnte man zu Orders List redirecten)
|
|
```
|
|
|
|
Dauert normalerweise unter 100ms weil alles lokal ist.
|
|
|
|
## 3. Deployment-Strategie
|
|
|
|
### Docker
|
|
Ich hab Docker Compose genommen weil:
|
|
- Ich's kenne und schnell damit bin
|
|
- Funktioniert überall gleich (Mac, Linux, Windows)
|
|
- Kunde muss nur `docker compose up` machen
|
|
- Keine Abhängigkeits-Konflikte
|
|
|
|
**Setup:**
|
|
2 Container - Backend und Frontend. Backend ist Node, Frontend wird mit nginx ausgeliefert. Hab multi-stage build verwendet um die Images kleiner zu halten.
|
|
|
|
### On-Premise beim Kunden
|
|
Da's beim Kunden on-premise laufen soll hab ich's simpel gehalten:
|
|
|
|
**Easy way:**
|
|
```bash
|
|
git clone
|
|
docker compose up -d
|
|
# done
|
|
```
|
|
|
|
Der Kunde braucht nur Docker installiert zu haben.
|
|
|
|
**Wenn's professional sein soll:**
|
|
- Images in private Registry
|
|
- Kunde zieht nur die Images (kein source code)
|
|
- .env file für Config
|
|
- Backup-Script für die DB
|
|
|
|
### CI/CD
|
|
Hab ich nicht implementiert (war ja nicht gefordert) aber wenn ich's machen würde:
|
|
- GitHub Actions (hab damit schon gearbeitet), workflow (gitea)
|
|
- Tests laufen lassen
|
|
- Images bauen
|
|
- Zu Registry pushen
|
|
- Optional auto-deploy zu staging
|
|
|
|
## 4. Skalierbarkeit, Sicherheit, Monitoring & Fehlerhandling
|
|
|
|
### Skalierbarkeit
|
|
|
|
**Aktueller Stand:** Einzelne Instanz, sollte für kleinere Kunden ok sein
|
|
|
|
**Wenn's größer wird:**
|
|
|
|
Ehrlich gesagt hab ich da keine super viel Erfahrung mit high-scale Systems, aber was ich mir vorstellen würde:
|
|
|
|
1. **Mehr Backend-Instanzen**
|
|
- Load Balancer davor (nginx kann das)
|
|
- SQLite wird dann zum Problem, also PostgreSQL
|
|
- Connection pooling nicht vergessen
|
|
|
|
2. **Database Optimization**
|
|
- Indexes auf die richtigen Felder (orderNumber, customerId)
|
|
- Vielleicht Read Replicas wenn's viele GET requests gibt
|
|
- Oder gleich managed DB nehmen (weniger Stress)
|
|
|
|
3. **Caching** (wenn nötig)
|
|
- Redis für häufige Queries
|
|
- Aber erstmal messen ob's wirklich gebraucht wird
|
|
|
|
Ich würde ehrlich gesagt erstmal abwarten wo die Bottlenecks sind bevor ich zu viel optimiere. Premature optimization und so.
|
|
|
|
### Sicherheit
|
|
|
|
**Was drin ist:**
|
|
- Input Validation mit Zod
|
|
- SQL Injection kann nicht passieren (prepared statements)
|
|
- CORS ist an (aber nicht restricted - müsste man noch machen)
|
|
|
|
Ich weiß dass da noch viel fehlt, aber für einen Prototyp sollte es ok sein. In einem echten Projekt würde man da mehr Zeit reinstecken.
|
|
|
|
### Monitoring
|
|
|
|
**Aktuell:** Console logs, super basic
|
|
|
|
Viel mehr kann ich dazu ehrlich gesagt nicht sagen weil ich's nicht in Production betreut hab. Aber das wären so die basics die Sinn machen würden.
|
|
|
|
### Fehlerhandling
|
|
|
|
**Mein Approach:**
|
|
|
|
Ich hab versucht die Errors sinnvoll zu kategorisieren:
|
|
|
|
```typescript
|
|
try {
|
|
// business logic
|
|
} catch (error) {
|
|
if (error.name === 'ZodError') {
|
|
// User hat Müll geschickt
|
|
return 400
|
|
}
|
|
// Irgendwas ist bei uns kaputt
|
|
console.error(error)
|
|
return 500
|
|
}
|
|
```
|
|
|
|
**Was ich beachtet hab:**
|
|
- 400 = User-Fehler (falsche inputs)
|
|
- 500 = Server-Fehler (unser Problem)
|
|
- Nie stack traces an den User schicken (security)
|
|
- Alles loggen für debugging
|
|
|
|
**Frontend Error Handling:**
|
|
- Try/catch um API calls
|
|
- User-freundliche Messages ("Bestellung konnte nicht erstellt werden" statt "500 Internal Server Error")
|
|
- Form bleibt gefüllt wenn's fehlschlägt (user muss nicht alles nochmal eingeben)
|
|
|
|
|
|
## Zusammenfassung & Ehrliche Einschätzung
|
|
|
|
**Was ich anders machen würde mit mehr Zeit:**
|
|
- PostgreSQL von Anfang an (Migration ist nervig)
|
|
- Echte Message Queue für Events
|
|
- Auth System
|
|
- Mehr Tests (hab nur die wichtigsten)
|
|
- Admin Dashboard wäre cool
|
|
|
|
**Nächste Schritte wenn's weitergeht:**
|
|
1. PostgreSQL Migration (wichtigste)
|
|
2. Message Queue (RabbitMQ maybe)
|
|
3. Auth hinzufügen (JWT)
|
|
4. Mehr Error handling
|
|
5. Production Monitoring setup
|
|
|
|
Ich denke für eine Challenge ist das ein ok Ergebnis. Nicht perfekt, aber funktioniert und ist ein guter Ausgangspunkt.
|
|
|
|
---
|