Files
plantillas-proyectos/backend/api/v1/modules/a76/company/routes.py
acazares 52b8fcd434 feat: Implement multi-tenancy support in middleware and security layers
- Enhanced TenantMiddleware to validate tenant information from JWT tokens.
- Added LicenseValidationMiddleware to check tenant licenses before processing requests.
- Updated security utilities to extract tenant information from tokens and validate company access.
- Introduced CompanyStore to manage active company state and handle company switching in the frontend.
- Modified API routes to include company_id in requests for better resource management.
- Improved logging and error handling throughout the middleware and API layers.
- Updated frontend components to reflect changes in company management and selection.
- Added new API route for fetching user's companies with proper authentication handling.
2025-11-11 14:15:31 -06:00

206 lines
6.0 KiB
Python

"""
Endpoints API para gestión de empresa
"""
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from typing import Optional
from core.database import get_core_db
from core.security import get_current_user, has_role, get_tenant_from_token
from .service import CompanyService
from .dto import CompanyCreateDTO, CompanyUpdateDTO, CompanyResponseDTO
router = APIRouter(prefix="/company")
@router.post(
"/", response_model=CompanyResponseDTO, status_code=status.HTTP_201_CREATED
)
async def create_company(
company_data: CompanyCreateDTO,
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
"""
Create a new company in the system
Only one company can exist per system due to the unique consecutive field.
"""
service = CompanyService(db)
return service.create_company(company_data)
@router.get("/", response_model=Optional[CompanyResponseDTO])
async def get_company(
db: Session = Depends(get_core_db), current_user: dict = Depends(get_current_user)
):
"""
Get the registered company information
Returns the unique company in the system or None if it doesn't exist.
"""
service = CompanyService(db)
company = service.get_company()
if not company:
raise HTTPException(status_code=404, detail="No company found")
return company
@router.get("/my-companies", response_model=list[CompanyResponseDTO])
async def get_my_companies(
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user)
):
"""
Get all companies that belong to the user's tenant
Returns a list of companies associated with the tenant_id from the user's token
"""
tenant_id = get_tenant_from_token(current_user)
if not tenant_id:
raise HTTPException(
status_code=400,
detail="Tenant ID not found in token"
)
service = CompanyService(db)
companies = service.get_companies_by_tenant(tenant_id)
return companies
@router.get("/status/exists", response_model=dict)
async def check_company_exists(
db: Session = Depends(get_core_db), current_user: dict = Depends(get_current_user)
):
"""
Check if a company is registered in the system
"""
service = CompanyService(db)
exists = service.exists_company()
return {
"exists": exists,
"message": "Company found" if exists else "No company registered",
}
# Specific endpoints for important fields
@router.get("/info/basic", response_model=dict)
async def get_company_basic_info(
db: Session = Depends(get_core_db), current_user: dict = Depends(get_current_user)
):
"""
Get basic company information (name, RFC, main activity)
"""
service = CompanyService(db)
company = service.get_company()
if not company:
raise HTTPException(status_code=404, detail="No company found")
return {
"name": company.name,
"rfc": company.rfc,
"main_activity": company.main_activity,
"logo": company.logo,
}
@router.get("/info/responsible", response_model=dict)
async def get_company_responsible_info(
db: Session = Depends(get_core_db), current_user: dict = Depends(get_current_user)
):
"""
Get company responsible person information
"""
service = CompanyService(db)
company = service.get_company()
if not company:
raise HTTPException(status_code=404, detail="No company found")
return {
"responsible": company.responsible,
"responsible_name": company.responsible_name,
"responsible_last_name": company.responsible_last_name,
"responsible_mother_last_name": company.responsible_mother_last_name,
"responsible_rfc": company.responsible_rfc,
"position": company.position,
}
@router.get("/info/program", response_model=dict)
async def get_company_program_info(
db: Session = Depends(get_core_db), current_user: dict = Depends(get_current_user)
):
"""
Get company program information
"""
service = CompanyService(db)
company = service.get_company()
if not company:
raise HTTPException(status_code=404, detail="No company found")
return {
"program": company.program,
"program_number": company.program_number,
"prosec": company.prosec,
"prosec_authorization": company.prosec_authorization,
"manufacturer_id": company.manufacturer_id,
}
@router.get("/{company_id}", response_model=CompanyResponseDTO)
async def get_company_by_id(
company_id: str,
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
"""
Get company by specific ID
"""
service = CompanyService(db)
company = service.get_company_by_id(company_id)
if not company:
raise HTTPException(
status_code=404, detail=f"Company with ID '{company_id}' not found"
)
return company
@router.put("/{company_id}", response_model=CompanyResponseDTO)
async def update_company(
company_id: str,
company_data: CompanyUpdateDTO,
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
"""
Update company information
"""
service = CompanyService(db)
company = service.update_company(company_id, company_data)
if not company:
raise HTTPException(
status_code=404, detail=f"Company with ID '{company_id}' not found"
)
return company
@router.delete("/{company_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_company(
company_id: str,
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
"""
Delete company from the system
Note: This will completely remove the company from the system.
"""
service = CompanyService(db)
if not service.delete_company(company_id):
raise HTTPException(
status_code=404, detail=f"Company with ID '{company_id}' not found"
)