Neue Ankündigungen (z. B. Schornsteinfeger, Handwerkertermin), nur vom
Vermieter anlegbar, für alle sichtbar. Zusätzlich eine gebündelte
'Für dich diese Woche'-Übersicht für Mieter mit fälligem Putzplan,
fälliger Miete, anstehendem Mülltermin und Ankündigungen der nächsten
7 Tage.
Statt zeitlich begrenzter Gästecodes, die jeder selbst ausstellen konnte,
gibt es jetzt einen dauerhaften Code je Mieter, den ausschließlich der
Vermieter vergibt/widerruft. Der Mieter sieht nur seinen eigenen Code
(read-only).
Server-side testing showed the 30mb express.json limit itself was
fine for payloads up to 30MB, but real phone photos (15-25MB each,
×3 files) can still exceed that. Adds readFileAsCompressedDataUrl:
downscales image uploads to max 1800px on the long edge at 0.82 JPEG
quality via canvas before converting to a data URL — typically
shrinks a multi-MB phone photo to a few hundred KB, which is more than
sufficient resolution for a legible ID/Schufa scan. PDFs pass through
uncompressed. Also raises the raw pre-upload size check to 25MB/file
and the server body limit to 50mb as a safety margin for PDF-heavy
cases the client-side compression doesn't touch.
Accepting an invitation as TENANT now sends up to three files (ID
front, ID back, optional Schufa) as base64 data URLs in one JSON body.
Raises express.json's limit from 10mb to 30mb so three real phone
photos fit. Also adds a client-side 8MB-per-file check with a clear
error message instead of letting an oversized file hit the server
limit and surface a bare "Status 413".
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.
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.