batch import csv

This commit is contained in:
debu-2 2026-10-05 04:53:45 +05:30
parent a679775f57
commit dd0ceef665
20 changed files with 1614 additions and 190 deletions

View file

@ -5,8 +5,12 @@ from sqlalchemy.ext.asyncio import AsyncSession
from app.database import get_postgres_session
from app.deps.org_manager import require_org_manager
from app.models import Account
from app.schemas import MailAliasCreate, MailAliasListResponse, MailAliasRead
from app.services.mail_aliases import create_mail_alias, list_mail_aliases
from app.schemas import MailAliasCreate, MailAliasListResponse, MailAliasRead, MailGroupEmailCheck
from app.services.mail_aliases import (
check_alias_email_available,
create_mail_alias,
list_mail_aliases,
)
router = APIRouter(prefix="/aliases", tags=["aliases"])
@ -20,6 +24,24 @@ async def get_aliases(
return MailAliasListResponse(items=items, counts=counts)
@router.get("/check-email", response_model=MailGroupEmailCheck)
async def check_email(
email: str,
manager: Account = Depends(require_org_manager),
session: AsyncSession = Depends(get_postgres_session),
) -> MailGroupEmailCheck:
if manager.company_domain is None:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="Company domain is required.",
)
return await check_alias_email_available(
session,
manager.company_domain,
email,
)
@router.post("", response_model=MailAliasRead, status_code=status.HTTP_201_CREATED)
async def add_alias(
payload: MailAliasCreate,

View file

@ -57,14 +57,6 @@ async def verify_owned_domain_dns(
domain: MailDomain,
) -> DnsVerificationResponse:
settings = get_settings()
if domain.status == "active":
return DnsVerificationResponse(
domain=domain.domain_name,
status=domain.status,
verified=True,
checks=[],
)
verification_token = await ensure_ownership_dns_record(session, domain)
checks = verify_company_dns(
domain_name=domain.domain_name,
@ -75,12 +67,15 @@ async def verify_owned_domain_dns(
verification_token=verification_token,
)
verified = all(check["verified"] for check in checks)
if verified:
if domain.status != "active" and verified:
await activate_company_domain(session, domain)
await session.commit()
status = "active"
else:
status = domain.status
return DnsVerificationResponse(
domain=domain.domain_name,
status=domain.status if not verified else "active",
status=status,
verified=verified,
checks=checks,
)

View file

@ -5,8 +5,12 @@ from sqlalchemy.ext.asyncio import AsyncSession
from app.database import get_postgres_session
from app.deps.org_manager import require_org_manager
from app.models import Account
from app.schemas import MailGroupCreate, MailGroupListResponse, MailGroupRead
from app.services.mail_groups import create_mail_group, list_mail_groups
from app.schemas import MailGroupCreate, MailGroupEmailCheck, MailGroupListResponse, MailGroupRead
from app.services.mail_groups import (
check_group_email_available,
create_mail_group,
list_mail_groups,
)
router = APIRouter(prefix="/groups", tags=["groups"])
@ -20,6 +24,25 @@ async def get_groups(
return MailGroupListResponse(items=items, counts=counts)
@router.get("/check-email", response_model=MailGroupEmailCheck)
async def check_email(
email: str,
manager: Account = Depends(require_org_manager),
session: AsyncSession = Depends(get_postgres_session),
) -> MailGroupEmailCheck:
if manager.company_domain is None:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="Company domain is required.",
)
result = await check_group_email_available(
session,
manager.company_domain,
email,
)
return result
@router.post("", response_model=MailGroupRead, status_code=status.HTTP_201_CREATED)
async def add_group(
payload: MailGroupCreate,

View file

@ -10,10 +10,13 @@ from app.models import Account
from app.routers.auth import validate_password
from app.schemas import (
OrgMemberCreate,
OrgMemberImportRequest,
OrgMemberImportResponse,
OrgMemberListResponse,
OrgMemberRead,
OrgMemberRoleUpdate,
)
from app.services.org_member_import import import_org_members
from app.services.org_members import (
create_org_member,
list_org_members,
@ -62,6 +65,23 @@ async def add_person(
) from error
@router.post("/import", response_model=OrgMemberImportResponse)
async def import_people(
payload: OrgMemberImportRequest,
manager: Account = Depends(require_org_manager),
session: AsyncSession = Depends(get_postgres_session),
) -> OrgMemberImportResponse:
try:
result = await import_org_members(session, manager=manager, payload=payload)
await session.commit()
return result
except ValueError as error:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail=str(error),
) from error
@router.patch("/{member_id}/role", response_model=OrgMemberRead)
async def update_member_role(
member_id: UUID,