Initial commit: Beisel Rallye Graz Project with full documentation
This commit is contained in:
+174
@@ -0,0 +1,174 @@
|
||||
# API-Design: Beisel Rallye 🍺
|
||||
|
||||
## Übersicht
|
||||
|
||||
Die API ermöglicht server-seitige Speicherung aller Rallye-Einträge und unterstützt echte Multi-User-Funktionalität über verschiedene Geräte hinweg.
|
||||
|
||||
## Endpunkte
|
||||
|
||||
### 1. Bezirk besuchen (POST /api/visit)
|
||||
|
||||
**Zweck:** Neuen Besuch eines Bezirks speichern
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"user_name": "Gregor",
|
||||
"district": "I. Innere Stadt",
|
||||
"beisel_name": "Schloßhotel Greising"
|
||||
}
|
||||
```
|
||||
|
||||
**Response (201 Created):**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Bezirk gespeichert!",
|
||||
"data": {
|
||||
"id": 6,
|
||||
"user_name": "Gregor",
|
||||
"district": "I. Innere Stadt",
|
||||
"beisel_name": "Schloßhotel Greising",
|
||||
"timestamp": "2026-06-29T10:30:00.000Z"
|
||||
},
|
||||
"progress": {
|
||||
"visited_count": 8,
|
||||
"total_districts": 17,
|
||||
"percentage": 47
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Fehler (400 Bad Request):**
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": "Ungültige Eingabe",
|
||||
"details": {
|
||||
"user_name": "Pflichtfeld",
|
||||
"district": "Ungültiger Bezirk"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Fortschritt abrufen (GET /api/status/:username)
|
||||
|
||||
**Zweck:** Aktuelle Rallye-Statistik für einen Benutzer laden
|
||||
|
||||
**Response (200 OK):**
|
||||
```json
|
||||
{
|
||||
"user_name": "Gregor",
|
||||
"progress": {
|
||||
"visited_count": 8,
|
||||
"total_districts": 17,
|
||||
"percentage": 47
|
||||
},
|
||||
"visits": [
|
||||
{
|
||||
"district": "I. Innere Stadt",
|
||||
"beisel_name": "Schloßhotel Greising",
|
||||
"timestamp": "2026-06-29T10:30:00.000Z"
|
||||
},
|
||||
{
|
||||
"district": "II. St. Leonhard",
|
||||
"beisel_name": "Jazzkeller",
|
||||
"timestamp": "2026-06-29T11:15:00.000Z"
|
||||
}
|
||||
],
|
||||
"last_updated": "2026-06-29T11:15:00.000Z"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Alle Teilnehmer anzeigen (GET /api/all-users)
|
||||
|
||||
**Zweck:** Leaderboard mit allen aktiven Teilnehmern
|
||||
|
||||
**Response (200 OK):**
|
||||
```json
|
||||
{
|
||||
"users": [
|
||||
{
|
||||
"user_name": "Gregor",
|
||||
"visited_count": 8,
|
||||
"last_active": "2026-06-29T11:15:00.000Z"
|
||||
},
|
||||
{
|
||||
"user_name": "Maria",
|
||||
"visited_count": 12,
|
||||
"last_active": "2026-06-29T10:45:00.000Z"
|
||||
}
|
||||
],
|
||||
"total_users": 2,
|
||||
"generated_at": "2026-06-29T12:00:00.000Z"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Reset für User (DELETE /api/reset/:username)
|
||||
|
||||
**Zweck:** Alle Einträge eines Users löschen
|
||||
|
||||
**Response (200 OK):**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Alle Einträge für 'Gregor' gelöscht",
|
||||
"deleted_count": 5
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Fehlerbehandlung
|
||||
|
||||
### Allgemeine Fehler (4xx/5xx)
|
||||
```json
|
||||
{
|
||||
"error_code": "INTERNAL_ERROR",
|
||||
"message": "Unerwarteter Serverfehler",
|
||||
"timestamp": "2026-06-29T12:00:00.000Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Validierungsfehler (400)
|
||||
```json
|
||||
{
|
||||
"error_code": "VALIDATION_ERROR",
|
||||
"message": "Ungültige Eingabe",
|
||||
"details": {
|
||||
"field_name": ["Fehlermeldung"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Implementierungs-Hinweise
|
||||
|
||||
### Datenbank-Operationen
|
||||
- Verwende `sqlite3` Package für asynchrone Operationen
|
||||
- Parameterisierte Queries gegen SQL Injection schützen
|
||||
- Connection Pooling für bessere Performance
|
||||
|
||||
### Rate Limiting
|
||||
- Max. 10 Anfragen pro Minute pro IP
|
||||
- Besonders bei POST /api/visit wichtig
|
||||
|
||||
### Sicherheit
|
||||
- Input Validation auf allen Endpunkten
|
||||
- User-Namen sanitieren (keine Script-Injection)
|
||||
- CORS Headers setzen falls nötig
|
||||
|
||||
### Performance
|
||||
- SQLite ist ausreichend für diese Anwendung
|
||||
- Keine komplexen Joins notwendig
|
||||
- Periodische Datenbank-Vacuum Operationen empfohlen
|
||||
|
||||
---
|
||||
*Stand: 2026-06-29 | Version: 1.0*
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
# Architektur-Dokumentation: Beisel Rallye 🍺
|
||||
|
||||
## Systemübersicht
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
|
||||
│ Browser │──────→│ Express Server │──────→│ SQLite DB │
|
||||
│ (Client) │ │ (:8083) │ │ │
|
||||
└─────────────────┘ └──────────────────┘ └─────────────────┘
|
||||
↕ ↕
|
||||
Nginx Reverse Proxy beisel_rally.db
|
||||
(aufeins.click.jetzt) :8083
|
||||
```
|
||||
|
||||
## Komponenten
|
||||
|
||||
### 1. Frontend (Browser)
|
||||
- **Technologie:** Vanilla JavaScript + EJS Templates
|
||||
- **Responsibility:** UI-Rendering, User-Interaktion, Client-Side Validation
|
||||
- **Speicherung:** Aktuelle Implementierung nutzt localStorage (→ wird durch Server API ersetzt)
|
||||
|
||||
### 2. Backend (Express.js)
|
||||
- **Port:** 8083
|
||||
- **Routing:** Express Router
|
||||
- **Datenbank:** SQLite via `sqlite3` Package
|
||||
- **Middleware:** body-parser, CORS (geplant)
|
||||
|
||||
### 3. Datenbank (SQLite)
|
||||
- **Datei:** `beisel_rally.db`
|
||||
- **Schema:** Einfache Tabelle `rally_logs`
|
||||
- **Skalierung:** Ausreichend für erwartete User-Anzahl (<1000)
|
||||
|
||||
## Datenfluss
|
||||
|
||||
### Aktuelle Implementierung (localStorage-basiert):
|
||||
```
|
||||
User → Browser UI → localStorage → (keine Server-Kommunikation)
|
||||
```
|
||||
|
||||
### Ziel-Implementierung (Server-seitig):
|
||||
```
|
||||
User → Browser UI → API Request → Express Server → SQLite DB
|
||||
↑ |
|
||||
└─────────────── API Response ←────────────────┘
|
||||
```
|
||||
|
||||
## Datenbank-Schema
|
||||
|
||||
```sql
|
||||
CREATE TABLE rally_logs (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_name TEXT NOT NULL,
|
||||
district TEXT NOT NULL,
|
||||
beisel_name TEXT NOT NULL,
|
||||
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Index für häufige Queries
|
||||
CREATE INDEX idx_user_district ON rally_logs(user_name, district);
|
||||
```
|
||||
|
||||
## Deployment-Architektur
|
||||
|
||||
### Nginx Reverse Proxy
|
||||
- **Funktion:** SSL-Terminierung, Load Balancing (geplant)
|
||||
- **Domain:** aufeins.click.jetzt
|
||||
- **Backend:** 192.168.0.187:8083
|
||||
- **SSL:** Let's Encrypt automatisch
|
||||
|
||||
### Server-Setup
|
||||
```bash
|
||||
# Abhängigkeiten installieren
|
||||
cd /home/claw/.openclaw/agents/wisp/workspace/beisel-rally
|
||||
npm install
|
||||
|
||||
# Server starten
|
||||
node index.js
|
||||
|
||||
# Im Hintergrund laufen lassen (optional)
|
||||
nohup node index.js > server.log 2>&1 &
|
||||
```
|
||||
|
||||
## Skalierungsbetrachtung
|
||||
|
||||
### Aktuelle Kapazitäten
|
||||
- **SQLite:** Bis ~1M Einträge performant
|
||||
- **Express:** Bis ~100 req/s ohne Optimierung
|
||||
- **Nginx:** Hoch skalierbar
|
||||
|
||||
### Erweiterungsmöglichkeiten
|
||||
1. **PostgreSQL Migration** bei >10k Usern
|
||||
2. **Redis Caching** für statische Daten (Bezirke, Beiseln)
|
||||
3. **Load Balancing** mit mehreren Express Instanzen
|
||||
4. **WebSocket** für Echtzeit-Updates
|
||||
|
||||
## Sicherheitshinweise
|
||||
|
||||
### Aktuelle Schwachstellen
|
||||
- ❌ Keine Input Validation auf Server-Side
|
||||
- ❌ Keine Rate Limiting
|
||||
- ❌ SQL Injection möglich (bei korrekter Implementierung)
|
||||
- ❌ CORS nicht konfiguriert
|
||||
|
||||
### Verbesserungen
|
||||
- ✅ Parameterisierte Queries verwenden
|
||||
- ✅ Rate Limiting implementieren
|
||||
- ✅ CORS Headers setzen
|
||||
- ✅ Input Sanitization hinzufügen
|
||||
- ✅ HTTPS erzwingen (bereits durch Nginx gegeben)
|
||||
|
||||
---
|
||||
*Stand: 2026-06-29 | Version: 1.0*
|
||||
@@ -0,0 +1,183 @@
|
||||
# Entwicklungshandbuch: Beisel Rallye 🍺
|
||||
|
||||
## Schnellstart
|
||||
|
||||
### Voraussetzungen
|
||||
- Node.js v18+
|
||||
- npm oder yarn
|
||||
- SQLite3 (wird via npm installiert)
|
||||
|
||||
### Setup
|
||||
```bash
|
||||
# In das Projektverzeichnis wechseln
|
||||
cd /home/claw/.openclaw/agents/wisp/workspace/beisel-rally
|
||||
|
||||
# Abhängigkeiten installieren
|
||||
npm install
|
||||
|
||||
# Server starten
|
||||
node index.js
|
||||
|
||||
# Server läuft auf http://localhost:8083
|
||||
```
|
||||
|
||||
## Code-Struktur
|
||||
|
||||
### Wichtige Dateien
|
||||
- `index.js` - Hauptserver mit Express App
|
||||
- `views/index.ejs` - Frontend Template
|
||||
- `public/css/style.css` - Styling
|
||||
- `beisel_rally.db` - SQLite Datenbank
|
||||
- `package.json` - Dependencies und Scripts
|
||||
|
||||
### Entwicklungs-Wiederholungszyklus
|
||||
1. Code ändern
|
||||
2. Server neu starten (`Ctrl+C`, dann `node index.js`)
|
||||
3. Im Browser testen (Cache leeren!)
|
||||
4. Git commit (wenn fertig)
|
||||
|
||||
## Wichtige Konzepte
|
||||
|
||||
### Express Middleware
|
||||
```javascript
|
||||
// Body Parser für JSON Requests
|
||||
app.use(express.json());
|
||||
|
||||
// Statische Dateien servieren
|
||||
app.use(express.static('public'));
|
||||
|
||||
// Custom Middleware (z.B. Logging)
|
||||
app.use((req, res, next) => {
|
||||
console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`);
|
||||
next();
|
||||
});
|
||||
```
|
||||
|
||||
### SQLite Operationen
|
||||
```javascript
|
||||
const sqlite3 = require('sqlite3').verbose();
|
||||
const db = new sqlite3.Database('./beisel_rally.db');
|
||||
|
||||
// Query ausführen
|
||||
db.run("INSERT INTO rally_logs (user_name, district) VALUES (?, ?)",
|
||||
["Gregor", "I. Innere Stadt"], function(err) {
|
||||
if (err) {
|
||||
console.error('Insert fehlgeschlagen:', err);
|
||||
return;
|
||||
}
|
||||
console.log('Erfolgreich eingefügt, ID:', this.lastID);
|
||||
});
|
||||
|
||||
// Daten abrufen
|
||||
db.all("SELECT * FROM rally_logs WHERE user_name = ?", ["Gregor"], (err, rows) => {
|
||||
if (err) {
|
||||
console.error('Query fehlgeschlagen:', err);
|
||||
return;
|
||||
}
|
||||
console.log(rows);
|
||||
});
|
||||
```
|
||||
|
||||
### Fehlerbehandlung
|
||||
```javascript
|
||||
// Try-Catch für async Operationen
|
||||
try {
|
||||
const result = await someAsyncOperation();
|
||||
res.json({ success: true, data: result });
|
||||
} catch (error) {
|
||||
console.error('Fehler:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Interner Serverfehler'
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
### Manuelles Testen
|
||||
1. Server starten
|
||||
2. Browser öffnen: `http://localhost:8083`
|
||||
3. API Endpunkte testen mit curl oder Postman:
|
||||
```bash
|
||||
# New Visit testen
|
||||
curl -X POST http://localhost:8083/api/visit \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"user_name":"Gregor","district":"I. Innere Stadt","beisel_name":"Test"}'
|
||||
|
||||
# Status abrufen
|
||||
curl http://localhost:8083/api/status/Gregor
|
||||
```
|
||||
|
||||
### Datenbank-Checks
|
||||
```bash
|
||||
# SQLite CLI starten
|
||||
sqlite3 beisel_rally.db
|
||||
|
||||
# Alle Einträge anzeigen
|
||||
SELECT * FROM rally_logs;
|
||||
|
||||
# Statistik pro User
|
||||
SELECT user_name, COUNT(*) as visits FROM rally_logs GROUP BY user_name;
|
||||
```
|
||||
|
||||
## Debugging
|
||||
|
||||
### Häufige Probleme
|
||||
|
||||
**Server startet nicht:**
|
||||
- Port 8083 ist belegt? → `lsof -i :8083` und Prozess killen
|
||||
- Node.js Version zu alt? → `node --version` (braucht v18+)
|
||||
|
||||
**Datenbank Fehler:**
|
||||
- Datei nicht gefunden? → Prüfen ob `beisel_rally.db` existiert
|
||||
- Permission denied? → `chmod 664 beisel_rally.db` und Gruppe prüfen
|
||||
|
||||
**Frontend lädt nicht:**
|
||||
- Cache geleert? → Hard Reload (Ctrl+Shift+R)
|
||||
- CORS Fehler? → Server Logs checken
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Code-Qualität
|
||||
- **ESLint** für JavaScript Linting
|
||||
- **Prettier** für konsistentes Formatting
|
||||
- **Git Commits** mit klaren Nachrichten
|
||||
- **Comments** erklären das "Warum", nicht das "Was"
|
||||
|
||||
### Sicherheit
|
||||
- **Input Validation** auf allen Endpunkten
|
||||
- **Parameterisierte Queries** gegen SQL Injection
|
||||
- **Rate Limiting** für API Endpunkte
|
||||
- **HTTPS** erzwingen (bereits durch Nginx gegeben)
|
||||
|
||||
### Performance
|
||||
- **Datenbank-Verbindungen** schließen wenn nicht benötigt
|
||||
- **Caching** für statische Daten (Bezirke, Beiseln)
|
||||
- **Pagination** bei großen Datensätzen
|
||||
- **Lazy Loading** für komplexe Views
|
||||
|
||||
## Deployment Checklist
|
||||
|
||||
Vor dem Deployen prüfen:
|
||||
- [ ] Alle Tests bestanden
|
||||
- [ ] Datenbank-Schema aktuell
|
||||
- [ ] Environment-Variablen gesetzt (falls nötig)
|
||||
- [ ] Logging konfiguriert
|
||||
- [ ] Backup-Mechanismus vorhanden
|
||||
- [ ] Monitoring/Alerting eingerichtet
|
||||
|
||||
## Ressourcen
|
||||
|
||||
### Offizielle Dokumentation
|
||||
- [Express.js](https://expressjs.com/)
|
||||
- [SQLite3 Node.js](https://github.com/TryGhost/node-sqlite3)
|
||||
- [Nginx Documentation](https://nginx.org/en/docs/)
|
||||
|
||||
### Lokale Hilfe
|
||||
- `PROJECT.md` - Projektübersicht
|
||||
- `API_DESIGN.md` - API Spezifikation
|
||||
- `ARCHITECTURE.md` - System-Architektur
|
||||
|
||||
---
|
||||
*Stand: 2026-06-29 | Version: 1.0*
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
# Beisel Rallye Graz 🍺
|
||||
|
||||
## Projektübersicht
|
||||
|
||||
Interaktive Website für eine Bier-Rallye durch 17 Grazer Bezirke. Teilnehmende tragen bei jedem besuchten Bezirk das entsprechende Beisel (Bierlokal) ein und verfolgen ihren Fortschritt.
|
||||
|
||||
### Konzept
|
||||
- **Ziel:** Alle 17 Grazer Bezirke besuchen
|
||||
- **Aktivität:** Für jeden Bezirk ein lokales Beisel finden und eintragen
|
||||
- **Zeitrahmen:** 24 Stunden Rallye
|
||||
- **Multi-User:** Mehrere Teilnehmer können parallel teilnehmen
|
||||
|
||||
## Technologie-Stack
|
||||
|
||||
- **Backend:** Express.js (Node.js)
|
||||
- **Frontend:** EJS Templates + Vanilla JavaScript
|
||||
- **Datenbank:** SQLite (beisel_rally.db)
|
||||
- **Styling:** Custom CSS mit Wirtshaus-Theme
|
||||
- **Deployment:** Nginx Reverse Proxy auf `aufeins.click.jetzt`
|
||||
|
||||
## Architektur
|
||||
|
||||
```
|
||||
beisel-rally/
|
||||
├── index.js # Express Server (Port 8083)
|
||||
├── package.json # Dependencies & Scripts
|
||||
├── beisel_rally.db # SQLite Datenbank
|
||||
├── server.log # Laufzeit-Logs
|
||||
├── PROJECT.md # Diese Dokumentation
|
||||
├── public/
|
||||
│ └── css/
|
||||
│ └── style.css # Responsive Styling
|
||||
└── views/
|
||||
└── index.ejs # Haupttemplate mit Client-Side Logic
|
||||
```
|
||||
|
||||
## Datenbank-Design
|
||||
|
||||
### Tabelle: `rally_logs`
|
||||
```sql
|
||||
CREATE TABLE rally_logs (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_name TEXT NOT NULL,
|
||||
district TEXT NOT NULL,
|
||||
beisel_name TEXT NOT NULL,
|
||||
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
```
|
||||
|
||||
**Zweck:** Server-seitige Speicherung aller Rallye-Einträge für persistente Multi-User-Fähigkeit.
|
||||
|
||||
## API-Endpunkte (geplant)
|
||||
|
||||
### Aktuelle Situation
|
||||
Derzeit wird **nur localStorage** im Browser genutzt. Die SQLite-Datenbank ist vorhanden, wird aber nicht integriert.
|
||||
|
||||
### Zu implementierende Endpunkte:
|
||||
- `POST /api/visit` - Neuen Bezirk besuchen
|
||||
- `GET /api/status/:username` - Fortschritt abrufen
|
||||
- `GET /api/all-users` - Alle Teilnehmer anzeigen
|
||||
- `DELETE /api/reset/:username` - Reset für User
|
||||
|
||||
## Deployment
|
||||
|
||||
### Nginx Konfiguration
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name aufeins.click.jetzt;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/aufeins.click.jetzt/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/aufeins.click.jetzt/privkey.pem;
|
||||
|
||||
location / {
|
||||
proxy_pass http://192.168.0.187:8083;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Server Starten
|
||||
```bash
|
||||
cd /home/claw/.openclaw/agents/wisp/workspace/beisel-rally
|
||||
node index.js
|
||||
# Server läuft auf http://localhost:8083
|
||||
```
|
||||
|
||||
## Entwicklungs-Status
|
||||
|
||||
### ✅ Abgeschlossen
|
||||
- Grundlegende Frontend-Struktur
|
||||
- Responsive Design mit Mobile-Support
|
||||
- User-Auswahl und -Verwaltung (localStorage)
|
||||
- Fortschrittsanzeige
|
||||
- Wirtshaus-Theme Implementierung
|
||||
|
||||
### ❌ Offene Punkte
|
||||
1. **SQLite-Integration** - API-Endpunkte für Datenbank-Zugriff
|
||||
2. **Server-Datenpersistenz** - localStorage → Server-Side Storage
|
||||
3. **Deployment** - Backend-Server auf 192.168.0.187:8083 starten
|
||||
4. **Sicherheit** - Input Validation, Rate Limiting
|
||||
5. **Export/Import** - Backup-Funktionalität
|
||||
|
||||
## Nächste Schritte
|
||||
|
||||
### Kurzfristig (Prio 1)
|
||||
- [ ] API-Endpunkte für SQLite-Datenbank implementieren
|
||||
- [ ] Client-Seite anpassen um API zu nutzen
|
||||
- [ ] Server starten und testen
|
||||
|
||||
### Mittelfristig (Prio 2)
|
||||
- [ ] Authentifizierung hinzufügen
|
||||
- [ ] Leaderboard implementieren
|
||||
- [ ] Export/Import Funktionalität
|
||||
|
||||
### Langfristig (Prio 3)
|
||||
- [ ] Mobile App (Progressive Web App)
|
||||
- [ ] Social Features (Teilen, Einladungen)
|
||||
- [ ] Anbindung an bestehende Beisel-Datenbank
|
||||
|
||||
## Kontakt & Credits
|
||||
|
||||
Projekt erstellt von Gregor. Entwicklung durch Wisp (AI Coding Agent).
|
||||
|
||||
**Domain:** aufeins.click.jetzt
|
||||
**Server:** 192.168.0.187:8083
|
||||
**Gitea:** http://gitea.click.jetzt:3000/clawdia/beisel-rally
|
||||
|
||||
---
|
||||
*Prost! 🍻*
|
||||
Binary file not shown.
@@ -0,0 +1,26 @@
|
||||
const express = require('express');
|
||||
const path = require('path');
|
||||
|
||||
const app = express();
|
||||
const port = 8083;
|
||||
|
||||
// Kein Caching für HTML
|
||||
app.use((req, res, next) => {
|
||||
res.set('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
|
||||
res.set('Pragma', 'no-cache');
|
||||
res.set('Expires', '0');
|
||||
res.set('Surrogate-Control', 'no-store');
|
||||
next();
|
||||
});
|
||||
|
||||
app.use(express.static(path.join(__dirname, 'public')));
|
||||
app.set('view engine', 'ejs');
|
||||
app.set('views', path.join(__dirname, 'views'));
|
||||
|
||||
app.get('/', (req, res) => {
|
||||
res.render('index');
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Beisel-Rallye läuft auf http://localhost:${port}`);
|
||||
});
|
||||
Generated
+1548
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "beisel-rally",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"body-parser": "^2.2.2",
|
||||
"ejs": "^6.0.1",
|
||||
"express": "^5.2.1",
|
||||
"sqlite3": "^6.0.1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Beisel-Rallye läuft auf http://localhost:8083
|
||||
Reference in New Issue
Block a user