fix(startup): populate applications.webhook_url for mokosh from MOKOSH_WEBHOOK_URL #326

Merged
YousifShkara merged 1 commit from fix/BUNYIP-336-mokosh-webhook-url-upsert into main 2026-07-03 14:03:49 +02:00
Owner

Bunyip's fan_out_account_deleted (bunyip-api/src/handlers/user.rs:694-721) iterates active applications and skips any row with a null-or-empty webhook_url:

if app.webhook_url.as_deref().is_none_or(str::is_empty) {
    continue;
}

The mokosh application row was seeded by 20260603000020_seed_mokosh_hosted_application.sql without a webhook_url column in its INSERT list, so the value defaulted to NULL and stayed NULL. Every account_deleted dispatch since PMS-591 + BUNYIP-211 shipped therefore silently skipped mokosh: bunyip's log recorded no delivery, mokosh-server received no event, users.deleted_at on the mokosh side stayed NULL, and the SPA (MAPPS-355 heartbeat + MAPPS-348 overlay + PMS-591 receiver, all merged) sat idle waiting for the 410 that the receiver was never told to produce. Users saw mokosh keep working end-to-end after a Bunyip account delete.

Populate the URL from MOKOSH_WEBHOOK_URL at startup, using the same env-driven-upsert pattern the existing OIDC-client registrations use (upsert_spa_oidc_client, upsert_lets_chat_oidc_client). Staging and production hit different receiver hosts (api.msp.a8n.systems vs api.msp.psa.systems), so a per-env value in a migration would have to hardcode one, and CLAUDE.md's immutable-migrations rule forbids editing the seed after the fact. Env-driven upsert covers both hosts through one code path and lands the value where operators expect (compose-variables.yml, alongside MOKOSH_APPS_REDIRECT_URIS).

Behaviour when env is unset (dev, self-host, misconfigured deploy): log at info and return Ok. Dev boot without the compose env keeps working; there is no local mokosh to dispatch to. When set but the mokosh row is missing (probably a botched migration state, not a normal scenario): warn and continue - do not fail bunyip-api boot on a bad seed.

Deployment side (compose-variables.yml on c-01 and nc-01, plus the template comment) ships as a separate docker-repo PR that references BUNYIP-336; both need to land for the URL to actually reach production, but they can merge independently and in either order (bunyip startup will just log-and-skip until the docker env var lands).

#BUNYIP-336

Bunyip's `fan_out_account_deleted` (`bunyip-api/src/handlers/user.rs:694-721`) iterates active applications and skips any row with a null-or-empty `webhook_url`: if app.webhook_url.as_deref().is_none_or(str::is_empty) { continue; } The mokosh application row was seeded by `20260603000020_seed_mokosh_hosted_application.sql` without a `webhook_url` column in its INSERT list, so the value defaulted to NULL and stayed NULL. Every account_deleted dispatch since PMS-591 + BUNYIP-211 shipped therefore silently skipped mokosh: bunyip's log recorded no delivery, mokosh-server received no event, `users.deleted_at` on the mokosh side stayed NULL, and the SPA (MAPPS-355 heartbeat + MAPPS-348 overlay + PMS-591 receiver, all merged) sat idle waiting for the 410 that the receiver was never told to produce. Users saw mokosh keep working end-to-end after a Bunyip account delete. Populate the URL from `MOKOSH_WEBHOOK_URL` at startup, using the same env-driven-upsert pattern the existing OIDC-client registrations use (`upsert_spa_oidc_client`, `upsert_lets_chat_oidc_client`). Staging and production hit different receiver hosts (`api.msp.a8n.systems` vs `api.msp.psa.systems`), so a per-env value in a migration would have to hardcode one, and CLAUDE.md's immutable-migrations rule forbids editing the seed after the fact. Env-driven upsert covers both hosts through one code path and lands the value where operators expect (compose-variables.yml, alongside `MOKOSH_APPS_REDIRECT_URIS`). Behaviour when env is unset (dev, self-host, misconfigured deploy): log at info and return Ok. Dev boot without the compose env keeps working; there is no local mokosh to dispatch to. When set but the mokosh row is missing (probably a botched migration state, not a normal scenario): warn and continue - do not fail bunyip-api boot on a bad seed. Deployment side (compose-variables.yml on c-01 and nc-01, plus the template comment) ships as a separate docker-repo PR that references BUNYIP-336; both need to land for the URL to actually reach production, but they can merge independently and in either order (bunyip startup will just log-and-skip until the docker env var lands). #BUNYIP-336
fix(startup): populate applications.webhook_url for mokosh from MOKOSH_WEBHOOK_URL
All checks were successful
E2E / Playwright against deployment (pull_request) Successful in 36s
Check / fmt + clippy + build + tests (pull_request) Successful in 15m47s
Create release / Create release from merged PR (pull_request) Has been skipped
e3e797cbb5
Bunyip's `fan_out_account_deleted` (`bunyip-api/src/handlers/user.rs:694-721`) iterates active applications and skips any row with a null-or-empty `webhook_url`:

    if app.webhook_url.as_deref().is_none_or(str::is_empty) {
        continue;
    }

The mokosh application row was seeded by `20260603000020_seed_mokosh_hosted_application.sql` without a `webhook_url` column in its INSERT list, so the value defaulted to NULL and stayed NULL. Every account_deleted dispatch since PMS-591 + BUNYIP-211 shipped therefore silently skipped mokosh: bunyip's log recorded no delivery, mokosh-server received no event, `users.deleted_at` on the mokosh side stayed NULL, and the SPA (MAPPS-355 heartbeat + MAPPS-348 overlay + PMS-591 receiver, all merged) sat idle waiting for the 410 that the receiver was never told to produce. Users saw mokosh keep working end-to-end after a Bunyip account delete.

Populate the URL from `MOKOSH_WEBHOOK_URL` at startup, using the same env-driven-upsert pattern the existing OIDC-client registrations use (`upsert_spa_oidc_client`, `upsert_lets_chat_oidc_client`). Staging and production hit different receiver hosts (`api.msp.a8n.systems` vs `api.msp.psa.systems`), so a per-env value in a migration would have to hardcode one, and CLAUDE.md's immutable-migrations rule forbids editing the seed after the fact. Env-driven upsert covers both hosts through one code path and lands the value where operators expect (compose-variables.yml, alongside `MOKOSH_APPS_REDIRECT_URIS`).

Behaviour when env is unset (dev, self-host, misconfigured deploy): log at info and return Ok. Dev boot without the compose env keeps working; there is no local mokosh to dispatch to. When set but the mokosh row is missing (probably a botched migration state, not a normal scenario): warn and continue - do not fail bunyip-api boot on a bad seed.

Deployment side (compose-variables.yml on c-01 and nc-01, plus the template comment) ships as a separate docker-repo PR that references BUNYIP-336; both need to land for the URL to actually reach production, but they can merge independently and in either order (bunyip startup will just log-and-skip until the docker env var lands).

#BUNYIP-336
YousifShkara deleted branch fix/BUNYIP-336-mokosh-webhook-url-upsert 2026-07-03 14:03:50 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/bunyip!326
No description provided.