Skip to main content

Module mandate

Module mandate 

Source
Expand description

Mandate — juridical delegation tracker (Story 3.4 — FR7 INV-14).

When a syndic must delegate a legal/technical act to an external professional (notaire for a unit sale, avocat for a litigation, architecte for renovation works, BET for technical studies, AMO for project management assistance, gardien for on-site duties), they issue a Mandate materialising:

  • the mandataire (subject_user_id),
  • the kind (mapped to a Story 3.1 UserRole),
  • the scope (Building or whole ACP),
  • mandatory temporal validity (valid_from / valid_until),
  • immutable audit (issued_by, reason, timestamps),
  • optional early revocation (revoked_at).

§Invariants enforced at issue() time

  • valid_until > valid_from
  • valid_until - valid_from <= 5 years (anti-abuse: no unlimited mandates)
  • reason.len() in [10, 500]
  • subject_user_id != issued_by (a syndic may not mandate themselves)

Runtime helpers is_expired() / is_revoked() / is_currently_active() are used by the upstream guard assert_mandate_authorizes to emit the correctly-typed AppError::Mandate* (403/404) instead of generic Forbidden strings.

Structs§

Mandate

Enums§

MandateKind
Kind of mandate. Mapped to a UserRole (Story 3.1) — issuing a mandate presumes the subject already carries the corresponding role.
MandateScope
Scope a mandate applies to. Either a single building, or the whole ACP (e.g. a notaire mandated on all transactions of a copropriété).

Constants§

MAX_MANDATE_DURATION_DAYS
Anti-abuse: a single mandate cannot be active for more than 5 years. Reissue (with a fresh reason) keeps the audit trail granular.
MAX_REASON_LEN
Hard upper bound to keep DB rows compact and prevent free-form abuse.
MIN_REASON_LEN
Minimal reason length (Belgian deontological practice: a mandate without a stated motive is unenforceable in front of a juge de paix).