# System-Architektur - PointCab Webexport Server
Diese Dokumentation beschreibt die technische Architektur des Systems.
## ποΈ Γbersicht
```
βββββββββββββββββββ βββββββββββββββββββββ βββββββββββββββββββ
β Browser ββββββΊβ Nginx Proxy ββββββΊβ NestJS β
β (Client) β β Manager (443) β β (Port 3000) β
βββββββββββββββββββ βββββββββββββββββββββ ββββββββββ¬βββββββββ
β
βββββββββββββββββββ΄ββββββββββββββββββ
β β
βββββββββ΄ββββββββ βββββββββ΄ββββββββ
β PostgreSQL β β Filesystem β
β (pointcab_db)β β (uploads/) β
ββββββββββββββββββ ββββββββββββββββββ
```
## π Verzeichnisstruktur
```
/var/www/pointcab_webexport_server/
βββ nodejs_space/ # Haupt-Anwendung
β βββ src/
β β βββ controllers/ # HTTP-Endpunkte
β β β βββ admin.controller.ts
β β β βββ projects.controller.ts
β β β βββ root.controller.ts
β β βββ services/ # Business-Logik
β β βββ admin.service.ts
β β βββ projects.service.ts
β β βββ upload.service.ts
β β βββ prisma.service.ts
β βββ prisma/
β β βββ schema.prisma # Datenbank-Schema
β βββ dist/ # Kompilierter Code
β βββ uploads/ # Hochgeladene Projekte
β βββ package.json
β βββ tsconfig.json
β βββ .env # Konfiguration
βββ backups/ # Deployment-Backups
```
## π οΈ Komponenten
### 1. Controllers
#### ProjectsController (`projects.controller.ts`)
Verantwortlich fΓΌr:
- Projekt-Anzeige (`GET /:shareId/view`)
- Passwort-Authentifizierung (`POST /:shareId/auth`)
- Asset-Serving (`GET /:shareId/*`)
**Wichtige Funktionen:**
```typescript
// Projekt anzeigen
@Get(':shareId/view')
async viewProject()
// Assets laden (JS, CSS, Bilder)
@Get(':shareId/*')
async getProjectResource()
// Passwort-Seite
@Get(':shareId')
async showPasswordPage()
```
#### AdminController (`admin.controller.ts`)
Verantwortlich fΓΌr:
- Dashboard (`GET /admin/dashboard`)
- Projekt-Verwaltung (CRUD)
- RAR-Entpacken
- Datei-Upload
### 2. Services
#### ProjectsService (`projects.service.ts`)
**Kernfunktionen:**
1. **Web-Subfolder-Erkennung:**
```typescript
detectWebSubfolder(projectPath: string): string | null
// Erkennt z.B. "Web_0_web/" Ordner
```
2. **Asset-Pfad-AuflΓΆsung:**
```typescript
resolveAssetPath(projectPath: string, assetPath: string): string
// LΓΆst relative Pfade auf
```
3. **Base-Tag-Injection:**
```typescript
injectBaseTag(html: string, shareId: string, htmlPath?: string): string
// FΓΌgt fΓΌr korrekte Asset-Pfade ein
```
#### AdminService (`admin.service.ts`)
**Kernfunktionen:**
1. **RAR-Entpacken:**
```typescript
extractRar(projectId: string, rarPath: string): Promise
// Verwendet spawn() fΓΌr groΓe Dateien
```
2. **HTML-Erkennung:**
```typescript
findHtmlFiles(projectPath: string): string[]
// Findet alle HTML-Dateien im Projekt
```
3. **Multi-HTML-Logik:**
```typescript
processExtractedProject(projectId: string): Promise
// Setzt htmlfilename = null bei mehreren HTMLs
```
#### UploadService (`upload.service.ts`)
**Kernfunktionen:**
- ZIP/RAR-Upload verarbeiten
- Projekt in Datenbank erstellen
- Multi-HTML-Erkennung
### 3. Datenbank-Schema
```prisma
model project {
id String @id @default(uuid())
name String @unique
shareid String @unique
password String // Klartext (kein Hash!)
htmlfilename String? // NULL bei Multi-HTML
uploaddate DateTime @default(now())
expirydate DateTime?
createdat DateTime @default(now())
}
```
**Wichtig:** `htmlfilename` ist **nullable** fΓΌr Multi-HTML-UnterstΓΌtzung!
## π Request-Flow
### Projekt anzeigen
```
1. Browser: GET /abc123/view
β
2. Nginx Proxy: Weiterleitung an :3000
β
3. ProjectsController.viewProject()
β
ββ Projekt aus DB laden
ββ Passwort-Check (Cookie)
ββ htmlfilename prΓΌfen
β ββ null β HTML-Auswahl-Seite
β ββ vorhanden β HTML laden
ββ Web-Subfolder erkennen
ββ Base-Tag injecten
ββ HTML zurΓΌckgeben
β
4. Browser: Rendert HTML
β
5. Browser: LΓ€dt Assets (GET /abc123/js/main.js)
β
6. ProjectsController.getProjectResource()
ββ Pfad auflΓΆsen (mit Subfolder)
ββ Datei zurΓΌckgeben
```
### RAR entpacken
```
1. Admin: POST /admin/projects/:id/extract-rar
β
2. AdminController.extractRar()
β
3. AdminService.extractRar()
ββ Platzhalter-HTML lΓΆschen
ββ RAR entpacken (spawn)
ββ HTML-Dateien finden
ββ Web-Subfolder erkennen
ββ htmlfilename setzen
β ββ 1 HTML β Dateiname
β ββ >1 HTML β null
ββ DB aktualisieren
```
## π Sicherheit
### Passwort-Handling
- PasswΓΆrter werden als **Klartext** gespeichert
- Kein bcrypt-Hashing (bewusste Entscheidung fΓΌr einfache Verwaltung)
- Cookie-basierte Session nach erfolgreicher Authentifizierung
### Pfad-Sicherheit
```typescript
// Pfad-Normalisierung verhindert Directory Traversal
const safePath = path.normalize(requestedPath).replace(/^(\.\.\/)+/, '');
```
### Datei-Zugriff
- Nur Dateien innerhalb des Projekt-Verzeichnisses
- Keine direkten Pfade vom Client
- MIME-Type-Validierung
## π Technologie-Stack
| Schicht | Technologie | Version |
|---------|-------------|--------|
| Runtime | Node.js | 18.x LTS |
| Framework | NestJS | 10.x |
| Sprache | TypeScript | 5.x |
| Datenbank | PostgreSQL | 16.x |
| ORM | Prisma | 5.x |
| Process Manager | PM2 | 5.x |
| Reverse Proxy | Nginx Proxy Manager | Latest |
| OS | Ubuntu | 24.04 LTS |
## π§ Konfiguration
### Umgebungsvariablen (.env)
```env
PORT=3000 # Server-Port
NODE_ENV=production # Umgebung
DATABASE_URL="postgresql://..." # DB-Verbindung
UPLOAD_DIR=/path/to/uploads # Upload-Verzeichnis
SESSION_SECRET=... # Session-VerschlΓΌsselung
ADMIN_PASSWORD=... # Admin-Zugang
```
### PM2 Konfiguration
```javascript
// ecosystem.config.js
module.exports = {
apps: [{
name: 'pointcab-server',
script: './dist/main.js',
instances: 1,
autorestart: true,
max_memory_restart: '1G'
}]
};
```
## π Performance
### Optimierungen
1. **Spawn statt Exec:** FΓΌr RAR-Entpacken (kein Buffer-Limit)
2. **Lazy Loading:** Assets werden on-demand geladen
3. **PM2 Clustering:** MΓΆglich fΓΌr Skalierung
### Limits
- Max Upload: 500 MB (konfigurierbar)
- Max Projekte: Unbegrenzt (Speicherplatz-abhΓ€ngig)
- Gleichzeitige Verbindungen: Node.js Standard
---
**Siehe auch:** [CHANGELOG.md](CHANGELOG.md)