Initial commit: Happy Up monorepo through Sprint 5.

Document-driven MVP with FastAPI backend, Vue H5, WeChat mini shell, product demo, and Docker dev stack.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-07-23 11:42:40 +08:00
commit 1aaef71f52
116 changed files with 10550 additions and 0 deletions
+53
View File
@@ -0,0 +1,53 @@
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