Added functions to fetch requirements from db.
Added functionality to create requirements on page
This commit is contained in:
@@ -1,15 +1,19 @@
|
||||
from contextlib import asynccontextmanager
|
||||
from typing import List
|
||||
from fastapi import FastAPI, Depends, Request
|
||||
from typing import List, Optional
|
||||
from fastapi import FastAPI, Depends, Request, HTTPException, status
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
||||
from fastapi.responses import RedirectResponse
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from src.models import TokenResponse, UserInfo, GroupResponse
|
||||
from src.models import (
|
||||
TokenResponse, UserInfo, GroupResponse,
|
||||
TagResponse, RequirementResponse, PriorityResponse,
|
||||
RequirementCreateRequest, RequirementUpdateRequest
|
||||
)
|
||||
from src.controller import AuthController
|
||||
from src.config import get_openid, get_settings
|
||||
from src.database import init_db, close_db, get_db
|
||||
from src.repositories import RoleRepository, GroupRepository
|
||||
from src.repositories import RoleRepository, GroupRepository, TagRepository, RequirementRepository, PriorityRepository
|
||||
import logging
|
||||
|
||||
# Configure logging
|
||||
@@ -176,3 +180,254 @@ async def get_groups(db: AsyncSession = Depends(get_db)):
|
||||
group_repo = GroupRepository(db)
|
||||
groups = await group_repo.get_all()
|
||||
return [GroupResponse.model_validate(g) for g in groups]
|
||||
|
||||
|
||||
# ===========================================
|
||||
# Tags Endpoints
|
||||
# ===========================================
|
||||
|
||||
@app.get("/api/tags", response_model=List[TagResponse])
|
||||
async def get_tags(db: AsyncSession = Depends(get_db)):
|
||||
"""
|
||||
Get all tags.
|
||||
|
||||
Returns:
|
||||
List of all tags with their codes and descriptions.
|
||||
"""
|
||||
tag_repo = TagRepository(db)
|
||||
tags = await tag_repo.get_all()
|
||||
return [TagResponse.model_validate(t) for t in tags]
|
||||
|
||||
|
||||
@app.get("/api/tags/{tag_id}", response_model=TagResponse)
|
||||
async def get_tag(tag_id: int, db: AsyncSession = Depends(get_db)):
|
||||
"""
|
||||
Get a specific tag by ID.
|
||||
|
||||
Args:
|
||||
tag_id: The tag ID
|
||||
|
||||
Returns:
|
||||
The tag if found.
|
||||
"""
|
||||
tag_repo = TagRepository(db)
|
||||
tag = await tag_repo.get_by_id(tag_id)
|
||||
if not tag:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Tag with id {tag_id} not found"
|
||||
)
|
||||
return TagResponse.model_validate(tag)
|
||||
|
||||
|
||||
# ===========================================
|
||||
# Priorities Endpoints
|
||||
# ===========================================
|
||||
|
||||
@app.get("/api/priorities", response_model=List[PriorityResponse])
|
||||
async def get_priorities(db: AsyncSession = Depends(get_db)):
|
||||
"""
|
||||
Get all priorities.
|
||||
|
||||
Returns:
|
||||
List of all priorities ordered by priority_num.
|
||||
"""
|
||||
priority_repo = PriorityRepository(db)
|
||||
priorities = await priority_repo.get_all()
|
||||
return [PriorityResponse.model_validate(p) for p in priorities]
|
||||
|
||||
|
||||
# ===========================================
|
||||
# Requirements Endpoints
|
||||
# ===========================================
|
||||
|
||||
def _build_requirement_response(req) -> RequirementResponse:
|
||||
"""Helper function to build RequirementResponse from a Requirement model."""
|
||||
# Determine validation status from latest validation
|
||||
validation_status = "Not Validated"
|
||||
if req.validations:
|
||||
# Get the latest validation
|
||||
latest_validation = max(req.validations, key=lambda v: v.created_at or req.created_at)
|
||||
validation_status = latest_validation.status.status_name if latest_validation.status else "Not Validated"
|
||||
|
||||
return RequirementResponse(
|
||||
id=req.id,
|
||||
req_name=req.req_name,
|
||||
req_desc=req.req_desc,
|
||||
version=req.version,
|
||||
created_at=req.created_at,
|
||||
updated_at=req.updated_at,
|
||||
tag=TagResponse.model_validate(req.tag),
|
||||
priority=req.priority if req.priority else None,
|
||||
groups=[GroupResponse.model_validate(g) for g in req.groups],
|
||||
validation_status=validation_status,
|
||||
)
|
||||
|
||||
|
||||
@app.get("/api/requirements", response_model=List[RequirementResponse])
|
||||
async def get_requirements(
|
||||
group_id: Optional[int] = None,
|
||||
tag_id: Optional[int] = None,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
Get all requirements, optionally filtered by group or tag.
|
||||
|
||||
Args:
|
||||
group_id: Optional group ID to filter by
|
||||
tag_id: Optional tag ID to filter by
|
||||
|
||||
Returns:
|
||||
List of all requirements with their related data.
|
||||
"""
|
||||
req_repo = RequirementRepository(db)
|
||||
|
||||
if group_id:
|
||||
requirements = await req_repo.get_by_group_id(group_id)
|
||||
elif tag_id:
|
||||
requirements = await req_repo.get_by_tag_id(tag_id)
|
||||
else:
|
||||
requirements = await req_repo.get_all()
|
||||
|
||||
return [_build_requirement_response(req) for req in requirements]
|
||||
|
||||
|
||||
@app.get("/api/requirements/{requirement_id}", response_model=RequirementResponse)
|
||||
async def get_requirement(requirement_id: int, db: AsyncSession = Depends(get_db)):
|
||||
"""
|
||||
Get a specific requirement by ID.
|
||||
|
||||
Args:
|
||||
requirement_id: The requirement ID
|
||||
|
||||
Returns:
|
||||
The requirement if found.
|
||||
"""
|
||||
req_repo = RequirementRepository(db)
|
||||
requirement = await req_repo.get_by_id(requirement_id)
|
||||
if not requirement:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Requirement with id {requirement_id} not found"
|
||||
)
|
||||
return _build_requirement_response(requirement)
|
||||
|
||||
|
||||
@app.post("/api/requirements", response_model=RequirementResponse, status_code=status.HTTP_201_CREATED)
|
||||
async def create_requirement(
|
||||
request: Request,
|
||||
req_data: RequirementCreateRequest,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
Create a new requirement.
|
||||
|
||||
Args:
|
||||
req_data: The requirement data
|
||||
|
||||
Returns:
|
||||
The created requirement.
|
||||
"""
|
||||
# Get the current user from cookie
|
||||
user_info = AuthController.get_current_user(request)
|
||||
|
||||
# Get the user's database ID
|
||||
from src.repositories import UserRepository
|
||||
user_repo = UserRepository(db)
|
||||
user = await user_repo.get_by_sub(user_info.sub)
|
||||
if not user:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="User not found in database"
|
||||
)
|
||||
|
||||
req_repo = RequirementRepository(db)
|
||||
requirement = await req_repo.create(
|
||||
user_id=user.id,
|
||||
tag_id=req_data.tag_id,
|
||||
req_name=req_data.req_name,
|
||||
req_desc=req_data.req_desc,
|
||||
priority_id=req_data.priority_id,
|
||||
group_ids=req_data.group_ids,
|
||||
)
|
||||
|
||||
await db.commit()
|
||||
return _build_requirement_response(requirement)
|
||||
|
||||
|
||||
@app.put("/api/requirements/{requirement_id}", response_model=RequirementResponse)
|
||||
async def update_requirement(
|
||||
requirement_id: int,
|
||||
request: Request,
|
||||
req_data: RequirementUpdateRequest,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
Update an existing requirement.
|
||||
|
||||
Args:
|
||||
requirement_id: The requirement ID to update
|
||||
req_data: The updated requirement data
|
||||
|
||||
Returns:
|
||||
The updated requirement.
|
||||
"""
|
||||
# Get the current user from cookie
|
||||
user_info = AuthController.get_current_user(request)
|
||||
|
||||
# Get the user's database ID
|
||||
from src.repositories import UserRepository
|
||||
user_repo = UserRepository(db)
|
||||
user = await user_repo.get_by_sub(user_info.sub)
|
||||
if not user:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="User not found in database"
|
||||
)
|
||||
|
||||
req_repo = RequirementRepository(db)
|
||||
requirement = await req_repo.update(
|
||||
requirement_id=requirement_id,
|
||||
editor_id=user.id,
|
||||
req_name=req_data.req_name,
|
||||
req_desc=req_data.req_desc,
|
||||
tag_id=req_data.tag_id,
|
||||
priority_id=req_data.priority_id,
|
||||
group_ids=req_data.group_ids,
|
||||
)
|
||||
|
||||
if not requirement:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Requirement with id {requirement_id} not found"
|
||||
)
|
||||
|
||||
await db.commit()
|
||||
return _build_requirement_response(requirement)
|
||||
|
||||
|
||||
@app.delete("/api/requirements/{requirement_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_requirement(
|
||||
requirement_id: int,
|
||||
request: Request,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
Delete a requirement.
|
||||
|
||||
Args:
|
||||
requirement_id: The requirement ID to delete
|
||||
"""
|
||||
# Verify user is authenticated
|
||||
AuthController.get_current_user(request)
|
||||
|
||||
req_repo = RequirementRepository(db)
|
||||
deleted = await req_repo.delete(requirement_id)
|
||||
|
||||
if not deleted:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Requirement with id {requirement_id} not found"
|
||||
)
|
||||
|
||||
await db.commit()
|
||||
|
||||
Reference in New Issue
Block a user