Adds "Wieder aufnehmen" to each archived contract card: landlord picks
a vacant room, move-in date, rent and deposit, then POST
/contracts/reactivate creates a fresh Contract row for that user (new
id, new terms, no carried-over documents/signature) and re-assigns the
room. The old contract is never touched — it stays exactly as-is in
the archive as a historical record, per the requirement that the
original tenancy documentation must be preserved even after rejoining.
New GET /contracts/vacant-rooms lists rooms with no active contract,
used to populate the room picker and prefill sensible rent/deposit
defaults from the room's base rent.
Landlords can now remove a tenant from their room via a "Mieter
ausziehen lassen" button on the contract card. This never deletes
anything: POST /contracts/:id/move-out sets Contract.isActive=false
(with an endDate), frees the room (User.roomId=null,
Room.status=VACANT) so it can be re-assigned via the existing invite
flow, and leaves the contract row — along with every linked payment,
ticket, rating, handover protocol, and contract document — untouched
and permanently queryable.
GET /contracts/documents now only lists active contracts; the new
GET /contracts/archive (landlord/admin only) lists deactivated ones,
rendered in a new "Archiv — ausgezogene Mieter" section on the
Verträge-page with their historical documents still downloadable.
Rewrites contractDocumentGenerator.ts from a short summary into a
proper Wohnraummietvertrag layout: numbered §§ for Vertragsparteien,
Mieträume, Mietzeit, Miete/Nebenkosten, Kaution, Instandhaltung/
Schönheitsreparaturen, Hausordnung, Tierhaltung/Untervermietung,
Mietanpassung, sonstige Vereinbarungen, salvatorische Klausel, plus
signature lines for both landlord and tenant (with the drawn signature
embedded once signed) and a page-footer disclaimer instead of a
top-of-document warning box.
Adds Contract.landlordName/landlordAddress/propertyAddress so the
document can show a real letterhead — addresses default to a
"please fill in" placeholder rather than a fabricated address, since
this is a real WG's data. Landlord fills them once via new fields in
the contract generator form; persisted per contract like the other
template options.
Landlords configure a contract via checkboxes/selects (WLAN included,
furnished, utility billing model, notice period, deposit, rent
adjustment clause) and generate a PDF (pdfkit) that's automatically
attached to the contract's document list. Tenants sign their own
contract in-app by drawing a signature on a canvas; signing embeds the
signature image into a freshly generated final PDF and marks the
contract as signed with a timestamp.
New: Contract.wifiIncluded/furnished/utilityBillingModel (+ new
UtilityBillingModel enum), Contract.tenantSignatureUrl/signedAt.
New endpoints: POST /contracts/:id/generate-document (landlord/admin),
POST /contracts/:id/sign (tenant on own contract, or landlord/admin).
Explicitly a documentation template generated from app data, not a
legally reviewed contract — noted in the PDF itself.
Replaces the unused, never-wired-up single contractPdfUrl field with
contractDocumentUrls (String[]) so landlords can attach several files
per contract (signed lease, addenda, ...) instead of just one. New
endpoints: GET /contracts/documents (tenant sees own contract only,
landlord sees all — same visibility rule as the rest of the app),
POST/DELETE /contracts/:id/documents (landlord/admin only). Frontend
reuses the existing FileReader-to-data-URL upload pattern already used
for inventory photos, so files are stored inline like everywhere else
in this app rather than introducing a new storage mechanism.