Flick Knowledge Base
Repository docs from .qoder/repowiki
Search, browse, and read the generated project wiki without leaving the repo.
Blocking System
Referenced Files in This Document
block.guard.tsuser.service.tsuser.controller.tsuser.route.tsuser.schema.tsuser.repo.tsuser.adapter.tsuser-block.table.tspost.service.tscomment.service.ts0000_snapshot.json0001_snapshot.json0002_snapshot.json0003_snapshot.json0005_snapshot.jsonuser-moderation.service.ts
Table of Contents
Introduction
This document explains the user blocking and unblocking system in the platform. It covers the block guard implementation, user blocking relationships, privacy enforcement mechanisms, block/unblock API endpoints, database schema for user blocks, real-time blocking updates, workflow, user experience implications, and integration with posts and comments. It also includes examples of blocking scenarios, permission checks, and blocking state management.
Project Structure
The blocking system spans the user module (controller, service, guard, repo), database adapters and tables, and integrations with posts and comments services. The routing layer exposes endpoints for blocking, unblocking, and listing blocked users.
graph TB
subgraph "User Module"
UC["UserController<br/>routes: /block/:userId, /unblock/:userId, /blocked"]
US["UserService<br/>blockUser, unblockUser, getBlockedUsers"]
UB["BlockGuard<br/>assertNoBlockRelationBetweenUsers"]
UR["UserRepo<br/>Read, Write, Blocks"]
end
subgraph "Database Layer"
UA["UserAdapter<br/>createBlock, removeBlock,<br/>getBlockedUsers, hasBlockRelation"]
UT["user_blocks table<br/>blocker_id, blocked_id"]
end
subgraph "Integration"
PS["PostService<br/>uses BlockGuard"]
CS["CommentService<br/>uses BlockGuard"]
end
UC --> US
US --> UR
UR --> UA
UA --> UT
PS --> UB
CS --> UBDiagram sources
user.controller.tsuser.service.tsblock.guard.tsuser.repo.tsuser.adapter.tsuser-block.table.tspost.service.tscomment.service.ts
Section sources
user.controller.tsuser.route.tsuser.service.tsblock.guard.tsuser.repo.tsuser.adapter.tsuser-block.table.tspost.service.tscomment.service.ts
Core Components
- Block Guard: Enforces privacy by preventing interactions between blocked users.
- User Controller: Exposes endpoints for blocking, unblocking, and listing blocked users.
- User Service: Implements business logic for block/unblock operations and retrieving blocked users.
- User Repo and Adapter: Provide read/write access to user data and block relationships.
- Database Schema: Defines the user_blocks table with foreign keys and uniqueness constraints.
- Integrations: PostService and CommentService use the block guard to enforce privacy during reads and writes.
Section sources
block.guard.tsuser.controller.tsuser.service.tsuser.repo.tsuser.adapter.tsuser-block.table.tspost.service.tscomment.service.ts
Architecture Overview
The blocking system follows a layered architecture:
- Presentation: Routes define endpoints for blocking operations.
- Application: Controllers delegate to services.
- Domain: Services encapsulate business rules and call repository adapters.
- Persistence: Adapters interact with the database via Drizzle ORM.
- Integration: Post and comment services enforce block relationships during content operations.
sequenceDiagram
participant Client as "Client"
participant Router as "UserRoute"
participant Controller as "UserController"
participant Service as "UserService"
participant Repo as "UserRepo"
participant Adapter as "UserAdapter"
participant DB as "Database"
Client->>Router : POST /user/block/ : userId
Router->>Controller : blockUser(userId)
Controller->>Service : blockUser(requestingUserId, targetUserId)
Service->>Repo : Read.findById for requester and target
Service->>Adapter : createBlock(blockerId, blockedId)
Adapter->>DB : INSERT INTO user_blocks
DB-->>Adapter : RETURNING created row
Adapter-->>Service : created block
Service-->>Controller : { blocked : true }
Controller-->>Client : OK { blocked : true }Diagram sources
user.route.tsuser.controller.tsuser.service.tsuser.adapter.ts
Detailed Component Analysis
Block Guard Implementation
The block guard enforces privacy by asserting that two users are not mutually blocking before allowing interactions. It performs:
- Self-check bypass (user cannot block themselves).
- Parallel lookup of requester and target users.
- Block relation check using the adapter’s hasBlockRelation.
- Throws appropriate errors when users are blocked or not found.
flowchart TD
Start(["assertNoBlockRelationBetweenUsers"]) --> SelfCheck{"requester === target?"}
SelfCheck --> |Yes| ReturnOK["Return (no-op)"]
SelfCheck --> |No| FetchUsers["Fetch requester and target"]
FetchUsers --> UsersFound{"Both users found?"}
UsersFound --> |No| ThrowNotFound["Throw USER_NOT_FOUND"]
UsersFound --> |Yes| CheckRelation["Check hasBlockRelation(authIds)"]
CheckRelation --> Blocked{"Relation exists?"}
Blocked --> |Yes| ThrowForbidden["Throw USER_INTERACTION_BLOCKED"]
Blocked --> |No| ReturnOKDiagram sources
block.guard.tsuser.adapter.ts
Section sources
block.guard.tsuser.adapter.ts
User Blocking Relationships
The system stores blocking relationships in a dedicated table with:
- Unique constraint on (blocker_id, blocked_id) to prevent duplicates.
- Foreign keys referencing the auth table with cascade deletion.
- Convenience methods to fetch blocked users and check bidirectional relations.
erDiagram
AUTH {
text id PK
}
USER_BLOCKS {
uuid id PK
text blocker_id FK
text blocked_id FK
timestamp created_at
}
AUTH ||--o{ USER_BLOCKS : "blocks"
AUTH ||--o{ USER_BLOCKS : "blocked_by"Diagram sources
user-block.table.ts0000_snapshot.json0001_snapshot.json0002_snapshot.json0003_snapshot.json0005_snapshot.json
Section sources
user-block.table.tsuser.adapter.ts0000_snapshot.json0001_snapshot.json0005_snapshot.json
Privacy Enforcement Mechanisms
Privacy enforcement occurs at multiple layers:
- Block Guard prevents interactions between blocked users in posts and comments.
- PostService and CommentService invoke the block guard when fetching content or creating comments.
- Uniqueness in user_blocks ensures idempotent block operations.
Section sources
post.service.tscomment.service.tsuser.adapter.ts
Block/Unblock API Endpoints
Endpoints exposed by the user route:
- POST /user/block/:userId — blocks the specified user
- POST /user/unblock/:userId — unblocks the specified user
- GET /user/blocked — lists users blocked by the current user
Middleware applied:
- Rate limiting
- Authentication
- User injection and onboarding requirement
Validation:
- userIdSchema validates presence of userId parameter.
Section sources
user.route.tsuser.schema.tsuser.controller.ts
Database Schema for User Blocks
The user_blocks table defines:
- Primary key id
- Non-null blocker_id and blocked_id
- Timestamp created_at with default now()
- Unique index on (blocker_id, blocked_id)
- Foreign keys referencing auth.id with cascade delete
Migrations show evolution of the schema and foreign key constraints.
Section sources
user-block.table.ts0000_snapshot.json0001_snapshot.json0002_snapshot.json0003_snapshot.json0005_snapshot.json
Real-Time Blocking Updates
Real-time updates are not implemented in the blocking subsystem. Blocking state changes are reflected immediately upon subsequent requests after successful block/unblock operations. No WebSocket events or cache invalidation patterns are present for blocking in the analyzed code.
[No sources needed since this section provides general guidance]
Blocking Workflow
End-to-end workflow for blocking:
- Client sends POST /user/block/:userId.
- Route applies middleware and authenticates the request.
- Controller delegates to UserService.
- Service validates self-blocking, looks up users, and persists the block via UserAdapter.
- Adapter inserts into user_blocks with conflict handling.
- Controller returns success with { blocked: true }.
Unblocking mirrors this with removal logic.
sequenceDiagram
participant Client as "Client"
participant Router as "UserRoute"
participant Controller as "UserController"
participant Service as "UserService"
participant Adapter as "UserAdapter"
participant DB as "Database"
Client->>Router : POST /user/unblock/ : userId
Router->>Controller : unblockUser(userId)
Controller->>Service : unblockUser(requestingUserId, targetUserId)
Service->>Adapter : removeBlock(blockerId, blockedId)
Adapter->>DB : DELETE FROM user_blocks WHERE blockerId AND blockedId
DB-->>Adapter : RETURNING deleted row
Adapter-->>Service : deleted block
Service-->>Controller : { blocked : false }
Controller-->>Client : OK { blocked : false }Diagram sources
user.route.tsuser.controller.tsuser.service.tsuser.adapter.ts
Section sources
user.controller.tsuser.service.tsuser.adapter.ts
User Experience Implications
- Blocking prevents the blocked user from initiating interactions (e.g., commenting on posts authored by the blocker).
- Blocked users are not visible in search results or lists that rely on the blocking guard.
- Unblocking restores normal interaction capabilities.
Section sources
block.guard.tscomment.service.tspost.service.ts
Integration with Posts and Comments
- PostService: Invokes assertNoBlockRelationBetweenUsers when fetching a post by ID to ensure the requester cannot view content from a blocked author.
- CommentService:
- Enforces block guard when fetching comments by post ID and when creating comments (including replies).
- Validates parent comment relationships while respecting block constraints.
sequenceDiagram
participant Client as "Client"
participant PostSvc as "PostService"
participant Guard as "BlockGuard"
participant PostRepo as "PostRepo"
participant CommentSvc as "CommentService"
Client->>PostSvc : getPostById(postId, { id })
PostSvc->>Guard : assertNoBlockRelationBetweenUsers(userId, postedBy)
Guard-->>PostSvc : ok or throws
PostSvc->>PostRepo : findByIdWithDetails
PostRepo-->>PostSvc : post
PostSvc-->>Client : post
Client->>CommentSvc : createComment({ postId, commentedBy, parentCommentId? })
CommentSvc->>Guard : assertNoBlockRelationBetweenUsers(commentedBy, post.postedBy)
alt Has parent
CommentSvc->>Guard : assertNoBlockRelationBetweenUsers(commentedBy, parent.commentedBy)
end
CommentSvc-->>Client : created commentDiagram sources
post.service.tsblock.guard.tscomment.service.ts
Section sources
post.service.tscomment.service.ts
Examples of Blocking Scenarios
- Scenario 1: Alice blocks Bob
- Alice cannot view Bob’s posts or comments.
- Creating comments on posts authored by Bob fails if the block guard triggers.
- Scenario 2: Carol replies to a comment by Dave
- If Carol is blocked by Dave, the reply creation is denied.
- If Carol is blocked by the original post author, the reply creation is denied.
- Scenario 3: Eve attempts to block herself
- The service rejects self-blocking with a bad request error.
Section sources
user.service.tscomment.service.tspost.service.ts
Permission Checks and Blocking State Management
- Permission checks:
- Self-block prevention in UserService.
- Not-found errors when users are missing.
- Forbidden errors when a block relationship exists.
- Blocking state management:
- Idempotent block creation via conflict handling.
- Explicit removal of block records.
- Bidirectional relation detection for privacy enforcement.
Section sources
user.service.tsuser.adapter.tsuser.adapter.ts
Moderation Integration
The moderation subsystem includes user blocking/unblocking operations separate from the user blocking system described here. These are administrative actions that operate on user accounts directly.
Section sources
user-moderation.service.ts
Dependency Analysis
The blocking system exhibits low coupling and high cohesion:
- Controllers depend on Services.
- Services depend on Repositories and Adapters.
- Adapters depend on the database schema and ORM.
- Post and Comment services depend on the BlockGuard for privacy enforcement.
graph LR
UC["UserController"] --> US["UserService"]
US --> UR["UserRepo"]
UR --> UA["UserAdapter"]
UA --> UT["user_blocks table"]
PS["PostService"] --> BG["BlockGuard"]
CS["CommentService"] --> BG
BG --> URDiagram sources
user.controller.tsuser.service.tsuser.repo.tsuser.adapter.tsuser-block.table.tspost.service.tscomment.service.tsblock.guard.ts
Section sources
user.controller.tsuser.service.tsuser.repo.tsuser.adapter.tsuser-block.table.tspost.service.tscomment.service.tsblock.guard.ts
Performance Considerations
- Database-level uniqueness on (blocker_id, blocked_id) prevents duplicate entries and supports efficient lookups.
- hasBlockRelation uses OR conditions with AND subqueries; ensure appropriate indexing for authId columns.
- Caching layers in UserRepo and adapters reduce repeated lookups for user data.
- Parallel fetching of requester and target users minimizes latency in the block guard.
[No sources needed since this section provides general guidance]
Troubleshooting Guide
Common issues and resolutions:
- User not found: Occurs when requester or target does not exist; verify user IDs and authentication state.
- Self-block attempted: The service explicitly rejects self-blocking; ensure clients prevent this scenario.
- Interaction blocked: When a forbidden error is returned, confirm that the block relationship exists and needs to be removed.
- Duplicate block operation: Block creation is idempotent; no error is thrown on duplicate attempts.
Section sources
user.service.tsuser.adapter.tsblock.guard.ts
Conclusion
The blocking system provides robust privacy enforcement through a dedicated guard, a normalized database schema, and integration with posts and comments services. It prevents interactions between blocked users, supports idempotent block operations, and maintains clear separation of concerns across layers. Administrators can manage user account states separately via the moderation subsystem.