Auth guards vary by endpoint — Create, Update, and Delete require an admin or benefit-provider OIDC token. Get and List accept any authenticated actor; app users (mobile JWT) see only active benefits, while admins see all.

Overview

A benefit is a specific offering — a free consultation or a health insurance policy — provided by a Benefit Provider. Benefits carry a benefit_type enum and a benefit_details JSONB block whose variant must match the type. Responses always include provider_name via a JOIN — callers never need a separate provider lookup.

Benefit Types

Type and details must be consistent at create time — a mismatch returns BE_503. (update_benefit does not re-validate this consistency.)
benefit_details is a serde-tagged enum. The discriminator key is benefit_type and its value is the SCREAMING_SNAKE_CASE variant name (CONSULTATION / INSURANCE_POLICY) — the same value as the sibling benefit_type column.

Insurance policy details

The INSURANCE_POLICY variant holds:
  • description — optional human-readable copy.
  • duration — externally-tagged single-key object: {"days": 90}, {"months": 12}, or {"years": 1}.
  • plans — a map keyed by free-form provider-defined plan_code (e.g. "1A", "2A", "2A1C"). Each PlanVariant carries daily_premium_amount, annual_premium_amount, coverage_amount (all amounts in minor units with a currency), optional grace_period_days, and nominee_required.
  • questionnaire — optional tree of Questions the policyholder answers at policy creation.

Visibility by Actor


Auth Guards by Endpoint


Endpoints

POST /benefits

Create a benefit. Provider must exist and be active.

GET /benefits

List benefits. App users see only ACTIVE ones. Filter by provider_id, benefit_type, status.

GET /benefits/{benefit_id}

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

PATCH /benefits/{benefit_id}

Update name, description, benefit_details, or status.

DELETE /benefits/{benefit_id}

Soft-delete (status → INACTIVE).

Request / Response Examples


Error Codes