Commit Graph

56 Commits

Author SHA1 Message Date
3b505d231a Restructure dashboard into sidebar navigation with grouped sections
20 flat scrolling sections replaced with a 10-item sidebar nav (Übersicht,
Mieter, Tickets & Handwerker, Putzplan, WG-Kasse, Inventar & Übergabe,
Zugang, Küche & Müll, Dokumente, Verträge & Abrechnung). One page visible
at a time, collapsible off-canvas menu on mobile. No backend/API changes.
2026-08-13 08:45:25 +00:00
d69e07f00d Add Homematic IP smart lock integration (Access Point + App setup)
The lock in this WG is a Homematic IP door lock (keypad + alarm), not
Nuki/Tuya as originally specced — confirmed with the user. Homematic IP
has no official self-service partner API for Access-Point-only setups
(no local CCU), so this uses the actively-maintained open-source
`homematicip` Python library (implements the same reverse-engineered
cloud protocol used by the official app) via two scripts rather than
reimplementing the HTTP/HMAC handshake from scratch — lower risk of
subtly wrong protocol details.

- scripts/hmip_register.py: non-interactive pairing (connection
  request -> wait for the physical blue-button press on the Access
  Point -> auth token). Writes progress to a status file so the API
  can poll it instead of blocking a request for up to ~6 minutes.
- scripts/hmip_control.py: list-devices / lock / unlock via
  HMIP_ACCESS_POINT + HMIP_AUTH_TOKEN env vars (not CLI args, so they
  don't leak into process listings).
- routes/smartLock.ts: POST /smartlock/pairing/start + GET .../status
  (LANDLORD/ADMIN, one-time setup), GET /smartlock/devices
  (LANDLORD/ADMIN), POST /smartlock/devices/:id/:lock|unlock (any
  authenticated user — this is the tenant-facing "keyless door" use
  case from the spec). All lock/unlock routes 409 until pairing has
  produced HMIP_ACCESS_POINT/HMIP_AUTH_TOKEN.

Does NOT cover temporary guest PIN codes on the keypad itself — that's
handled through Homematic IP's own "eSchlüssel" app feature, which
isn't exposed by this API; guest codes remain DB-only as before.
2026-08-13 08:21:19 +00:00
6333bc70b2 Add push reminder job for expiring notice deadlines
"Automatische Warnungen bei Auslauf/Kündigungsfristen" was only a
passive dashboard view (GET /contracts/notice-deadlines, isUrgent
flag) — nobody gets notified unless the landlord happens to open the
cockpit. Adds a daily job (same pattern as dailyDunningJob.ts) that
pushes landlords/admins when a contract's notice deadline falls
within 30 days. Dedup is via the Notification history (payload.
contractId within a 14-day cooldown) rather than a new Contract
column, consistent with contracts.ts's existing "no extra model
needed" approach.
2026-08-13 07:56:18 +00:00
762e17a864 Wire up OneSignal push delivery: register endpoint + reminder jobs
sendPushNotification() (services/notificationService.ts) already called
the real OneSignal API correctly, but two things made it unreachable:
no endpoint ever set User.pushToken, and no job existed for the two
push-based requirements beyond rent dunning — cleaning check-in
reminders and the trash-calendar evening push. Both CleaningTask and
TrashSchedule already had an unused `reminderSentAt` column, so the
schema anticipated this and was just never wired up.

- PUT /v1/auth/push-token: registers the current device's OneSignal
  Player ID.
- jobs/cleaningReminderJob.ts, jobs/trashReminderJob.ts: same
  find-due/send-once/mark-reminderSentAt pattern as the existing
  dailyDunningJob.ts. Safe to run without OneSignal credentials
  configured — sendPushNotification degrades to an in-app Notification
  log when ONESIGNAL_APP_ID/API_KEY or a user's pushToken are absent.

Not done here (needs real third-party setup from the user, same as the
Cloudflare tunnel token pattern): ONESIGNAL_APP_ID/API_KEY in .env, and
a frontend OneSignal Web SDK integration (service worker, VAPID keys)
to actually populate pushToken from a real browser.
2026-08-13 07:47:42 +00:00
3629f5f66f Fix prisma client output path: target .prisma/client, not @prisma/client
Prisma 5.22's generator wants the explicit output to point at the
internal .prisma/client directory (which @prisma/client forwards to),
not the @prisma/client package directory itself — pointing it there
directly made `prisma generate` fail outright ("replace ... with
../backend/node_modules/.prisma/client").
2026-08-13 07:41:30 +00:00
791b9bb01e Add peer rating system for tenants
Implements the previously-deferred "Bewertungssystem für Zwischenmieter"
requirement, which existed only as a vague idea with no model, route, or
UI. Design (confirmed with user): any authenticated user can rate any
tenant (1-5 + optional comment), freestanding (not tied to a contract,
creatable any time), visible only to LANDLORD/ADMIN — tenants can submit
ratings but not view them, to keep WG-internal friction out of the open.

- prisma: TenantRating model + User relations. Also pins the Prisma
  Client `output` path explicitly: since schema.prisma lives at the repo
  root (no package.json there) while node_modules only exists under
  backend/, `prisma generate`'s root-inference walked up past the repo
  and wrote into an unrelated ancestor directory when invoked from a
  fresh checkout. The explicit relative output keeps repo-root schema +
  backend-only deps working the same locally and in Docker.
- backend: GET/POST /v1/ratings (role-gated read), GET /v1/ratings/tenants
  (name+room only, any authenticated user, for the picker).
- dashboard: rating form for everyone, landlord-only ratings/summary view.
2026-08-13 07:39:32 +00:00
4ba0100d31 Add 1-click PDF export for tickets (craftsman handoff)
Implements the "1-Klick-PDF-Export für Handwerker" requirement from
the ticketing module spec, which existed only as a schema stub
(HandoverProtocol.pdfUrl) with no actual generator anywhere in the
codebase. Adds a server-side PDF endpoint (pdfkit, no headless
browser needed) summarizing a ticket's category, priority, status,
room, reporter and description, plus a "PDF" button in the landlord
cockpit that downloads it via an authenticated blob fetch (the API
uses a Bearer token, not cookies, so a plain <a href> wouldn't carry
auth).
2026-08-13 07:27:01 +00:00
40b67f2a5f Seed: skip if DB already has data instead of wiping it
The seed's deleteMany() chain didn't cover Ticket (or other tables
that now reference User), so it started failing with a foreign key
violation once real ticket data existed. Rather than cascading the
delete (which would wipe real data on every container restart), seed
now only runs against an empty database and is a no-op otherwise.
2026-08-13 07:18:13 +00:00
d1b2447d92 Fix seed.ts module resolution: move to backend/prisma/
ts-node resolved node_modules relative to the script path, so running
from prisma/seed.ts (outside backend/) never found bcryptjs or
@prisma/client in backend/node_modules — the seed silently failed on
every container start. Moving the script under backend/prisma/ fixes
resolution; also adds a missing .gitignore for node_modules.
2026-08-13 07:16:11 +00:00
c8a5984f8b Dateien nach "web-dashboard" hochladen 2026-08-12 21:56:12 +00:00
ca6d851a70 Dateien nach "backend/src/routes" hochladen 2026-08-12 21:55:35 +00:00
b25f5f0cdb Dateien nach "backend/src" hochladen 2026-08-12 21:53:18 +00:00
5261ef3710 Dateien nach "prisma" hochladen 2026-08-12 21:51:22 +00:00
1dc1eade8f Dateien nach "backend/src/routes" hochladen 2026-08-12 21:38:33 +00:00
e33aadaa90 Dateien nach "backend/src/routes" hochladen 2026-08-12 21:38:03 +00:00
aad208d839 Dateien nach "prisma" hochladen 2026-08-12 21:33:55 +00:00
b7cbac9eb3 Dateien nach "backend/src" hochladen 2026-08-12 21:31:52 +00:00
007ed74527 index.html final korrigiert (byte-exact reupload) 2026-08-12 21:28:30 +00:00
7bfa45a400 Add Putzplan calendar/absences UI 2026-08-12 19:57:54 +00:00
9c99d3b631 Add cleaning-calendar and cleaning-absences endpoints 2026-08-12 19:37:04 +00:00
dbf670a0b3 Add CleaningAbsence model for Putzplan-Kalender 2026-08-12 19:32:41 +00:00
544eb4d745 Add Putzplan UI section 2026-08-12 19:11:21 +00:00
669aed188c Add tenants list endpoint for cleaning-task assignment 2026-08-12 18:56:47 +00:00
869aeb2a2c Mount cleaning-tasks router 2026-08-12 18:51:47 +00:00
57ee85292c Add Putzplan cleaning-tasks route 2026-08-12 18:50:23 +00:00
e3ac1e9c4a Add ticket reporting UI and role-scoped rendering (tenant privacy) 2026-08-12 18:39:17 +00:00
ff7e815704 Mount tickets router 2026-08-12 18:25:09 +00:00
efcbcab0d8 Restrict cockpit summary to own data + shared areas for tenants 2026-08-12 18:24:28 +00:00
ffea782e96 Add tickets API with room-scoped access control for tenants 2026-08-12 18:22:42 +00:00
6d8cbd7f42 add login + invite UI to web dashboard 2026-08-12 18:03:24 +00:00
00eaa3d7d6 update prisma/schema.prisma (add Invitation model) 2026-08-12 17:53:57 +00:00
bd96bb2db1 add backend/src/routes/invitations.ts 2026-08-12 17:48:25 +00:00
b20eec366f update backend/src/routes/auth.ts 2026-08-12 17:45:55 +00:00
e1b3ea65ba update backend/src/middleware/auth.ts 2026-08-12 17:45:54 +00:00
0797d85d78 update prisma/seed.ts 2026-08-12 17:45:54 +00:00
b7df0455a5 update backend/src/routes/cockpit.ts 2026-08-12 17:45:53 +00:00
b2428ad77e update backend/src/app.ts 2026-08-12 17:45:52 +00:00
3e61a3175f update backend/package.json 2026-08-12 17:45:52 +00:00
35b887d954 add web-dashboard/Dockerfile 2026-08-12 16:46:21 +00:00
1a2701576f add web-dashboard/index.html 2026-08-12 16:46:20 +00:00
ba0429c26b add prisma/schema.prisma 2026-08-12 16:42:35 +00:00
55b96aadb2 add prisma/seed.ts 2026-08-12 16:37:35 +00:00
efa8e4a8af add backend/scripts/send-test-webhook.ts 2026-08-12 16:36:30 +00:00
fa1ed531e3 add backend/src/jobs/dailyDunningJob.ts 2026-08-12 16:35:03 +00:00
d6f1bc781a add backend/src/services/notificationService.ts 2026-08-12 16:35:02 +00:00
1f6f9d5842 add backend/src/modules/banking/paymentService.ts 2026-08-12 16:35:01 +00:00
a7a41b16e7 add backend/src/modules/banking/matching.ts 2026-08-12 16:31:07 +00:00
29dbc8ba8f add backend/src/modules/banking/signature.ts 2026-08-12 16:31:06 +00:00
d3b1ed4049 add backend/src/modules/banking/types.ts 2026-08-12 16:31:05 +00:00
b0989f31f2 add backend/src/routes/cockpit.ts 2026-08-12 16:28:51 +00:00