feat: update API endpoints for company-vendor architecture

- Add transfer-ownership endpoint to companies API
- Add user search endpoint for autocomplete (/admin/users/search)
- Update company detail endpoint to include owner info and vendors list
- Update vendor endpoints to use company relationship for ownership
- Update deps.py vendor access check to use company.owner_user_id

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-02 19:39:31 +01:00
parent ec2885dab5
commit 66c967a04e
6 changed files with 194 additions and 143 deletions

View File

@@ -4,6 +4,7 @@ Company management endpoints for admin.
"""
import logging
from datetime import UTC, datetime
from fastapi import APIRouter, Body, Depends, Path, Query
from sqlalchemy.orm import Session
@@ -19,6 +20,8 @@ from models.schema.company import (
CompanyDetailResponse,
CompanyListResponse,
CompanyResponse,
CompanyTransferOwnership,
CompanyTransferOwnershipResponse,
CompanyUpdate,
)
@@ -136,11 +139,26 @@ def get_company_details(
vendor_count = len(company.vendors)
active_vendor_count = sum(1 for v in company.vendors if v.is_active)
# Build vendors list for detail view
vendors_list = [
{
"id": v.id,
"vendor_code": v.vendor_code,
"name": v.name,
"subdomain": v.subdomain,
"is_active": v.is_active,
"is_verified": v.is_verified,
}
for v in company.vendors
]
return CompanyDetailResponse(
id=company.id,
name=company.name,
description=company.description,
owner_user_id=company.owner_user_id,
owner_email=company.owner.email if company.owner else None,
owner_username=company.owner.username if company.owner else None,
contact_email=company.contact_email,
contact_phone=company.contact_phone,
website=company.website,
@@ -152,6 +170,7 @@ def get_company_details(
updated_at=company.updated_at.isoformat(),
vendor_count=vendor_count,
active_vendor_count=active_vendor_count,
vendors=vendors_list,
)
@@ -260,6 +279,55 @@ def toggle_company_status(
)
@router.post(
"/{company_id}/transfer-ownership",
response_model=CompanyTransferOwnershipResponse,
)
def transfer_company_ownership(
company_id: int = Path(..., description="Company ID"),
transfer_data: CompanyTransferOwnership = Body(...),
db: Session = Depends(get_db),
current_admin: User = Depends(get_current_admin_api),
):
"""
Transfer company ownership to another user (Admin only).
**This is a critical operation that:**
- Changes the company's owner_user_id
- Updates all associated vendors' owner_user_id
- Creates audit trail
⚠️ **This action is logged and should be used carefully.**
**Requires:**
- `new_owner_user_id`: ID of user who will become owner
- `confirm_transfer`: Must be true
- `transfer_reason`: Optional reason for audit trail
"""
company, old_owner, new_owner = company_service.transfer_ownership(
db, company_id, transfer_data
)
db.commit() # ✅ ARCH: Commit at API level for transaction control
return CompanyTransferOwnershipResponse(
message="Ownership transferred successfully",
company_id=company.id,
company_name=company.name,
old_owner={
"id": old_owner.id,
"username": old_owner.username,
"email": old_owner.email,
},
new_owner={
"id": new_owner.id,
"username": new_owner.username,
"email": new_owner.email,
},
transferred_at=datetime.now(UTC),
transfer_reason=transfer_data.transfer_reason,
)
@router.delete("/{company_id}")
def delete_company(
company_id: int = Path(..., description="Company ID"),