feat: guide entry inspection and finalize one lease package (#60)

This commit is contained in:
nessar committed 2026-08-17 14:18:17 +02:00
1 parent 9006f5c3d5
commit 9a3e90ac74
132 files changed
+9431 -5614

No files matched your search

+4 -4
View File
@@ -4,13 +4,13 @@
Within Rental Management, `Lease` owns its contractual lifecycle, dates, rent terms, and lease-party relationships while referencing independent `Apartment` and `Tenant` aggregates by ID. Activation freezes the landlord identity and address, apartment address, tenant identities and addresses, guarantors, and financial terms; later changes are effective-dated immutable `LeaseAmendment` records that preserve both contract versions and may only recalculate future unpaid dues. `RentDue` and `RentPayment` are independent aggregates; a positive payment owns allocations whose sum cannot exceed the amount received, each allocation cannot exceed its due's remaining balance, and one payment may cover multiple dues only within the same lease. Any surplus stays unallocated. `Guarantor` remains internal to `Lease` until it gains an independent lifecycle or must be shared across leases.
`Apartment` owns stable `PrivateArea` values covering rooms and annexes under the tenant's exclusive use. A lease snapshot freezes those identifiers and descriptions; furniture-inventory lines, property-condition observations, and photo zones all reference them, while the regulatory main-room count is derived rather than stored independently.
`Apartment` owns stable `PrivateArea` values covering rooms and annexes under the tenant's exclusive use. A lease snapshot freezes those identifiers and descriptions; furniture-inventory lines, property-condition observations, and photo evidence all reference them, while the regulatory main-room count is derived rather than stored independently.
`FurnitureInventory` is also an independent aggregate referenced by `LeaseId`, not a growing collection inside `Lease`. It remains editable with the lease draft, every generated `LeaseDocumentRevision` freezes its own inventory snapshot for the printed contract, and changing the inventory obsoletes that revision; lease finalization then freezes the aggregate while separately retaining any declared handwritten entry corrections.
`FurnitureInventory` is also an independent aggregate referenced by `LeaseId`, not a growing collection inside `Lease`. It remains editable with the lease draft and receives every explicitly reconciled entry discrepancy before a `LeaseDocumentRevision` freezes its inventory snapshot; changing the inventory then obsoletes that revision, and lease finalization freezes the aggregate.
`PropertyConditionReport` is an independent aggregate identified by its own ID and uniquely constrained by `(LandlordId, LeaseId, ENTRY|EXIT)`. It owns its observations, photo references, finalization evidence, and append-only supplements; `Lease` does not embed that growing inspection history.
`PropertyConditionReport` is an independent aggregate identified by its own ID and uniquely constrained by `(LandlordId, LeaseId, ENTRY|EXIT)`. It owns its observations, photo references, finalization evidence, and accepted supplement requests. A request accepted before signature changes the draft and invalidates the affected confirmations; one accepted after finalization is append-only. `Lease` does not embed that growing inspection history.
Creating the `EXIT` report snapshots the effective finalized `ENTRY` report, including accepted supplements, while preserving the stable room, zone, inventory-line, and entry-photo references needed for deterministic comparison. The exit draft then evolves independently; every entry photo requires one explicitly linked exit counterpart or an audited absence reason, while additional unpaired exit photos remain allowed.
Creating the `EXIT` report snapshots the effective finalized `ENTRY` report, including accepted supplements, while preserving the stable room, zone, inventory-line, and entry-photo references needed for deterministic comparison. The exit draft then evolves independently and presents entry photos as area references without requiring one-to-one photo pairing.
A new `Lease` is always a mutable, permanently deletable `DRAFT`; draft overlap is allowed and creates no dues. Explicit activation reserves the period in the apartment's versioned `ApartmentOccupancy` aggregate, which retains active and archived lease periods and rejects inclusive overlap, then creates one `RentDue` per landlord, lease, and occupied calendar month under a unique database constraint. Making concurrent activations contend on the same occupancy document prevents write skew that a query-only overlap check would allow. Boundary months prorate rent and charges by occupied calendar days. An amendment split combines its before and after portions before performing one monetary rounding step, while settlement and due-date timing remain independent facts on the due.
@@ -2,10 +2,10 @@
**Status**: accepted
Inspection-photo uploads are auto-oriented from EXIF, fitted without upscaling inside an orientation-aware 1920 × 1080 frame while preserving aspect ratio, converted by the server to WebP at 75% quality, and stripped of metadata before receiving their stable reference and SHA-256 fingerprint. The normalized image is the immutable evidence retained and shared with the parties; the original upload is deleted after successful conversion, trading original fidelity and device-supplied metadata for bounded local storage and reduced privacy leakage while allowing the landlord to review and retake a photo before finalization. Reliable capture references and audit timestamps remain application-controlled facts rather than EXIF claims.
Inspection-photo uploads are auto-oriented from EXIF, fitted without upscaling inside an orientation-aware 1920 × 1080 frame while preserving aspect ratio, converted by the server to WebP at 75% quality, and stripped of metadata before receiving their stable reference and SHA-256 fingerprint. The same operation produces a stripped PNG thumbnail bounded to 320 × 240 for PDF embedding. The normalized WebP is the immutable evidence retained and shared with the parties; the original upload is deleted after successful conversion, trading original fidelity and device-supplied metadata for bounded local storage and reduced privacy leakage while allowing the landlord to review and retake a photo before finalization. Reliable capture references and audit timestamps remain application-controlled facts rather than EXIF claims.
The server delegates this normalization to ImageMagick installed in the runtime image and invoked directly without a shell. Its security policy denies every coder and delegate by default, enables only the input formats explicitly accepted by the product and WebP output, restricts paths to application-controlled temporary files, and bounds dimensions, sequence length, memory, mapped memory, disk, threads, and execution time. The application additionally enforces a process timeout, validates the resulting format and dimensions, and publishes the normalized file only after successful verification. This avoids depending on small Java WebP wrappers while keeping the image processor replaceable behind one adapter.
The server delegates this normalization to ImageMagick installed in the runtime image and invoked directly without a shell. Its security policy denies every coder and delegate by default, enables only the input formats explicitly accepted by the product and WebP/PNG output, restricts paths to application-controlled temporary files, and bounds dimensions, sequence length, memory, mapped memory, disk, threads, and execution time. The application additionally enforces a process timeout, validates both resulting formats and dimensions, and publishes the normalized files only after successful verification. This avoids depending on small Java WebP wrappers while keeping the image processor replaceable behind one adapter.
Accepted uploads are single-image JPEG, PNG, WebP, and HEIC/HEIF files, identified from their decoded content rather than trusted extensions or client-supplied media types. Animated or multi-image inputs and every other format are rejected. HEIC/HEIF support is supplied by the runtime ImageMagick build through its system `libheif` codec; the container build verifies that the four accepted decoders and the WebP encoder are actually available.
Accepted uploads are single-image JPEG, PNG, WebP, and HEIC/HEIF files, identified from their decoded content rather than trusted extensions or client-supplied media types. Animated or multi-image inputs and every other format are rejected. HEIC/HEIF support is supplied by the runtime ImageMagick build through its system `libheif` codec; the container build verifies that the four accepted decoders and the WebP and PNG encoders are actually available.
Upload byte counts and source pixel dimensions are operational resource controls, not domain rules. ImageMagick limits remain configurable and their defaults are calibrated with representative and adversarial images under the target container memory and expected concurrency; they are not inferred from codec capabilities. Exceeding a resource limit or failing normalization deletes the temporary source, leaves the report draft unchanged, and returns an actionable retry error. No stable photo reference is created until the normalized result has passed format and dimension verification.
@@ -1,5 +1,5 @@
# Allow declared handwritten inventory corrections at lease entry
**Status**: accepted
**Status**: superseded by ADR-0021
When the entry condition report reveals a difference from the furniture inventory printed in the latest lease revision, the parties may correct that inventory by hand and initial the correction before signing. The printed revision number is never changed by hand: it continues to identify the generated base document, while the declared corrections form a separate contractual layer. Lease finalization requires the landlord to answer whether such differences exist, confirm which corrections prefilled from the structured report were actually written and initialed, and attest that every party initialed them; correction text may be adjusted and exceptional inventory corrections added, while changes to any other lease term still require a regenerated revision. The signed scan becomes the contractual evidence.
@@ -0,0 +1,5 @@
# Generate the lease signature package after the entry condition report
**Status**: superseded by ADR-0021
The complete lease draft and its furniture inventory feed the entry condition report before any lease revision is printed for signature. Once every report step is confirmed, the application generates the signature package containing the lease, the contractual inventory, and the neutral statement that the entry condition report was completed. After the signed lease is uploaded and finalized, the condition-report PDF is added immutably to its final dossier. This order removes the handwritten inventory-correction layer and supersedes ADR-0018.
@@ -0,0 +1,5 @@
# Bind handwritten signatures to an immutable condition-report revision
**Status**: superseded by ADR-0021
The inspection is captured once in the guided tunnel, including its photos, then frozen as a numbered PDF revision with a short fingerprint. A signature sheet prepared before the visit identifies the lease and parties; the revision and fingerprint are copied onto it before the parties sign by hand, then its scan is bound to that exact PDF. This avoids duplicate entry, an on-site printer, and a paid electronic-signature service. The release remains subject to legal validation of this hybrid proof mechanism.
@@ -0,0 +1,5 @@
# Sign and finalize one package containing the lease and entry report
**Status**: accepted
The complete lease draft and inventory feed the guided entry condition report before the first signature revision is generated. After every report step is confirmed and each inventory discrepancy is reconciled, the application freezes one PDF package containing the lease, contractual inventory, illustrated condition report, and a signature clause that explicitly covers every listed annex. An accepted supplement request received before signature changes that draft and invalidates the package; one received after finalization remains append-only. The landlord sends the current package outside the application, all parties sign it by hand, and the returned scan is uploaded once to finalize the lease and entry report atomically. This avoids on-site printing, duplicate entry, paid electronic signatures, a separate signature sheet, and a post-finalization condition-report attachment. This decision supersedes ADR-0019 and ADR-0020.
@@ -1,4 +1,4 @@
# Reset development data instead of preserving compatibility
# Reset development data rather than preserving compatibility
**Status**: accepted