finishing QDRO section

This commit is contained in:
HotSwapp
2025-08-15 17:19:51 -05:00
parent 006ef3d7b1
commit abc7f289d1
22 changed files with 2753 additions and 46 deletions

View File

@@ -52,7 +52,13 @@ class PaginatedSchedulesResponse(BaseModel):
total: int
@router.get("/schedules", response_model=Union[List[ScheduleResponse], PaginatedSchedulesResponse])
@router.get(
"/schedules",
response_model=Union[List[ScheduleResponse], PaginatedSchedulesResponse],
summary="List pension schedules for a file",
description="Filter by file number, date range, version, numeric ranges, and optional tokenized search (version, frequency). Supports pagination, sorting, and optional total count.",
tags=["pensions", "pensions-schedules"],
)
async def list_pension_schedules(
file_no: str = Query(..., description="Filter by file number"),
start: Optional[date] = Query(None, description="Start date (inclusive) for vests_on"),
@@ -123,7 +129,14 @@ class ScheduleUpdate(BaseModel):
frequency: Optional[str] = None
@router.post("/schedules", response_model=ScheduleResponse, status_code=status.HTTP_201_CREATED)
@router.post(
"/schedules",
response_model=ScheduleResponse,
status_code=status.HTTP_201_CREATED,
summary="Create pension schedule",
description="Create a new pension schedule row for a file.",
tags=["pensions", "pensions-schedules"],
)
async def create_pension_schedule(
payload: ScheduleCreate,
db: Session = Depends(get_db),
@@ -142,7 +155,13 @@ async def create_pension_schedule(
return row
@router.get("/schedules/{row_id}", response_model=ScheduleResponse)
@router.get(
"/schedules/{row_id}",
response_model=ScheduleResponse,
summary="Get pension schedule",
description="Fetch a single pension schedule row by ID.",
tags=["pensions", "pensions-schedules"],
)
async def get_pension_schedule(
row_id: int,
db: Session = Depends(get_db),
@@ -154,7 +173,13 @@ async def get_pension_schedule(
return row
@router.put("/schedules/{row_id}", response_model=ScheduleResponse)
@router.put(
"/schedules/{row_id}",
response_model=ScheduleResponse,
summary="Update pension schedule",
description="Update fields on an existing pension schedule.",
tags=["pensions", "pensions-schedules"],
)
async def update_pension_schedule(
row_id: int,
payload: ScheduleUpdate,
@@ -171,7 +196,13 @@ async def update_pension_schedule(
return row
@router.delete("/schedules/{row_id}", status_code=status.HTTP_204_NO_CONTENT)
@router.delete(
"/schedules/{row_id}",
status_code=status.HTTP_204_NO_CONTENT,
summary="Delete pension schedule",
description="Delete a pension schedule row by ID.",
tags=["pensions", "pensions-schedules"],
)
async def delete_pension_schedule(
row_id: int,
db: Session = Depends(get_db),
@@ -208,7 +239,13 @@ class PaginatedMarriagesResponse(BaseModel):
total: int
@router.get("/marriages", response_model=Union[List[MarriageResponse], PaginatedMarriagesResponse])
@router.get(
"/marriages",
response_model=Union[List[MarriageResponse], PaginatedMarriagesResponse],
summary="List marriage history",
description="Filter by file, date range, version, numeric ranges, and optional tokenized search (version, spouse_name, notes). Supports pagination and sorting.",
tags=["pensions", "pensions-marriages"],
)
async def list_marriages(
file_no: str = Query(..., description="Filter by file number"),
start: Optional[date] = Query(None, description="Start date (inclusive) for married_from"),
@@ -307,7 +344,14 @@ class MarriageUpdate(BaseModel):
marital_percent: Optional[float] = None
@router.post("/marriages", response_model=MarriageResponse, status_code=status.HTTP_201_CREATED)
@router.post(
"/marriages",
response_model=MarriageResponse,
status_code=status.HTTP_201_CREATED,
summary="Create marriage history row",
description="Create a new marriage history record for a file.",
tags=["pensions", "pensions-marriages"],
)
async def create_marriage(
payload: MarriageCreate,
db: Session = Depends(get_db),
@@ -320,7 +364,13 @@ async def create_marriage(
return row
@router.get("/marriages/{row_id}", response_model=MarriageResponse)
@router.get(
"/marriages/{row_id}",
response_model=MarriageResponse,
summary="Get marriage history row",
description="Fetch a single marriage history record by ID.",
tags=["pensions", "pensions-marriages"],
)
async def get_marriage(
row_id: int,
db: Session = Depends(get_db),
@@ -332,7 +382,13 @@ async def get_marriage(
return row
@router.put("/marriages/{row_id}", response_model=MarriageResponse)
@router.put(
"/marriages/{row_id}",
response_model=MarriageResponse,
summary="Update marriage history row",
description="Update fields on an existing marriage history record.",
tags=["pensions", "pensions-marriages"],
)
async def update_marriage(
row_id: int,
payload: MarriageUpdate,
@@ -349,7 +405,13 @@ async def update_marriage(
return row
@router.delete("/marriages/{row_id}", status_code=status.HTTP_204_NO_CONTENT)
@router.delete(
"/marriages/{row_id}",
status_code=status.HTTP_204_NO_CONTENT,
summary="Delete marriage history row",
description="Delete a marriage history record by ID.",
tags=["pensions", "pensions-marriages"],
)
async def delete_marriage(
row_id: int,
db: Session = Depends(get_db),
@@ -386,7 +448,13 @@ class PaginatedDeathResponse(BaseModel):
total: int
@router.get("/death-benefits", response_model=Union[List[DeathResponse], PaginatedDeathResponse])
@router.get(
"/death-benefits",
response_model=Union[List[DeathResponse], PaginatedDeathResponse],
summary="List death benefits",
description="Filter by file, date range, version, numeric ranges, and optional tokenized search (version, beneficiary_name, benefit_type, notes). Supports pagination and sorting.",
tags=["pensions", "pensions-death"],
)
async def list_death_benefits(
file_no: str = Query(..., description="Filter by file number"),
start: Optional[date] = Query(None, description="Start date (inclusive) for created_at"),
@@ -506,7 +574,14 @@ class DeathUpdate(BaseModel):
disc2: Optional[float] = None
@router.post("/death-benefits", response_model=DeathResponse, status_code=status.HTTP_201_CREATED)
@router.post(
"/death-benefits",
response_model=DeathResponse,
status_code=status.HTTP_201_CREATED,
summary="Create death benefit",
description="Create a new death benefit record for a file.",
tags=["pensions", "pensions-death"],
)
async def create_death_benefit(
payload: DeathCreate,
db: Session = Depends(get_db),
@@ -519,7 +594,13 @@ async def create_death_benefit(
return row
@router.get("/death-benefits/{row_id}", response_model=DeathResponse)
@router.get(
"/death-benefits/{row_id}",
response_model=DeathResponse,
summary="Get death benefit",
description="Fetch a single death benefit record by ID.",
tags=["pensions", "pensions-death"],
)
async def get_death_benefit(
row_id: int,
db: Session = Depends(get_db),
@@ -531,7 +612,13 @@ async def get_death_benefit(
return row
@router.put("/death-benefits/{row_id}", response_model=DeathResponse)
@router.put(
"/death-benefits/{row_id}",
response_model=DeathResponse,
summary="Update death benefit",
description="Update fields on an existing death benefit record.",
tags=["pensions", "pensions-death"],
)
async def update_death_benefit(
row_id: int,
payload: DeathUpdate,
@@ -548,7 +635,13 @@ async def update_death_benefit(
return row
@router.delete("/death-benefits/{row_id}", status_code=status.HTTP_204_NO_CONTENT)
@router.delete(
"/death-benefits/{row_id}",
status_code=status.HTTP_204_NO_CONTENT,
summary="Delete death benefit",
description="Delete a death benefit record by ID.",
tags=["pensions", "pensions-death"],
)
async def delete_death_benefit(
row_id: int,
db: Session = Depends(get_db),
@@ -669,7 +762,13 @@ class PensionDetailResponse(BaseModel):
separations: PaginatedSeparationsResponse
@router.get("/{file_no}/detail", response_model=PensionDetailResponse)
@router.get(
"/{file_no}/detail",
response_model=PensionDetailResponse,
summary="Pension detail with nested lists",
description="Return a representative Pension record for a file along with nested lists (schedules, marriages, death benefits, separations), each with independent pagination, sorting, and filtering controls.",
tags=["pensions", "pensions-detail"],
)
async def get_pension_detail(
file_no: str,
# Schedules controls
@@ -895,7 +994,14 @@ class PensionUpdate(BaseModel):
tax_rate: Optional[float] = Field(default=None, ge=0, le=100)
@router.post("/", response_model=PensionResponse, status_code=status.HTTP_201_CREATED)
@router.post(
"/",
response_model=PensionResponse,
status_code=status.HTTP_201_CREATED,
summary="Create Pension",
description="Create a main Pension record for a file.",
tags=["pensions", "pensions-main"],
)
async def create_pension(
payload: PensionCreate,
db: Session = Depends(get_db),
@@ -908,7 +1014,13 @@ async def create_pension(
return row
@router.get("/{pension_id}", response_model=PensionResponse)
@router.get(
"/{pension_id}",
response_model=PensionResponse,
summary="Get Pension",
description="Fetch a main Pension record by ID.",
tags=["pensions", "pensions-main"],
)
async def get_pension(
pension_id: int,
db: Session = Depends(get_db),
@@ -920,7 +1032,13 @@ async def get_pension(
return row
@router.put("/{pension_id}", response_model=PensionResponse)
@router.put(
"/{pension_id}",
response_model=PensionResponse,
summary="Update Pension",
description="Update fields on an existing Pension record.",
tags=["pensions", "pensions-main"],
)
async def update_pension(
pension_id: int,
payload: PensionUpdate,
@@ -937,7 +1055,13 @@ async def update_pension(
return row
@router.delete("/{pension_id}", status_code=status.HTTP_204_NO_CONTENT)
@router.delete(
"/{pension_id}",
status_code=status.HTTP_204_NO_CONTENT,
summary="Delete Pension",
description="Delete a Pension record by ID.",
tags=["pensions", "pensions-main"],
)
async def delete_pension(
pension_id: int,
db: Session = Depends(get_db),