Skip to content

feat: add user blocking functionality and related database changes#2598

Closed
baktun14 wants to merge 2 commits intomainfrom
features/block-user
Closed

feat: add user blocking functionality and related database changes#2598
baktun14 wants to merge 2 commits intomainfrom
features/block-user

Conversation

@baktun14
Copy link
Copy Markdown
Contributor

@baktun14 baktun14 commented Jan 29, 2026

Summary by CodeRabbit

Release Notes

  • New Features
    • Added user blocking/unblocking capability through new API endpoints
    • Blocked users are restricted to read-only access; state-changing operations return error responses
    • User deployments automatically close when an account is blocked

✏️ Tip: You can customize this high-level summary in your review settings.

@baktun14 baktun14 requested a review from a team as a code owner January 29, 2026 02:04
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 29, 2026

📝 Walkthrough

Walkthrough

Introduces user blocking functionality by adding an is_blocked column to the database, creating block/unblock user API routes, implementing a request interceptor to deny non-safe requests from blocked users, and adding a background job to automatically close deployments for blocked users.

Changes

Cohort / File(s) Summary
Database Schema
apps/api/drizzle/0028_shocking_gabe_jones.sql, apps/api/drizzle/meta/0028_snapshot.json, apps/api/drizzle/meta/_journal.json
Adds is_blocked column to userSetting table with default value false, updates schema snapshot, and records migration in journal.
User Model & Repository
apps/api/src/user/model-schemas/user/user.schema.ts, apps/api/src/user/repositories/user/user.repository.ts
Adds isBlocked field to Users table schema and implements blockUser() and unblockUser() repository methods.
User Management Routes
apps/api/src/routes/internal/users.ts, apps/api/src/routes/internal/index.ts
Introduces /users/{userId}/block and /users/{userId}/unblock endpoints that update user blocking status and trigger deployment closure job.
Request Blocking Interceptor
apps/api/src/auth/services/blocked-user.interceptor.ts, apps/api/src/rest-app.ts
Adds BlockedUserInterceptor to reject non-safe HTTP requests from blocked users with Forbidden response.
Routing & Middleware
apps/api/src/routers/internalRouter.ts
Registers privateMiddleware for /users/* routes.
Background Job Processing
apps/api/src/app/services/close-blocked-user-deployments/close-blocked-user-deployments.handler.ts, apps/api/src/app/providers/jobs.provider.ts, apps/api/src/core/services/job-queue/job-queue.service.ts
Implements CloseBlockedUserDeploymentsHandler job that retrieves user deployments and closes them when a user is blocked; adds handler to job initialization and extends job context with isBlocked flag.
Testing
apps/api/test/seeders/user.seeder.ts
Updates user seeder to include isBlocked field with default false.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant API as Block User API
    participant UserRepo as UserRepository
    participant DB as Database
    participant JobQueue as JobQueueService
    
    Client->>API: POST /users/{userId}/block
    API->>UserRepo: blockUser(userId)
    UserRepo->>DB: UPDATE userSetting SET is_blocked=true
    DB-->>UserRepo: Updated User
    UserRepo-->>API: UserOutput
    API->>JobQueue: enqueue(CloseBlockedUserDeployments)
    JobQueue-->>API: Job scheduled
    API-->>Client: {id, isBlocked: true}
Loading
sequenceDiagram
    participant Client
    participant BlockedUserInterceptor
    participant ExecutionContextService
    participant NextHandler
    
    Client->>BlockedUserInterceptor: Request (POST/DELETE/etc.)
    BlockedUserInterceptor->>ExecutionContextService: Get CURRENT_USER
    ExecutionContextService-->>BlockedUserInterceptor: currentUser with isBlocked flag
    alt User is blocked & method is not safe
        BlockedUserInterceptor-->>Client: 403 Forbidden (User is blocked)
    else User is not blocked OR method is safe (GET/HEAD/OPTIONS)
        BlockedUserInterceptor->>NextHandler: pass to next middleware
        NextHandler-->>Client: Process request normally
    end
Loading
sequenceDiagram
    participant JobQueue
    participant CloseBlockedUserDeploymentsHandler
    participant UserWalletRepo as UserWalletRepository
    participant DeploymentReader
    participant DeploymentWriter
    participant Logger
    
    JobQueue->>CloseBlockedUserDeploymentsHandler: handle(payload: userId)
    CloseBlockedUserDeploymentsHandler->>UserWalletRepo: findByUserId(userId)
    alt Wallet not found
        UserWalletRepo-->>CloseBlockedUserDeploymentsHandler: undefined
        CloseBlockedUserDeploymentsHandler->>Logger: Skip - no wallet
    else Wallet found but no address
        UserWalletRepo-->>CloseBlockedUserDeploymentsHandler: Wallet (no address)
        CloseBlockedUserDeploymentsHandler->>Logger: Skip - no address
    else Wallet with address
        UserWalletRepo-->>CloseBlockedUserDeploymentsHandler: Wallet
        CloseBlockedUserDeploymentsHandler->>DeploymentReader: list(userId)
        DeploymentReader-->>CloseBlockedUserDeploymentsHandler: deployments[]
        loop For each deployment
            CloseBlockedUserDeploymentsHandler->>DeploymentWriter: close(wallet, dseq)
            alt Success
                DeploymentWriter-->>CloseBlockedUserDeploymentsHandler: closed
                CloseBlockedUserDeploymentsHandler->>Logger: Log success
            else Failure
                DeploymentWriter-->>CloseBlockedUserDeploymentsHandler: error
                CloseBlockedUserDeploymentsHandler->>Logger: Log error (continue)
            end
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested reviewers

  • stalniy
  • ygrishajev

Poem

🐰 A blocked user cannot deploy,
Our jobs hop swiftly, closing all they know,
The interceptor stands with watchful eyes,
While isBlocked flags rise,
User freedom now controlled, we go! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main changes: adding database schema for user blocking (isBlocked column), implementing blocking/unblocking routes, job handler for closing deployments, and interceptor for blocking requests from blocked users.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Jan 29, 2026

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
857 1 856 1
View the top 1 failed test(s) by shortest run time
Addresses API GET /v1/addresses/{address}/deployments/{skip}/{limit} returns 400 when skip is not a number
Stack Traces | 0.073s run time
Error: 
    at Query.run (.../dialects/postgres/query.js:76:25)
    at .../sequelize/src/sequelize.js:650:28
    at processTicksAndRejections (node:internal/process/task_queues:103:5)
    at PostgresQueryInterface.insert (.../dialects/abstract/query-interface.js:795:21)
    at Lease.save (.../sequelize/src/model.js:4154:35)
    at lease.create (.../sequelize/src/model.js:2305:12)
    at createLease (.../test/seeders/lease.seeder.ts:6:10)
    at async Promise.all (index 1)
    at setup (.../test/functional/addresses.spec.ts:357:5)
    at Object.<anonymous> (.../test/functional/addresses.spec.ts:191:27)

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@baktun14 baktun14 closed this Feb 4, 2026
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