Systemarchitektur¶
Tech-Stack¶
| Komponente | Technologie | Version |
|---|---|---|
| Framework | Next.js | 16.1.1 |
| Frontend | React | 19.2.3 |
| Sprache | TypeScript | 5 |
| Datenbank | pg (PostgreSQL) | 8.17.2 |
| Auth | bcryptjs + jsonwebtoken | 2.4.3 / 9.0.2 |
| Blockchain | ethers.js | 6.16.0 |
| Styling | Inline CSS (kein Tailwind) | - |
Verzeichnisstruktur¶
admin/
├── proxy.ts # Middleware: Whitelist + JWT-Auth
├── package.json # Dependencies
├── tsconfig.json # TypeScript strict mode
├── next.config.ts # Next.js Config (leer)
├── .env → ../.env # Symlink zum Haupt-.env
│
├── app/
│ ├── layout.tsx # Root-Layout (Dark Theme)
│ ├── login/page.tsx # Login-Seite
│ │
│ ├── lib/ # Utilities
│ │ ├── auth.ts # JWT + bcrypt Auth
│ │ ├── db.ts # Main DB Pool (max: 5)
│ │ ├── charityDb.ts # Charity DB Pool (max: 3)
│ │ └── colors.ts # Design-Tokens
│ │
│ ├── components/ # Wiederverwendbare UI
│ │ ├── AdminShell.tsx # Layout-Wrapper + Sidebar
│ │ ├── Sidebar.tsx # Navigation (15 Einträge)
│ │ ├── DataTable.tsx # Paginierte Tabelle
│ │ ├── StatCard.tsx # Metrik-Karte
│ │ └── StatusBadge.tsx # Status-Badge
│ │
│ ├── dashboard/page.tsx # Dashboard
│ ├── users/
│ │ ├── page.tsx # User-Liste
│ │ └── [wallet]/page.tsx # User-Detail
│ ├── settlements/page.tsx # Settlements
│ ├── intents/page.tsx # Kaufabsichten
│ ├── vouchers/page.tsx # Gutscheine
│ ├── affiliates/page.tsx # Affiliates
│ ├── winners/page.tsx # Gewinner
│ ├── charity/page.tsx # Charity Voting
│ ├── config/page.tsx # Konfiguration
│ ├── contracts/page.tsx # Contract-Salden
│ ├── errors/page.tsx # Fehler
│ ├── workers/page.tsx # Worker-Status
│ ├── seeds/page.tsx # Seed-Monitor
│ ├── watchdog/page.tsx # Watchdog
│ └── testplayers/page.tsx # Test-Spieler
│ │
│ └── api/ # 25 API-Routen
│ ├── auth/login/route.ts
│ ├── auth/logout/route.ts
│ ├── dashboard/stats/route.ts
│ ├── users/route.ts
│ ├── users/[wallet]/route.ts
│ ├── settlements/route.ts
│ ├── intents/route.ts
│ ├── vouchers/route.ts
│ ├── vouchers/stats/route.ts
│ ├── affiliates/route.ts
│ ├── winners/route.ts
│ ├── charity/rounds/route.ts
│ ├── charity/rounds/[id]/route.ts
│ ├── charity/projects/route.ts
│ ├── config/route.ts
│ ├── contracts/route.ts
│ ├── errors/route.ts
│ ├── workers/route.ts
│ ├── seeds/route.ts
│ ├── watchdog/route.ts
│ ├── testplayers/route.ts
│ └── maintenance/route.ts
Architekturprinzipien¶
1. Client-Side Rendering (CSR)¶
Alle Seiten sind Client-Komponenten ("use client"). Daten werden via useEffect + fetch() geladen:
"use client";
const [data, setData] = useState(null);
useEffect(() => {
fetch("/api/endpoint")
.then(r => r.json())
.then(setData);
}, []);
2. Direkte DB-Zugriffe¶
Kein ORM - direkte SQL-Queries via pg-Pool:
3. Whitelist-basierte Security¶
Nur explizit erlaubte Routen passieren die Middleware (siehe Authentifizierung).
4. Inline-Styling¶
Kein Tailwind/CSS-Framework - zentralisierte Farbkonstanten in colors.ts:
export const colors = {
bg: "#0a0e12",
bgCard: "#1a2332",
accent: "#3b82f6",
success: "#22c55e",
text: "#e2e8f0",
// ...
} as const;
Datenbank-Verbindungen¶
Main Database (chainbets)¶
// app/lib/db.ts
export const db = new Pool({
host: process.env.DB_HOST ?? "127.0.0.1",
port: Number(process.env.DB_PORT ?? 5432),
database: process.env.DB_NAME ?? "chainbets",
user: process.env.DB_USER ?? "chainbets",
password: process.env.DB_PASSWORD ?? "chainbets_dev_pw",
max: 5
});
Charity Database (chainbets_charity)¶
// app/lib/charityDb.ts
export const charityDb = new Pool({
database: "chainbets_charity", // Separate Datenbank
max: 3
});
Abhängigkeiten¶
{
"dependencies": {
"next": "16.1.1",
"react": "^19.2.3",
"pg": "^8.17.2",
"bcryptjs": "^2.4.3",
"jsonwebtoken": "^9.0.2",
"ethers": "^6.16.0"
}
}
Bewusst minimale Dependencies - kein ORM, kein CSS-Framework, kein State-Management.