Skip to content

Mongo↔PG membership/user drift: join paths don't mirror to pod_members (real members 403'd) #747

Description

@lilyshen0722

Problem

Membership and user rows drift between MongoDB (source of truth) and PostgreSQL (chat mirror). Surfaced 2026-07-24: Commonly HQ had 66 Mongo pod.members but only 1 in PG pod_members, so 65/66 members 403'd on reactions (fixed for reactions via a Mongo fallback in #746 + a one-off backfill; this issue tracks the root).

Two drifts:

  1. pod_members: ensureUserInCommunityPod (HQ auto-join) and likely other join paths (invite redeem, etc.) write Mongo pod.members but never mirror to PG pod_members. Any PG-gated access/read check then mis-treats real members as non-members.
  2. users: registration creates the Mongo user but doesn't sync to PG users — 5 HQ members aren't in PG users at all (the message path lazily backfills on first message; fix(register): mirror the default workspace pod into Postgres #743 fixed this for the auto-workspace pod, not users generally). PG-user-dependent features (message author render) show these as "Unknown" until they send a message.

Why it matters

Anything gating on PG (callerHasPodAccess's human path did, before #746; possibly other reaction/message/read checks) silently mistreats members. The failures are invisible when the caller swallows errors.

Options

  • Mirror on write: ensureUserInCommunityPod + join paths call PGPod.addMember (and syncUserToPostgreSQL) like createPod does. Correct data, but every join path must remember.
  • Mongo-as-truth for access: PG-gated access checks fall back to Mongo membership (what fix(reactions): human pod-access falls back to Mongo membership (PG pod_members drift) #746 did for reactions). Robust, but per-check.
  • Reconciliation sweep: periodic job backfilling PG pod_members/users from Mongo. Catches drift regardless of path.

Recommend Mongo-fallback for access checks (done for reactions) + a reconciliation sweep, and audit other PG-gated reads for the same 403-real-members risk.

Acceptance

  • A member in Mongo pod.members is never 403'd by a PG-gated check.
  • New community/invite joins land in PG pod_members.
  • Registration users reachable in PG (or all PG reads tolerate their absence).

Context: reaction 403 incident, #746 / #743.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions