Auth guards vary by endpoint — Create, Update, and Delete are admin-only. Get and List accept both JWT users (active only) and the admin key.

Overview

A benefit is a specific offering — a free consultation session, an insurance policy, a diagnostic test — provided by a Benefit Provider. Benefits carry a benefit_type enum and a benefit_details JSONB object whose variant must match the type. Responses always include provider_name via a JOIN, so callers never need a separate lookup to display who offers the benefit.

Benefit Types

benefit_typebenefit_details variantDescription
consultationConsultation { description }Free or subsidised doctor consultation
insurance_policyInsurancePolicy { description }Health or accident insurance
Type consistency is enforced at create time. Sending benefit_type = consultation with InsurancePolicy details returns 400 BenefitTypeMismatch.

Visibility Rules

ActorActive benefitsInactive benefits
JWT user (active status)✓ visibleHidden — returned as 404
Admin key✓ visible✓ visible
JWT users that are still onboarding cannot call benefit endpoints — GET /benefits requires status = active.

Endpoints

POST /benefits

Admin only. Create a benefit. Provider must exist and be active. Name must be unique within that provider.

GET /benefits

List benefits. JWT users see only active ones regardless of filters. Supports provider_id, benefit_type, status, pagination.

GET /benefits/{benefit_id}

Fetch a benefit by UUID. JWT users receive 404 for inactive benefits.

PATCH /benefits/{benefit_id}

Admin only. Update name, benefit_details, or status. All fields optional; omitting all is a no-op.

DELETE /benefits/{benefit_id}

Admin only. Soft-delete a benefit (sets status = inactive). No child-record check.

Request / Response Examples

curl -X POST http://localhost:8080/benefits \
  -H 'admin-api-key: your-admin-key' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Free GP Consultation",
    "benefit_type": "consultation",
    "provider_id": "018f4c2a-1b3e-7d8f-9a0b-2c3d4e5f6a7b",
    "benefit_details": {
      "type": "Consultation",
      "description": "One free general physician consultation per month"
    }
  }'
curl http://localhost:8080/benefits?provider_id=018f4c2a-1b3e-7d8f-9a0b-2c3d4e5f6a7b \
  -H 'Authorization: Bearer eyJhbGci...'

Error Codes

CodeHTTPDescription
BE_500500Internal server error
BE_501404Benefit not found
BE_502409Name already exists for this provider
BE_503400benefit_type / benefit_details mismatch
BE_504404Benefit provider not found or inactive
BE_505400Validation error (e.g. empty name)