coder13 / coder13/LetsCube

Build the friend request, friendship, and blocking lifecycle

Open
#75 0 comments 0 reactions 1 assignee Claimed by @coder13 View on GitHub
area: auth area: data area: social enhancement priority: P1
Dominant language
JavaScript
Stars
30
Forks
9
PR merge metrics
No merged PRs in 30d

Description

## Goal

Create the durable, server-authorized relationship model that every Friend System surface can depend on.

## Product contract

Authenticated users can:

- send a friend request;
- cancel their own outgoing request;
- accept or decline an incoming request;
- list accepted friends and incoming/outgoing requests;
- unfriend someone;
- block or unblock another user.

State transitions must be idempotent. A crossed request may become an accepted friendship instead of creating two requests. Self-requests, duplicate relationships, blocked pairs, and unauthorized transitions are rejected consistently.

Blocking is directional and overrides friendship state:

- blocking removes any accepted friendship between the pair;
- pending friend requests and room invitations between the pair become non-actionable;
- the blocked user cannot send new requests or invitations;
- APIs do not reveal whether a block exists.

## Data and API design

- Store one canonical relationship per unordered user pair using a normalized pair key and a unique index.
- Keep directional blocks separate from the symmetric friendship so future policy stays understandable.
- MongoDB remains the source of truth; add backward-compatible Prisma models and non-blocking PostgreSQL mirrors from the first enabled write.
- Notifications reference relationship/request resources but are not the relationship source of truth.
- Use authenticated REST operations for durable state changes; Socket.IO may announce changes to the affected users but must not own them.
- Return explicit public user projections. Never use, return, search, log, or retain email; #191 is a prerequisite.

## Acceptance criteria

- [ ] Document the relationship state machine, invariants, conflict responses, and any resend cooldown.
- [ ] Add MongoDB schemas/indexes and corresponding backward-compatible PostgreSQL migrations/mirrors.
- [ ] Implement authenticated list/create/cancel/accept/decline/unfriend/block/unblock operations.
- [ ] Enforce server-side authorization, per-user/per-pair limits, idempotency, and concurrency-safe unique-pair behavior.
- [ ] Emit typed realtime invalidation/update events to both users' existing per-user rooms.
- [ ] Reconcile state from REST after reconnect so missed realtime events do not corrupt the UI.
- [ ] Add tests for crossed requests, duplicate/replayed actions, concurrent accepts, self-actions, blocking, unblocking, unfriending, ID tampering, and disabled PostgreSQL.
- [ ] Add privacy-safe metrics for request/accept/decline/block outcomes without recording graph edges or identity.

## Dependencies

- #191 stop retaining WCA email addresses

## Launch gate

- #188 hardening must pass before broad enablement; it does not block building this foundation.

## Non-goals

- Direct messages (#189).
- Stranger recommendations or matching (#190).
- Browser push notifications.
- Room invitations (#187), which consume this relationship API.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.