package com.lincfusion.udyamlinc.apex; import com.lincfusion.udyamlinc.common.ApiResponse; import com.lincfusion.udyamlinc.security.TenantContext; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /** * The NABARD surface. Every endpoint returns aggregates. * *

Reachable only with {@code SCOPE_NABARD}, enforced in {@code SecurityConfig} * — an apex user cannot reach {@code /officer/**} and a bank user cannot reach * this. The two are not ranks of the same permission; they are different * entitlements, and a bank must be able to say truthfully that its regulator * cannot read its borrowers through this platform. * *

The second guard is belt and braces: each handler asserts the caller is apex * before answering. If a routing rule is ever loosened by accident, these fail * rather than quietly widening. */ @RestController @RequestMapping("/nabard") @RequiredArgsConstructor public class ApexController { private final ApexService apexService; @GetMapping("/dashboard") public ApiResponse> dashboard(TenantContext tenant) { requireApex(tenant); Map out = new LinkedHashMap<>(apexService.national()); out.put("dataAgeDays", apexService.dataAgeDays()); return ApiResponse.ok(out); } @GetMapping("/banks") public ApiResponse>> banks(TenantContext tenant) { requireApex(tenant); return ApiResponse.ok(apexService.bankScorecard()); } @GetMapping("/districts") public ApiResponse>> districts(TenantContext tenant) { requireApex(tenant); return ApiResponse.ok(apexService.byDistrict()); } @GetMapping("/sectors") public ApiResponse>> sectors(TenantContext tenant) { requireApex(tenant); return ApiResponse.ok(apexService.bySector()); } @GetMapping("/digest") public ApiResponse> digest(TenantContext tenant) { requireApex(tenant); return ApiResponse.ok(apexService.digest()); } @GetMapping("/institutions") public ApiResponse>> institutions(TenantContext tenant) { requireApex(tenant); return ApiResponse.ok(apexService.institutions()); } private void requireApex(TenantContext tenant) { if (tenant == null || !tenant.isApex()) { throw new org.springframework.security.access.AccessDeniedException( "The NABARD surface is limited to apex users"); } } }