8.4 KiB
Kimi-Kontext: Hocks Mieterportal (mieterportal.hocks.eu)
Projekt-Kontextdatei für Kimi Work. Stand: 02.10.2026, 11:00 Uhr. Bitte bei größeren Änderungen am Projekt aktualisieren. Konventionen und Workflow sind am Projekt Schulportal (sfg.hocks.eu) orientiert.
1. Projektüberblick
Mieterportal der Hocks Verwaltung für 50 Wohnungen in 3 Häusern (Hauptstraße 12 · Ringweg 3 · Am Park 5). Analog zum Schulportal: alle Mietangelegenheiten digital an einem Ort. Rollenmodus statt echter Anmeldung (Demo): Umschalten Mieter ↔ Verwaltung über die Seitenleiste (Schaltfläche „Als Verwaltung anzeigen").
Die 5 Module:
- Dashboard (
/) – Mieter: Begrüßung, nächste Zahlung, Mietdiagramm, Ankündigungen, offene Meldungen. Verwaltung: Kennzahlen (Vermietungsquote, Miet-Soll, Rückstände), Einnahmenverlauf + Belegung pro Haus (Recharts). - Mietkonto & Zahlungen (
/mietkonto) – Buchungsverlauf 2026 mit Statusfilter, Nebenkostenguthaben, Zahlungsdaten. Verwaltung: Zahlungsstatus aller Wohnungen, Rückstandsliste, Haus-Filter. - Schadensmeldungen (
/schadensmeldungen) – Tickets mit Kategorie, Dringlichkeit, Status; Neuanlage per Dialog; Verwaltung pflegt Status per Select. - Dokumente (
/dokumente) – Verträge/Abrechnungen/Hausordnung/Protokolle, Suche + Kategorie-Chips. Mieter sieht eigene + Hausdokumente (unitId=null). - Nachrichten (
/nachrichten) – Chat Mieter ↔ Verwaltung, Ungelesen-Markierung, neue Unterhaltungen.
Login-Seite (/login): Hero mit generiertem Foto, Feature-Liste, Demo-Einstiege
(„Als Mieterin anmelden" / „Als Verwaltung anmelden"). Kein echtes Auth – der
Rollenwechsel setzt nur den Store.
2. Technischer Stack
| Teil | Technologie |
|---|---|
| Frontend | React 18 + TypeScript, Vite 7, Tailwind v3.4 + shadcn/ui (Radix), React Router 7 (BrowserRouter), Recharts |
| State | React Context + useReducer, Persistenz in localStorage (hocks-mieterportal-v1) |
| Daten | src/data/seed.ts (handschriftlich) + src/data/generated.json (maschinell via beispieldaten.py) |
| Branding | KI-generiert: src/assets/logo.png (Haus-Schlüssel-Emblem, transparent), hero.jpg, modules.jpg |
| Webserver (Ziel) | Docker-Container mp-portal (nginx), statisches dist/, gemountet /opt/mieterportal/dist |
| Mail (optional) | mail-server/: Postfix-Relay (mp-mail) + Python-API (mp-mail-api), Muster aus Schulportal |
| Server | Root-VPS hocks.eu (IONOS), Docker + Portainer, Subdomain via NPM (Nginx Proxy Manager, Let's Encrypt) |
3. Wichtige Dateien
Projektverzeichnis: C:\Users\ah\Documents\Kimi\Workspaces\Mieterportal
Git: https://git.hocks.eu/ah-admin/Mieterportal (Branch main). Secrets
ausgesperrt via .gitignore (mail-server/mail.env etc.).
| Datei | Inhalt |
|---|---|
src/store/store.tsx |
Store-Provider, Reducer, Actions (setRole/addTicket/setTicketStatus/addMessage/newThread/markThreadRead), fmtEUR |
src/data/seed.ts |
Tickets, Dokumente, Nachrichten-Threads, Ankündigungen + Re-Export units/transactions aus generated.json |
src/data/generated.json |
50 Wohnungen + 552 Buchungen, erzeugt von beispieldaten.py (Seed 20261002) |
beispieldaten.py |
Deterministischer Generator: python beispieldaten.py [seed] |
src/types/index.ts |
Alle Typen (Unit, Transaction, Ticket, DocumentItem, Thread, Announcement) |
src/components/AppLayout.tsx |
Sidebar (Desktop) + Mobile Top-Bar/Nav, Rollenwechsel, Ungelesen-Badge, ThemeToggle |
src/components/ThemeToggle.tsx |
Dark-Mode-Umschalter (Sonne/Mond) |
src/lib/theme.ts |
mp-theme in localStorage, Init vor erstem Render (main.tsx) |
src/pages/Login.tsx |
Landing/Login mit Hero-Bild und Demo-Einstiegen |
Dockerfile |
Optionaler All-in-One-Build (node build → nginx) für docker build-Workflow |
docker/nginx.conf |
nginx-Site: SPA-Fallback, Gzip, Cache-Header für /assets/, Security-Header |
docker-compose.yml |
mp-portal (nginx + gemountetes dist) im externen Netz npm_default; Mail-Stack separat |
deploy.sh |
Bewährter Deploy-Workflow (s. Kap. 4) |
mail-server/ |
Postfix-Relay + schlanke Mail-API (Muster Schulportal, angepasst) |
4. Deploy-Workflow (bewährt, aus Schulportal übernommen)
# 1. Bauen (im Projektverzeichnis)
npm run build
# 2. Paketieren + Hochladen (pscp braucht cwd = Projektverzeichnis)
tar -czf mp-dist.tar.gz -C dist .
"/c/Program Files/PuTTY/pscp.exe" -batch \
-hostkey "SHA256:4G3UxsugNkHH6BrPXScLXh+vX8P1sLgWKn8cZBKSRxw" \
-i "Z:\Devel\ssh\priv_ionos_hocks_vps.ppk" -P 38592 \
mp-dist.tar.gz root@hocks.eu:/tmp/
# 3. Entpacken + Container neu starten + Hash prüfen
"/c/Program Files/PuTTY/plink.exe" -batch -hostkey "SHA256:4G3UxsugNkHH6BrPXScLXh+vX8P1sLgWKn8cZBKSRxw" \
-i "Z:\Devel\ssh\priv_ionos_hocks_vps.ppk" -P 38592 root@hocks.eu \
"rm -rf /opt/mieterportal/dist && mkdir -p /opt/mieterportal/dist && \
tar -xzf /tmp/mp-dist.tar.gz -C /opt/mieterportal/dist && \
cd /opt/mieterportal && docker compose up -d && sleep 2 && \
curl -s https://mieterportal.hocks.eu/ | grep -o 'index-[^\"]*\.js'"
# Alternativ alles in einem Schritt:
./deploy.sh
- SSH: Port 38592, Key
Z:\Devel\ssh\priv_ionos_hocks_vps.ppk(Pageant), Hostkey-Flag zwingend. - Vorsicht Fail2Ban: zu viele gescheiterte SSH-Versuche von einer IP führen zu einem
Ban (Timeout-Verbindungsbild). Ban aufheben auf dem Server:
fail2ban-client unban --all. - Erst-Einrichtung auf dem Server (einmalig):
mkdir -p /opt/mieterportal+docker-compose.ymlunddocker/nginx.confdorthin kopieren, danndocker compose up -d. NPM-Proxy-Hostmieterportal.hocks.eu→ Containermp-portal:80. - HTML wird mit
no-cachegeliefert (nginx-Config), Assets hash-benannt → Reload genügt. Der eingebettete Kimi-Browser cached hart → beim Testen Cache-Buster anhängen:?v=X.
5. Zugänge & Konfiguration
- Keine echten Zugänge (Demo). Rollenwechsel im UI; Store-Reset über Browser-DevTools
(localStorage-Key
hocks-mieterportal-v1löschen). - Demo-Mieterin: Anna Berger, Hauptstraße 12, Whg. 7 (id
hs-7). - Mail-API-Token: bewusst nicht hier dokumentiert – liegt in
mail-server/mail.env(nicht im Repo; Vorlagemail.env.example).
6. Konventionen & Besonderheiten
- Dark Mode: class-Strategie, Präferenz
mp-theme, Init vor erstem Render. Feste Farbklassen werden inindex.cssfür.darkumrechnen (.dark .bg-white/.bg-slate-50/.bg-teal-50); Sidebar ist eigenes Dunkel-Teal. - Barrierefreiheit: aria-pressed/labels am ThemeToggle und Rollenwechsel, Fokus-Ringe.
- Formatierung: Beträge via
fmtEUR(Intl de-DE), Datumsformate TT.MM.JJJJ. - Datenpflege: Bestandsdaten ändern →
beispieldaten.pyanpassen und neu ausführen, nicht generated.json von Hand editieren. - Sicherheit: kein offenes Relay (Postfix mynetworks loopback + Docker-Netz, sender_canonical zentral). Upload/Download-Funktionen sind Demo-Darstellungen.
- Keine destruktiven Aktionen auf dem Server ohne ausdrückliche Bestätigung.
7. Testing
npm run build(tsc -b) ist die echte Typprüfung;npx tsc --noEmitprüft wegen Solution-tsconfig ggf. nichts.- Headless-Screenshots (Dark Mode = Systempräferenz):
"/c/Program Files/Google/Chrome/Application/chrome.exe" --headless --disable-gpu --screenshot=... --window-size=WxH "URL" - Screenshots ausgeliefert nach
preview/.
8. Verlauf / offene Punkte
Erledigt 02.10. (v1.0): Portal komplett neu aufgesetzt (5 Module, Mieter-/Verwaltungsansicht, KI-Branding: Logo/Hero/Illustration), Docker-Setup (Dockerfile, nginx, compose), Repo in git.hocks.eu angelegt, Deploy-Workflow + Dark Mode + beispieldaten.py aus dem Schulportal übernommen, mail-server-Struktur angelegt (noch nicht live verkabelt).
Offen:
- Deployment auf hocks.eu ausstehend (SSH-Zugang per Pageant-ppk geklärt; Fail2Ban-Ban
nach früher Fehlversuchen abwarten/aufheben, dann
./deploy.sh). - Mail-Stack optional einrichten:
mail.envaus Vorlage befüllen, Relay-Ziel inpostfix/main.cfsetzen, npm_default-Netz prüfen. - Mögliche nächste Schritte: echte Anmeldung + serverseitige Datenbank (PostgreSQL/Node-API), E-Mail-Benachrichtigung bei neuen Schadensmeldungen, Mehrseitigkeit für 50 echte Mietverhältnisse.
9. Sonstiges
- User kommuniziert auf Deutsch; alle UI-Texte und Antworten auf Deutsch.
- Dateien außerhalb des Workspaces immer erst in den Workspace kopieren.
- Vorsicht mit destruktiven Aktionen (Explizite Bestätigung einholen).