Consolidate region management APIs
This commit is contained in:
@@ -50,29 +50,39 @@ it's stored for a future pricing-rule integration.
|
||||
| Function reference | Endpoint | Status |
|
||||
|---|---|---|
|
||||
| `assignAreaToRegion(areaId, regionId)` | — | Blocked — no `Area` entity exists (see [00_existing_gaps.md](./00_existing_gaps.md#9-no-area-entity-between-region-and-route)). Stand-in: `PUT /api/routes/{id}/region` assigns/reassigns an existing route directly to a region (see [11_route_sales_management.md](./11_route_sales_management.md)). |
|
||||
| `setRegionalTarget(regionId, period, targetValue)` | `PUT /api/regions/{id}/targets/{period}` | Implemented |
|
||||
| `setRegionalBudget(regionId, period, budgetAmount)` | `PUT /api/regions/{id}/budgets/{period}` | Implemented |
|
||||
| `mapAgencyToRegion(agencyId, regionId)` | `POST /api/regions/{id}/agencies` | Implemented |
|
||||
| `setRegionalTaxRule(regionId, ruleConfig)` | `PUT /api/regions/{id}/tax-rule` | Implemented |
|
||||
| `setRegionalTarget(regionId, period, targetValue)` | `PUT /api/regions/{id}/manage` (consolidated, see below) | Implemented |
|
||||
| `setRegionalBudget(regionId, period, budgetAmount)` | `PUT /api/regions/{id}/manage` (consolidated, see below) | Implemented |
|
||||
| `mapAgencyToRegion(agencyId, regionId)` | `PUT /api/regions/{id}/manage` (consolidated, see below) | Implemented |
|
||||
| `setRegionalTaxRule(regionId, ruleConfig)` | `PUT /api/regions/{id}/manage` (consolidated, see below) | Implemented |
|
||||
| `getRegionHierarchy(regionId)` | `GET /api/regions/{id}/hierarchy` | Implemented (region → routes → store ids; no `Area` level) |
|
||||
| `getRegionDashboard(regionId, period)` | `GET /api/regions/{id}/dashboard?period=...` | Implemented (real-time aggregation; see Open Questions, resolved) |
|
||||
|
||||
All request/response DTOs live in `Features/Region/RegionDTOs.cs`; routing and access checks are
|
||||
in `RegionController.cs` and `RegionService.cs`.
|
||||
|
||||
The four `set*`/`mapAgencyToRegion` actions above were later consolidated into a single
|
||||
`PUT /api/regions/{id}/manage` endpoint (`RegionService.ManageAsync`) — every field on the request
|
||||
is optional, and only the sub-action(s) whose fields are present get applied, so one call can
|
||||
update just one thing (as the frontend's `region-manage-sheet.tsx` does, one button per field) or
|
||||
several at once. See [BACKEND_API_REFERENCE.md §6.5](../../sharedDocs/BACKEND_API_REFERENCE.md#65-regions)
|
||||
for the exact request/response shape.
|
||||
|
||||
---
|
||||
|
||||
## Business Rules
|
||||
|
||||
- Only `RegionalManager` and above (per role level in `Data/Seed/RoleAndPermissionSeed.cs`) can
|
||||
set targets/budgets/tax-rule for their own region; only `RegionalAgency` can set them across
|
||||
regions. Implemented via `RegionService.CanManageRegionAsync`: role level ≥ 60 (`RegionalAgency`)
|
||||
is allowed unconditionally, role level ≥ 50 (`RegionalManager`) requires a matching
|
||||
`UserRegionScope` row for that region, anything lower is rejected. The same gate is applied to
|
||||
`mapAgencyToRegion`.
|
||||
- `mapAgencyToRegion` additionally rejects the target user if their role level is below the
|
||||
`RegionalAgency` threshold (60) — you can only map a user who actually holds (or outranks) that
|
||||
role.
|
||||
- ⚠️ **Temporarily disabled**: `RegionService.CanManageRegionAsync` (the gate on `ManageAsync`) was
|
||||
stubbed to always return `true` — role-based restriction is deliberately deferred pending a
|
||||
decision on the role model for this endpoint (tracked as a `TODO` in `RegionService.cs`). The
|
||||
design below is what it enforced before being stubbed out, and what it should return to:
|
||||
- Only `RegionalManager` and above (per role level in `Data/Seed/RoleAndPermissionSeed.cs`) can
|
||||
set targets/budgets/tax-rule for their own region; only `RegionalAgency` can set them across
|
||||
regions. Role level ≥ 60 (`RegionalAgency`) allowed unconditionally, role level ≥ 50
|
||||
(`RegionalManager`) requires a matching `UserRegionScope` row for that region, anything lower
|
||||
rejected.
|
||||
- `agencyUserId` (when supplied to `manage`) still rejects the target user if their role level is
|
||||
below the `RegionalAgency` threshold (60) — you can only map a user who actually holds (or
|
||||
outranks) that role. This check was not part of the disabled gate and remains active.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user