from sqlalchemy import select from sqlalchemy.orm import Session from app.db.models import Child from app.db.models import Video as VideoModel from app.schemas.models import UploadTokenRequest, VideoCreateRequest from app.services import oss as oss_service def verify_child_owner(db: Session, parent_user_id: int, child_id: int) -> Child | None: return db.scalar( select(Child).where( Child.id == child_id, Child.parent_user_id == parent_user_id, Child.status != "archived", ) ) def create_upload_token(body: UploadTokenRequest) -> dict: object_key = oss_service.generate_object_key(body.child_id, body.file_name) return oss_service.create_upload_token(object_key, body.content_type, body.size) def save_direct_upload(token: str, object_key: str, data: bytes) -> None: if not oss_service.validate_upload_token(token, object_key): raise ValueError("invalid_upload_token") oss_service.save_local_upload(object_key, data) oss_service.consume_upload_token(token, object_key) def register_video( db: Session, user_id: int, body: VideoCreateRequest ) -> tuple[VideoModel | None, str | None]: child = verify_child_owner(db, user_id, body.child_id) if not child: return None, "child_not_found" existing = db.scalar(select(VideoModel).where(VideoModel.object_key == body.object_key)) if existing: return existing, "duplicate" video = VideoModel( child_id=body.child_id, uploaded_by=user_id, scene=body.scene.value, object_key=body.object_key, status="uploaded", ) db.add(video) db.commit() db.refresh(video) return video, None