An admin can now queue up an email address in advance (POST/GET/DELETE /system/pending-provisioning) with a source user and an optional admin flag. The moment that email actually verifies a real account - not raw registration, which proves nothing about ownership - it gets a deep copy of the source user's per-user API keys and every company they own (company profile, aliases, competitors, monitor config, sources, source documents, monitoring runs, reports, snapshots, detected changes, and enrichment - not just the company row), plus an email notification destination for its own address linked to the copied companies. The clone logic (_copy_row/_clone_company in provisioning_service.py) is generic over every table it touches via column introspection, so it doesn't need hand-maintained field lists per model. Co-Authored-By: Claude Sonnet 5 <[email protected]>
38 lines
1.2 KiB
Python
38 lines
1.2 KiB
Python
from __future__ import annotations
|
|
|
|
import uuid
|
|
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.models.pending_provisioning import PendingProvisioning
|
|
|
|
|
|
class PendingProvisioningRepository:
|
|
def __init__(self, db: AsyncSession) -> None:
|
|
self.db = db
|
|
|
|
async def list_all(self) -> list[PendingProvisioning]:
|
|
result = await self.db.execute(select(PendingProvisioning))
|
|
return list(result.scalars().all())
|
|
|
|
async def get_by_email(self, email: str) -> PendingProvisioning | None:
|
|
result = await self.db.execute(
|
|
select(PendingProvisioning).where(PendingProvisioning.email == email.lower())
|
|
)
|
|
return result.scalar_one_or_none()
|
|
|
|
async def create(
|
|
self, email: str, source_user_id: uuid.UUID, make_admin: bool
|
|
) -> PendingProvisioning:
|
|
record = PendingProvisioning(
|
|
email=email.lower(), source_user_id=source_user_id, make_admin=make_admin
|
|
)
|
|
self.db.add(record)
|
|
await self.db.flush()
|
|
return record
|
|
|
|
async def delete(self, record: PendingProvisioning) -> None:
|
|
await self.db.delete(record)
|
|
await self.db.flush()
|