The application has many user-editable forms beyond Appartement creation and editing. They use different Angular form APIs and operation-specific state holders, and their client-side constraints and error presentation are not consistently aligned with the backend domain. Some save flows discard backend details, some display a single server message, and some expose raw domain or framework wording. A landlord can therefore encounter late, generic, or misleading errors in Bail, tenant, inventory, state-of-the-premises, payment, and document workflows.
Issue #41 establishes the structured validation-error contract and proves it through the Appartement form. Without a deliberate rollout, the remaining forms will continue to behave inconsistently and future forms may repeat the same problem.
Solution
After #41 lands, audit every remaining user-editable form against its actual backend request DTO and domain invariants. Migrate each form to the shared field-path/error-code contract, mirror every user-correctable save-time constraint in Angular, and apply the agreed interaction model: visible required fields, French inline guidance after touch or submit, first-invalid focus, per-field server-error clearing, preserved values, operation-local pending state, and safe top-level handling for non-field failures.
Do not centralize domain rules in a new validation framework. The backend domain remains authoritative; each Angular form explicitly mirrors the small set of rules its user can influence. Reuse the shared HTTP error and form-state seams established by #41. Coordinate the state-of-the-premises portion with #40 so planned work is not duplicated.
User Stories
As a landlord, I want every form to identify required fields before submission, so that I can complete workflows without trial and error.
As a landlord, I want every user-editable field to follow the same save-time validity as its backend domain value, so that the frontend does not submit requests the backend predictably rejects.
As a landlord, I want the frontend not to invent stricter rules than the backend, so that valid domain values remain enterable.
As a landlord, I want optional facts to remain optional at the lifecycle stage where the domain permits them, so that progressive workflows are not blocked prematurely.
As a landlord, I want validation guidance in French beside the affected control, so that I never need to interpret raw Jakarta or English domain messages.
As a landlord, I want untouched fields left quiet, so that a new form does not open covered in errors.
As a landlord, I want touched invalid fields explained immediately, so that I can correct them while I work.
As a landlord, I want one submit attempt to reveal every current field failure, so that I can correct the form in one pass.
As a keyboard user, I want an invalid submit to focus the first invalid control, so that long and nested forms remain navigable.
As a landlord, I want a corrected field's backend error cleared independently, so that the interface reflects my correction without hiding other failures.
As a landlord, I want entered values preserved after failed validation, network errors, conflicts, and unexpected failures, so that recovery does not require re-entry.
As a landlord, I want save actions blocked only while their own operation is pending, so that duplicate submissions stop without freezing unrelated work.
As a landlord, I want backend field failures mapped to controls even when client validation missed a new rule, so that validation drift remains recoverable.
As a landlord, I want unknown field codes and cross-field failures shown safely at form level, so that an unmapped response never disappears or renders raw JSON.
As a landlord, I want conflicts distinguished from invalid input, so that stale data, referenced resources, and business conflicts provide suitable recovery guidance.
As a landlord, I want unexpected failures reported generically without internal details, so that production diagnostics remain private.
As a landlord, I want tenant creation and editing to apply the same identity, email, phone, and address constraints as the backend.
As a landlord, I want landlord-profile editing to apply the same completeness and contact constraints as the backend.
As a landlord, I want Bail draft and amendment forms to mirror party, date, monetary, charge, revision, guarantor, clause, and legal-term invariants relevant at their lifecycle stage.
As a landlord, I want Appartement document uploads to validate document metadata, dates, file presence, type, and size before avoidable requests are made.
As a landlord, I want furniture inventory editing to explain invalid quantities, presence choices, required categories, and labels at their matching controls.
As a landlord, I want lease-ending forms to explain invalid dates, reasons, evidence metadata, withdrawal, invalidation, agreed end, and closure facts at the point of entry.
As a landlord, I want Bail finalization to identify missing files, attestations, revision facts, signatures, and inventory corrections without collapsing them into one generic error.
As a landlord, I want state-of-the-premises editing and finalization to map nested participant, observation, meter, access, inventory, zone, photo, and evidence failures to their visible sections.
As a landlord, I want rent payment, allocation, reversal, and refund dialogs to align amount, date, reason, balance, and version constraints with the backend.
As a landlord, I want rent-revision preview, proposal, delivery, and application forms to align index, amount, period, delivery, proof, and date constraints with the backend.
As a developer, I want every mutable HTTP request audited against its corresponding Angular form, so that no form or backend-only rule is silently omitted.
As a developer, I want stable English field paths and error codes used consistently across web adapters, so that all Angular forms share one parsing convention.
As a developer, I want only deliberately classified errors exposed to clients, so that arbitrary exception text is not treated as user guidance.
As a developer, I want focused parity tests at existing seams, so that future changes fail close to the form or API contract they break.
As a developer, I want the shared implementation from #41 reused without another state-management or validation abstraction, so that form behavior becomes consistent without a framework migration.
As a future contributor, I want new form conventions demonstrated by representative existing forms and tests, so that new workflows naturally follow the same behavior.
Implementation Decisions
This issue starts after #41 and reuses its HTTP validation payload, frontend parsing, safe error classification, HTTP status conventions, and Appartement reference implementation.
Build a written parity checklist during implementation that pairs each user-editable Angular field with its backend request constraint and domain invariant. The checklist is implementation evidence, not a runtime schema.
Audit all remaining current user-editable surfaces: landlord profile, tenant, guarantor, Bail draft/amendment/legal terms/clauses, Appartement documents, furniture inventory, Bail finalization, lease ending and evidence, state-of-the-premises editing/finalization/supplements, rent payments/allocations/reversals/refunds, and rent-revision workflows.
Coordinate state-of-the-premises DTO validation and page decomposition with #40. Reuse completed work and do not implement the same boundary twice.
The backend domain remains authoritative. Angular explicitly mirrors only user-influenceable save-time constraints; technical IDs, optimistic versions, storage metadata, and internal invariants remain backend-only.
Do not change when a domain fact becomes required merely to make forms uniform. Draft, readiness, finalization, and legal-warning boundaries remain specific to each aggregate and use case.
Reuse the validation response established by #41: HTTP 400, top-level validation_failed, and all stable English field-path/code entries. Conflicts remain 409 and unexpected failures remain safe 500 responses.
Deliberately classify safe domain/input errors as each workflow is migrated. Do not expose arbitrary IllegalArgumentException text.
Angular owns French field messages. Safe non-field server messages remain available for business conflicts and fallbacks according to ADR-0005.
Apply the same interaction behavior to every migrated form: required markers, touched-or-submit visibility, all-errors reveal, first-invalid focus, independent server-error clearing, preserved input, and operation-local pending controls.
Existing native and Angular Material controls remain preferred where they prevent invalid enum, date, number, and file choices. Do not replace working controls solely for visual uniformity.
Reuse the established Angular forms approach within each feature. This issue does not require rewriting every form to one forms API when behavior can be made consistent with a smaller change.
Do not add OpenAPI generation, JSON Schema validation, a shared validation DSL, a new form library, or another state-management mechanism.
Update relevant domain documentation only if an audit uncovers an unresolved domain term or lifecycle decision. Do not place implementation constraints in the glossary.
Testing Decisions
Tests assert user-visible form behavior and public HTTP responses, not validator implementation details.
For each workflow, prefer its existing authenticated web-adapter test as the highest backend seam. Add focused invalid requests proving all relevant field paths/codes are returned before the use case is invoked.
Prefer existing Angular component tests as the highest frontend seam. Cover required markers, validation timing, French inline messages, focus, correction clearing, preserved data, and pending state for each migrated form.
Exercise shared parsing and state behavior once in the shared frontend seam established by #41. Individual forms test only their mapping and domain-specific constraints rather than duplicating the parser suite.
Add browser coverage only to existing critical journeys where multiple composed components or dialogs make unit-level confidence insufficient. Do not create one Playwright test per field or a new E2E suite.
Use paired backend/frontend cases for every nuanced or cross-field rule. Straight enum constraints already made impossible by a selector need only representative coverage.
Verify malformed or unknown server validation entries produce a safe form-level French fallback rather than raw JSON or a missing error.
Verify conflicts remain distinguishable from validation and that unexpected exception messages are not exposed.
Preserve the repository's existing tests for asynchronous loading, duplicate-submission prevention, stale-response handling, accessibility, and landlord isolation.
Run the full frontend formatter, lint, type checker, unit tests, relevant Playwright journeys, backend formatter/static checks, domain/web/integration tests, and builds after the rollout.
Out of Scope
The Appartement creation/editing migration delivered by #41.
Replacing domain rules or lifecycle boundaries merely to standardize frontend behavior.
Adding new business fields, redesigning workflows, or performing unrelated component refactors.
A generated API client, JSON Schema, runtime schema validator, shared validation DSL, or new dependency.
Rewriting all forms to a single Angular forms API when existing approaches can satisfy the interaction contract.
Exposing technical invariants as editable fields.
HTTP 422; validation remains HTTP 400.
A general internationalization framework or non-French UI.
Backward-compatible API adapters, database migrations, or preservation of disposable development data.
Duplicating work already delivered or explicitly owned by #40.
Further Notes
#41 is the executable reference for the common contract and must land first.
#40 owns overlapping state-of-the-premises HTTP-boundary work. Resolve overlap by reusing its result or narrowing this issue's remaining checklist.
The audit should produce the smallest change per form. Shared code is justified only where #41 already established the seam or repeated migrations prove an independently testable helper is necessary.
Blocked by: #41
## Problem Statement
The application has many user-editable forms beyond Appartement creation and editing. They use different Angular form APIs and operation-specific state holders, and their client-side constraints and error presentation are not consistently aligned with the backend domain. Some save flows discard backend details, some display a single server message, and some expose raw domain or framework wording. A landlord can therefore encounter late, generic, or misleading errors in Bail, tenant, inventory, state-of-the-premises, payment, and document workflows.
Issue #41 establishes the structured validation-error contract and proves it through the Appartement form. Without a deliberate rollout, the remaining forms will continue to behave inconsistently and future forms may repeat the same problem.
## Solution
After #41 lands, audit every remaining user-editable form against its actual backend request DTO and domain invariants. Migrate each form to the shared field-path/error-code contract, mirror every user-correctable save-time constraint in Angular, and apply the agreed interaction model: visible required fields, French inline guidance after touch or submit, first-invalid focus, per-field server-error clearing, preserved values, operation-local pending state, and safe top-level handling for non-field failures.
Do not centralize domain rules in a new validation framework. The backend domain remains authoritative; each Angular form explicitly mirrors the small set of rules its user can influence. Reuse the shared HTTP error and form-state seams established by #41. Coordinate the state-of-the-premises portion with #40 so planned work is not duplicated.
## User Stories
1. As a landlord, I want every form to identify required fields before submission, so that I can complete workflows without trial and error.
2. As a landlord, I want every user-editable field to follow the same save-time validity as its backend domain value, so that the frontend does not submit requests the backend predictably rejects.
3. As a landlord, I want the frontend not to invent stricter rules than the backend, so that valid domain values remain enterable.
4. As a landlord, I want optional facts to remain optional at the lifecycle stage where the domain permits them, so that progressive workflows are not blocked prematurely.
5. As a landlord, I want validation guidance in French beside the affected control, so that I never need to interpret raw Jakarta or English domain messages.
6. As a landlord, I want untouched fields left quiet, so that a new form does not open covered in errors.
7. As a landlord, I want touched invalid fields explained immediately, so that I can correct them while I work.
8. As a landlord, I want one submit attempt to reveal every current field failure, so that I can correct the form in one pass.
9. As a keyboard user, I want an invalid submit to focus the first invalid control, so that long and nested forms remain navigable.
10. As a landlord, I want a corrected field's backend error cleared independently, so that the interface reflects my correction without hiding other failures.
11. As a landlord, I want entered values preserved after failed validation, network errors, conflicts, and unexpected failures, so that recovery does not require re-entry.
12. As a landlord, I want save actions blocked only while their own operation is pending, so that duplicate submissions stop without freezing unrelated work.
13. As a landlord, I want backend field failures mapped to controls even when client validation missed a new rule, so that validation drift remains recoverable.
14. As a landlord, I want unknown field codes and cross-field failures shown safely at form level, so that an unmapped response never disappears or renders raw JSON.
15. As a landlord, I want conflicts distinguished from invalid input, so that stale data, referenced resources, and business conflicts provide suitable recovery guidance.
16. As a landlord, I want unexpected failures reported generically without internal details, so that production diagnostics remain private.
17. As a landlord, I want tenant creation and editing to apply the same identity, email, phone, and address constraints as the backend.
18. As a landlord, I want landlord-profile editing to apply the same completeness and contact constraints as the backend.
19. As a landlord, I want Bail draft and amendment forms to mirror party, date, monetary, charge, revision, guarantor, clause, and legal-term invariants relevant at their lifecycle stage.
20. As a landlord, I want Appartement document uploads to validate document metadata, dates, file presence, type, and size before avoidable requests are made.
21. As a landlord, I want furniture inventory editing to explain invalid quantities, presence choices, required categories, and labels at their matching controls.
22. As a landlord, I want lease-ending forms to explain invalid dates, reasons, evidence metadata, withdrawal, invalidation, agreed end, and closure facts at the point of entry.
23. As a landlord, I want Bail finalization to identify missing files, attestations, revision facts, signatures, and inventory corrections without collapsing them into one generic error.
24. As a landlord, I want state-of-the-premises editing and finalization to map nested participant, observation, meter, access, inventory, zone, photo, and evidence failures to their visible sections.
25. As a landlord, I want rent payment, allocation, reversal, and refund dialogs to align amount, date, reason, balance, and version constraints with the backend.
26. As a landlord, I want rent-revision preview, proposal, delivery, and application forms to align index, amount, period, delivery, proof, and date constraints with the backend.
27. As a developer, I want every mutable HTTP request audited against its corresponding Angular form, so that no form or backend-only rule is silently omitted.
28. As a developer, I want stable English field paths and error codes used consistently across web adapters, so that all Angular forms share one parsing convention.
29. As a developer, I want only deliberately classified errors exposed to clients, so that arbitrary exception text is not treated as user guidance.
30. As a developer, I want focused parity tests at existing seams, so that future changes fail close to the form or API contract they break.
31. As a developer, I want the shared implementation from #41 reused without another state-management or validation abstraction, so that form behavior becomes consistent without a framework migration.
32. As a future contributor, I want new form conventions demonstrated by representative existing forms and tests, so that new workflows naturally follow the same behavior.
## Implementation Decisions
- This issue starts after #41 and reuses its HTTP validation payload, frontend parsing, safe error classification, HTTP status conventions, and Appartement reference implementation.
- Build a written parity checklist during implementation that pairs each user-editable Angular field with its backend request constraint and domain invariant. The checklist is implementation evidence, not a runtime schema.
- Audit all remaining current user-editable surfaces: landlord profile, tenant, guarantor, Bail draft/amendment/legal terms/clauses, Appartement documents, furniture inventory, Bail finalization, lease ending and evidence, state-of-the-premises editing/finalization/supplements, rent payments/allocations/reversals/refunds, and rent-revision workflows.
- Coordinate state-of-the-premises DTO validation and page decomposition with #40. Reuse completed work and do not implement the same boundary twice.
- The backend domain remains authoritative. Angular explicitly mirrors only user-influenceable save-time constraints; technical IDs, optimistic versions, storage metadata, and internal invariants remain backend-only.
- Do not change when a domain fact becomes required merely to make forms uniform. Draft, readiness, finalization, and legal-warning boundaries remain specific to each aggregate and use case.
- Reuse the validation response established by #41: HTTP 400, top-level `validation_failed`, and all stable English field-path/code entries. Conflicts remain 409 and unexpected failures remain safe 500 responses.
- Deliberately classify safe domain/input errors as each workflow is migrated. Do not expose arbitrary `IllegalArgumentException` text.
- Angular owns French field messages. Safe non-field server messages remain available for business conflicts and fallbacks according to ADR-0005.
- Apply the same interaction behavior to every migrated form: required markers, touched-or-submit visibility, all-errors reveal, first-invalid focus, independent server-error clearing, preserved input, and operation-local pending controls.
- Existing native and Angular Material controls remain preferred where they prevent invalid enum, date, number, and file choices. Do not replace working controls solely for visual uniformity.
- Reuse the established Angular forms approach within each feature. This issue does not require rewriting every form to one forms API when behavior can be made consistent with a smaller change.
- Do not add OpenAPI generation, JSON Schema validation, a shared validation DSL, a new form library, or another state-management mechanism.
- Update relevant domain documentation only if an audit uncovers an unresolved domain term or lifecycle decision. Do not place implementation constraints in the glossary.
## Testing Decisions
- Tests assert user-visible form behavior and public HTTP responses, not validator implementation details.
- For each workflow, prefer its existing authenticated web-adapter test as the highest backend seam. Add focused invalid requests proving all relevant field paths/codes are returned before the use case is invoked.
- Prefer existing Angular component tests as the highest frontend seam. Cover required markers, validation timing, French inline messages, focus, correction clearing, preserved data, and pending state for each migrated form.
- Exercise shared parsing and state behavior once in the shared frontend seam established by #41. Individual forms test only their mapping and domain-specific constraints rather than duplicating the parser suite.
- Add browser coverage only to existing critical journeys where multiple composed components or dialogs make unit-level confidence insufficient. Do not create one Playwright test per field or a new E2E suite.
- Use paired backend/frontend cases for every nuanced or cross-field rule. Straight enum constraints already made impossible by a selector need only representative coverage.
- Verify malformed or unknown server validation entries produce a safe form-level French fallback rather than raw JSON or a missing error.
- Verify conflicts remain distinguishable from validation and that unexpected exception messages are not exposed.
- Preserve the repository's existing tests for asynchronous loading, duplicate-submission prevention, stale-response handling, accessibility, and landlord isolation.
- Run the full frontend formatter, lint, type checker, unit tests, relevant Playwright journeys, backend formatter/static checks, domain/web/integration tests, and builds after the rollout.
## Out of Scope
- The Appartement creation/editing migration delivered by #41.
- Replacing domain rules or lifecycle boundaries merely to standardize frontend behavior.
- Adding new business fields, redesigning workflows, or performing unrelated component refactors.
- A generated API client, JSON Schema, runtime schema validator, shared validation DSL, or new dependency.
- Rewriting all forms to a single Angular forms API when existing approaches can satisfy the interaction contract.
- Exposing technical invariants as editable fields.
- HTTP 422; validation remains HTTP 400.
- A general internationalization framework or non-French UI.
- Backward-compatible API adapters, database migrations, or preservation of disposable development data.
- Duplicating work already delivered or explicitly owned by #40.
## Further Notes
- #41 is the executable reference for the common contract and must land first.
- #40 owns overlapping state-of-the-premises HTTP-boundary work. Resolve overlap by reusing its result or narrowing this issue's remaining checklist.
- The audit should produce the smallest change per form. Shared code is justified only where #41 already established the seam or repeated migrations prove an independently testable helper is necessary.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Blocked by: #41
Problem Statement
The application has many user-editable forms beyond Appartement creation and editing. They use different Angular form APIs and operation-specific state holders, and their client-side constraints and error presentation are not consistently aligned with the backend domain. Some save flows discard backend details, some display a single server message, and some expose raw domain or framework wording. A landlord can therefore encounter late, generic, or misleading errors in Bail, tenant, inventory, state-of-the-premises, payment, and document workflows.
Issue #41 establishes the structured validation-error contract and proves it through the Appartement form. Without a deliberate rollout, the remaining forms will continue to behave inconsistently and future forms may repeat the same problem.
Solution
After #41 lands, audit every remaining user-editable form against its actual backend request DTO and domain invariants. Migrate each form to the shared field-path/error-code contract, mirror every user-correctable save-time constraint in Angular, and apply the agreed interaction model: visible required fields, French inline guidance after touch or submit, first-invalid focus, per-field server-error clearing, preserved values, operation-local pending state, and safe top-level handling for non-field failures.
Do not centralize domain rules in a new validation framework. The backend domain remains authoritative; each Angular form explicitly mirrors the small set of rules its user can influence. Reuse the shared HTTP error and form-state seams established by #41. Coordinate the state-of-the-premises portion with #40 so planned work is not duplicated.
User Stories
Implementation Decisions
validation_failed, and all stable English field-path/code entries. Conflicts remain 409 and unexpected failures remain safe 500 responses.IllegalArgumentExceptiontext.Testing Decisions
Out of Scope
Further Notes
mentioned in issue #41
mentioned in issue #47
mentioned in issue #48
mentioned in issue #49
mentioned in issue #50
mentioned in issue #51
mentioned in issue #52
mentioned in issue #53
mentioned in issue #54
mentioned in issue #55
mentioned in issue #56
mentioned in issue #57
mentioned in issue #58
mentioned in issue #59
Preserved GitLab #42 history: source attribution, exact timestamps, discussion grouping and review positions. Historical diff snapshots: 5; visible source notes: 14.
gitlab-47-issue-42.md (SHA-256
448484e0bb508e865da7a65478700e34633b176c334749f1b36359ce9b17ad45)gitlab-47-issue-42.json (SHA-256
c605942a61d2a54b74f6ab823c3cd7913e3436dd3d279799797e132e9b4986e9)Old CI job execution and reports are omitted. Original source files and rollback backups remain protected.