Skip to content

Build friendship lifecycle backend foundation - #193

Merged
coder13 merged 4 commits into
masterfrom
agent/issue-75-friendship-lifecycle
Jul 14, 2026
Merged

Build friendship lifecycle backend foundation#193
coder13 merged 4 commits into
masterfrom
agent/issue-75-friendship-lifecycle

Conversation

@coder13

@coder13 coder13 commented Jul 13, 2026

Copy link
Copy Markdown
Owner

Summary

  • canonical MongoDB relationship state and directional blocks, with authenticated lifecycle REST actions
  • public identity projection only: this feature never accepts, searches, returns, logs, or measures email
  • revisioned MongoDB tombstones and strictly newer PostgreSQL mirrors prevent delayed writes from resurrecting friendships or blocks
  • opaque Redis/Socket.IO invalidations, with REST reconciliation as the durable client contract
  • disabled-by-default HTTP and realtime surface behind SOCIAL_FEATURES_ENABLED

Request-creation limits

This replaces the former pending-request quota/reservation design. Redis atomically limits new requests to 30 per actor per 10 minutes and 3 per normalized pair per 24 hours. A Lua script checks both counters before incrementing either and assigns fixed TTLs, so it works across API processes and crashes leave no durable reservation or cleanup work. Redis failure is fail-closed (503 request_rate_limit_unavailable); a reached limit is 429 request_rate_limited with a retry time. Existing cancel/decline pair cooldowns remain.

Review hardening

  • block/unblock remains fail-closed: relationship cleanup completes before block deactivation
  • request creation is bounded by the atomic Redis limiter rather than an exact pending-count cap that could leak after a crash
  • MongoDB tombstones plus strictly newer PostgreSQL mirrors prevent reordered writes from restoring relationships or blocks
  • durable relationship/block transitions immediately mirror and invalidate; no quota reconciliation can suppress their side effects

Dependencies and remaining work

Merge order is #192 / #191 → #185 → this PR; rebase before it is ready. This remains backend foundation only: client invalidation/reconnect reconciliation belongs to #186 and room invitations to #187.

Validation

  • yarn lint
  • yarn test (server: 21 suites / 121 tests; client: 14 suites / 82 tests; scrambles: 1 suite / 22 tests)
  • git diff --check
  • focused tests cover concurrent cross-pair user limits, pair-window expiry, Redis failure, and fail-closed service behavior

A fresh-database prisma migrate deploy was not run locally because the available Lets Cube PostgreSQL container belongs to another active worktree; CI exercises the committed migration against isolated PostgreSQL 17.

coder13 added 4 commits July 12, 2026 20:51
Add server-authorized friendship and blocking transitions, privacy-safe REST and realtime contracts, and non-blocking PostgreSQL mirrors. Document the state machine and cover concurrency, replay, blocking, privacy, metrics, and disabled-Postgres behavior.
Gate social routes and realtime delivery behind the disabled-by-default rollout flag. Keep relationship and block tombstones revisioned for fail-closed unblock and reordered PostgreSQL mirrors, and reserve pending-request quota atomically with rollback and stale reconciliation.
Keep in-flight quota reservations counted until their relationship write resolves, and make quota cleanup asynchronous after durable social transitions so mirrors and invalidations are never suppressed by maintenance failures.
Use an atomic, expiring Redis limiter for per-user and per-pair friend request creation so crashes cannot leak durable quota reservations or suppress relationship side effects.
@coder13
coder13 merged commit 7c102a2 into master Jul 14, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant