Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Design: Move Group Block Handling to BlockRequestsController

Date: 2026-06-12
Status: Approved
Author: Claude

1. Problem Statement

Group block handling for restaurant_id == 'all' (or blank) was incorrectly added to Api::Partner::V1::InventoriesController#block. The correct place for this behavior is Api::Partner::V1::BlockRequestsController#create. We need to:

  1. Revert Api::Partner::V1::InventoriesController#block to match the main branch behavior (single-restaurant only).
  2. Extend Api::Partner::V1::BlockRequestsController#create to handle both single-restaurant and group (all/blank) block requests.

2. Goals

  • POST /api/partner/v1/inventories/block only handles single-restaurant inventory blocks, exactly as on main.
  • POST /api/partner/v1/block_requests handles:
    • single restaurant_id → creates one pending BlockAllotmentRequest
    • restaurant_id == 'all' or blank → creates pending requests for flagged restaurants and directly blocks non-flagged restaurants
  • Group block operations are atomic (all-or-nothing rollback on any failure).
  • ChangeTracker notifications for group blocks are moved to BlockRequestsController.

3. Architecture

┌─────────────────────────────────────┐
│  POST /api/partner/v1/block_requests │
│  BlockRequestsController#create      │
└──────────────┬──────────────────────┘
               │
       ┌───────┴───────┐
       │               │
restaurant_id         restaurant_id
single                'all' / blank
       │               │
       ▼               ▼
SubmitService    GroupSubmitService
       │               │
       ▼               ▼
pending request   pending requests + direct blocks

4. Components

4.1 Api::Partner::V1::BlockRequestsController#create

  • Permits restaurant_id along with existing params.
  • If restaurant_id is 'all' or blank:
    • Calls BlockRequest::GroupSubmitService with restaurants from the current staff.
    • On success, calls ChangeTracker#track_block_inventory and #notify_managers if any direct block occurred.
    • Renders JSON using Api::Partner::BlockAllotmentRequestSerializer with data (array of block requests) plus top-level direct_block_ids.
  • Otherwise:
    • Calls BlockRequest::SubmitService with the single restaurant.
    • Renders JSON using Api::Partner::BlockAllotmentRequestSerializer with data (single block request), status :created.

4.2 BlockRequest::GroupSubmitService

  • Accepts restaurants, staff, and params.
  • Partitions restaurants into:
    • flagged (and start_date >= 2 days away) → pending block requests
    • non-flagged (or start_date < 2 days away) → direct inventory block
  • Wraps the entire operation in an ActiveRecord::Base.transaction to guarantee all-or-nothing behavior.
  • Returns a ServiceResult with:
    • block_requests: array of created pending requests
    • direct_block_ids: array of restaurant IDs directly blocked
    • direct_message: combined success message from direct blocks

4.3 BlockRequest::SubmitService

  • No functional changes.
  • Continues to validate flagged status, date range, reason, and duplicates.
  • Creates a single pending BlockAllotmentRequest.

4.4 Api::Partner::V1::InventoriesController#block

  • Reverted to main branch implementation.
  • Removes handle_group_block private method.
  • Behavior for single restaurant remains:
    • If flagged and date >= 2 days → create pending request
    • Else → direct block via PartnerService::Inventories::BlockService

5. Data Flow

Single restaurant

  1. Client posts to /api/partner/v1/block_requests with restaurant_id: 123.
  2. Controller calls BlockRequest::SubmitService.
  3. Service validates and creates pending BlockAllotmentRequest.
  4. Controller renders { data: serialized_request }, status 201.

Group block

  1. Client posts to /api/partner/v1/block_requests with restaurant_id: 'all' (or omitted).
  2. Controller resolves all restaurants accessible to the current staff.
  3. Controller calls BlockRequest::GroupSubmitService.
  4. Service partitions restaurants and processes flagged/non-flagged paths inside a transaction.
  5. On success:
    • Controller calls ChangeTracker#track_block_inventory and #notify_managers if direct_block_ids is non-empty.
    • Controller renders { data: [...serialized_requests], direct_block_ids: [...] }, status 201.
  6. On any failure, transaction rolls back and controller renders 422 with error messages.

6. Error Handling

ScenarioHTTP StatusResponse
Single restaurant validation fails422{ errors: [...], message: '...' }
Group block: any restaurant fails422{ errors: [...], message: '...' } (all rolled back)
Group block: all succeed201{ data: [...], direct_block_ids: [...] }
Restaurant not found / not authorized404 / 422Existing error handling

7. Testing Plan

Request specs (spec/requests/api/partner/v1/block_requests_spec.rb)

  • Add context POST /api/partner/v1/block_requests with restaurant_id == 'all':
    • all flagged restaurants → creates pending requests for all
    • mixed flagged/non-flagged → pending for flagged, direct block for non-flagged
    • all non-flagged → direct blocks, no pending requests
    • partial failure → no side effects (rollback)
  • Add context POST /api/partner/v1/block_requests with blank restaurant_id:
    • behaves like 'all'

Request specs (spec/requests/api/partner/v1/inventories_spec.rb)

  • Remove all group-block test contexts.
  • Keep single-restaurant block tests matching main branch behavior.

Service specs (spec/services/block_request/group_submit_service_spec.rb)

  • Add test confirming entire operation rolls back on any failure.
  • Update existing tests if transaction wrapping changes assertions around counts.

8. Files to Modify

  • app/controllers/api/partner/v1/block_requests_controller.rb
  • app/controllers/api/partner/v1/inventories_controller.rb
  • app/services/block_request/group_submit_service.rb
  • spec/requests/api/partner/v1/block_requests_spec.rb
  • spec/requests/api/partner/v1/inventories_spec.rb
  • spec/services/block_request/group_submit_service_spec.rb

9. Out of Scope

  • No changes to routes.
  • No changes to BlockRequest::SubmitService behavior.
  • No UI/frontend changes.