Context
Off-plan property имеет фундаментальный risk: double-sale (двое продают один и тот же unit разным buyers). Когда Studio приглашает External Sales Agent или Agency, нужно гарантировать что каждый unit имеет один правовой owner на момент reserve action.
Дополнительный constraint: real-world паттерн — Organisation пригласила external sales agency → не хочет чтобы агенты сразу видели pricing на 100 квартир (commercial confidentiality). Default mode должен быть secure-by-default (не expose всё всем).
Phase 1.3.4 (Per-unit stock tagging) + Phase 1.10 (Sales App filtering) + Phase 1.4.12 (Stock allocation conflict reconciliation) — все depend on stock allocation architecture.
Decision
Stock allocation model = S·1 (Subset-1) с Closed pool default + per-project Open mode toggle.
Closed pool mode (default — Foundational §4.4)
- Guest organisations (приглашённые Studio как Free Guest per ADR 0008) видят 0 юнитов пока им явно не assigned.
- Owner Organisation team — Sales Manager / Admin / Owner видят все units (privileged tier). Content Editor видит все units regardless of allocation (content access ≠ sales access). Sales Agent видит только assigned.
- Per-project setting в Project Settings UI (рядом с Public Visibility per Foundational §5).
Open pool mode (opt-in — Foundational §4.4)
- Гости видят общий «Internal pool» (как у брокеров в open competition models — multiple agencies на shared inventory).
- First-click-wins на reserve action (per Phase 1.10 + Foundational §7.4 Edge case).
- Optimistic lock + 409 Conflict modal с timestamp + audit log обоих attempts.
S·1 visibility rules (3 sub-rules — CONV-16 Learning)
- Owner / Admin / Sales Manager always sees all units (privileged — assignment never hides from owner-team).
- Content Editor sees all units regardless of allocation (content access ≠ sales access — separate concerns).
- On target removal escalate up to Manager/Admin — NEVER auto-revert to «shared» mode (prevents accidental «everyone can sell» mistakes).
Locking strategy
- Pessimistic lock on reserve action — when Sales Agent clicks "Reserve", DB transaction lock'ит unit row, validates allocation (S·1 check) + status (must be
available), then writesreserved+ setsreserved_by_user_id. - No reservation TTL (per CONV-18 simplification) — Partner manages reservation в own external CRM. Our admin offers manual unit status flips (available ↔ reserved ↔ sold).
- Conflict reconciliation — Phase 1.4.12 operator dashboard task для bug recovery (admin error, two Orgs claiming one unit).
Bulk allocation UX (CONV-16 Learning)
Stage 1: filter list + multi-select checkboxes + dropdown «Assign to» (Organisation / specific user). Not CSV import (AI file upload at Phase 1.5.6 covers structured import path).
Alternatives Considered
- Open-by-default (Shared default) — rejected (CONV-18). Original design (per CONV-16 interview) but переоценено: Closed default лучше matches off-plan industry pattern где studios cautious about revealing pricing к external agents. Open mode остаётся как opt-in для those who want it.
- Per-unit ACL (no defaults) — rejected. Too operationally expensive (admin assigns каждый unit individually); Closed pool + bulk allocation UX покрывает 95% workflow без friction.
- No allocation system (everyone sees everything) — rejected. Не решает double-sale risk + commercial confidentiality requirement.
- Multi-allocation (one unit assigned to multiple parties) — rejected for Stage 1. Increases double-sale risk, requires conflict-resolution UI. Stage 2 если demand.
Consequences
- Phase 1.3.4 (Per-unit stock tagging) implements DB schema:
unit_assignmentstable (unit_id × target_id × target_type[org|user]). - Phase 1.10 (Sales App filtering) middleware — stock allocation filter применяется после auth-scoped view rendering (per ADR 0009).
- Phase 1.4.12 (Stock allocation conflict reconciliation) — operator dashboard для admin-error recovery.
- Cross-references:
- ADR 0009 — provides Sales Agent role + Internal/External split + entity model.
- ADR 0008 — Open pool mode может быть Tier 2+ feature (TBD в sub-plan ratification).
- Sub-plan
plans/permission-and-tenancy-model.md— DB schema + API contracts.
Revisit trigger
- Multi-allocation demand (3+ studios request) → revisit с conflict-resolution UI design.
- CSV import for stock allocation demand → expand AI file upload (Phase 1.5.6) to handle structured assignment.
- Reservation TTL demand (если studios complain about manual unit status management) → reservation timer Stage 2.