fix(tenancies): unblock first-tenancy chicken-and-egg in webhook
Webhook auto-create on signed Reservation Agreement was gating itself on isTenanciesModuleEnabled, but autoCreatePendingTenancies never enabled the module — so the very first tenancy on a fresh port was unreachable even though the row-exists fallback in isTenanciesModuleEnabled was designed exactly for this lazy auto-surface case. Drop the gate; the inserted row now flips the module on automatically via the fallback. docs/tenancies-design.md §"When disabled" and the P3 PR-table row updated to reflect the new contract. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -680,11 +680,12 @@ export interface AutoCreateOptions {
|
||||
* then confirms start date + tenure type via the entity-tab UI to flip
|
||||
* `pending → active`.
|
||||
*
|
||||
* Caller is responsible for gating on `isTenanciesModuleEnabled(portId)` —
|
||||
* this function does NOT check the flag itself (per design line 132: the
|
||||
* webhook caller short-circuits when the module is off). Service-level
|
||||
* idempotency: skips any berth that already has a non-terminal tenancy in
|
||||
* `(pending, active)` so a webhook re-delivery never double-mints.
|
||||
* The webhook caller does not gate on `isTenanciesModuleEnabled` — the
|
||||
* row-exists fallback in that helper lazily surfaces the module from the
|
||||
* first successful insert onwards, which is what unlocks the very first
|
||||
* tenancy on a fresh port. Service-level idempotency: skips any berth that
|
||||
* already has a non-terminal tenancy in `(pending, active)` so a webhook
|
||||
* re-delivery never double-mints.
|
||||
*
|
||||
* Returns the newly-inserted rows (empty array when nothing to mint).
|
||||
*/
|
||||
|
||||
@@ -1683,15 +1683,13 @@ export async function handleDocumentCompleted(eventData: { documentId: string; p
|
||||
evaluateRule('contract_signed', doc.interestId!, doc.portId, systemMeta),
|
||||
);
|
||||
|
||||
// Tenancies P3 — auto-create pending tenancies (one per in-bundle berth)
|
||||
// when the module is enabled for this port. Gating is at the call site:
|
||||
// disabled module = stage + docStatus updates still fire, only the
|
||||
// tenancy mint is skipped (per docs/tenancies-design.md §"When disabled").
|
||||
// Tenancies P3 — auto-create pending tenancies (one per in-bundle berth).
|
||||
// No module gate here: the row-exists fallback in `isTenanciesModuleEnabled`
|
||||
// lazily surfaces the module after the first signing, which is exactly what
|
||||
// we want for the first-ever Reservation Agreement on a fresh port. Admins
|
||||
// can still pre-enable the module to make widgets/sidebar appear earlier.
|
||||
void (async () => {
|
||||
try {
|
||||
const { isTenanciesModuleEnabled } =
|
||||
await import('@/lib/services/tenancies-module.service');
|
||||
if (!(await isTenanciesModuleEnabled(doc.portId))) return;
|
||||
const { autoCreatePendingTenancies } =
|
||||
await import('@/lib/services/berth-tenancies.service');
|
||||
// Re-read signedFileId from the post-commit row; the in-tx update
|
||||
|
||||
Reference in New Issue
Block a user