Files
marriage/.history/scripts/patch_20250808211820.sh
Andrey K. Choi cc87dcc0fa
Some checks failed
continuous-integration/drone/push Build is failing
api development
2025-08-08 21:58:36 +09:00

123 lines
3.9 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
set -euo pipefail
# 1) Репозиторий: приводить user_id к uuid.UUID
cat > services/profiles/src/app/repositories/profile_repository.py <<'PY'
import uuid
from typing import Optional
from sqlalchemy import select
from sqlalchemy.orm import Session
from app.models.profile import Profile
from app.schemas.profile import ProfileCreate
class ProfileRepository:
def __init__(self, db: Session):
self.db = db
@staticmethod
def _to_uuid(v) -> uuid.UUID:
if isinstance(v, uuid.UUID):
return v
return uuid.UUID(str(v))
def get_by_user(self, user_id) -> Optional[Profile]:
uid = self._to_uuid(user_id)
stmt = select(Profile).where(Profile.user_id == uid)
return self.db.execute(stmt).scalar_one_or_none()
def create(self, user_id, obj: ProfileCreate) -> Profile:
uid = self._to_uuid(user_id)
p = Profile(
user_id=uid,
gender=obj.gender,
city=obj.city,
languages=obj.languages or [],
interests=obj.interests or [],
)
self.db.add(p)
self.db.commit()
self.db.refresh(p)
return p
PY
# 2) Схемы: дефолты - пустые списки (чтобы не было None → JSONB)
cat > services/profiles/src/app/schemas/profile.py <<'PY'
from __future__ import annotations
from typing import Optional, List
from pydantic import BaseModel, Field
class ProfileBase(BaseModel):
gender: str
city: str
languages: List[str] = Field(default_factory=list)
interests: List[str] = Field(default_factory=list)
class ProfileCreate(ProfileBase):
pass
class ProfileOut(ProfileBase):
id: str
user_id: str
class Config:
from_attributes = True
PY
# 3) Роут: ловим ошибки явно → 400 вместо 500
cat > services/profiles/src/app/api/routes/profiles.py <<'PY'
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from sqlalchemy.exc import IntegrityError, DataError
from app.db.deps import get_db
from app.schemas.profile import ProfileCreate, ProfileOut
from app.services.profile_service import ProfileService
from app.core.security import get_current_user # возвращает объект с полями sub, email, role
router = APIRouter(prefix="/v1/profiles", tags=["profiles"])
@router.get("/me", response_model=ProfileOut)
def get_my_profile(db: Session = Depends(get_db), user=Depends(get_current_user)):
svc = ProfileService(db)
p = svc.get_by_user(user.sub)
if not p:
# 404, если профиль отсутствует
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Profile not found")
return p
@router.post("", response_model=ProfileOut, status_code=status.HTTP_201_CREATED)
def create_profile(payload: ProfileCreate, db: Session = Depends(get_db), user=Depends(get_current_user)):
svc = ProfileService(db)
try:
existing = svc.get_by_user(user.sub)
if existing:
return existing
p = svc.create(user.sub, payload)
return p
except (IntegrityError, DataError, ValueError) as exc:
db.rollback()
raise HTTPException(status_code=400, detail=f"Invalid data: {exc}")
PY
# 4) Сервис — тонкая обёртка над репозиторием
cat > services/profiles/src/app/services/profile_service.py <<'PY'
from sqlalchemy.orm import Session
from app.repositories.profile_repository import ProfileRepository
from app.schemas.profile import ProfileCreate
class ProfileService:
def __init__(self, db: Session):
self.repo = ProfileRepository(db)
def get_by_user(self, user_id):
return self.repo.get_by_user(user_id)
def create(self, user_id, obj: ProfileCreate):
return self.repo.create(user_id, obj)
PY
echo "[profiles] rebuilding..."
docker compose build profiles
docker compose restart profiles