This commit is contained in:
2026-04-08 00:14:00 +03:00
parent 3d29e1f84e
commit 4f5daa9e65

View File

@@ -8,6 +8,7 @@ from fastapi import Depends, FastAPI, HTTPException
from pydantic import BaseModel from pydantic import BaseModel
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlalchemy.exc import SQLAlchemyError
app = FastAPI(title="AI CI/CD Assistant") app = FastAPI(title="AI CI/CD Assistant")
@@ -42,12 +43,26 @@ def validate_config(config_text: str):
@app.get("/health") @app.get("/health")
async def health(): async def health():
return {"status": "ok"} # lightweight DB probe to surface connection issues early
db_ok = True
db_error = None
try:
with engine.connect() as conn:
conn.exec_driver_sql("SELECT 1")
except Exception as e:
db_ok = False
db_error = str(e)
return {"status": "ok", "db_ok": db_ok, "db_error": db_error}
@app.on_event("startup") @app.on_event("startup")
def _startup(): def _startup():
# Ensure tables exist; if DB is unreachable, endpoints will surface the error.
try:
Base.metadata.create_all(bind=engine) Base.metadata.create_all(bind=engine)
except Exception:
# Avoid crashing the service hard; /health will show db_error.
pass
class RegisterRequest(BaseModel): class RegisterRequest(BaseModel):
@@ -67,6 +82,7 @@ def register(req: RegisterRequest, db: Session = Depends(get_db)):
if not email or not req.password: if not email or not req.password:
raise HTTPException(status_code=400, detail="Email and password are required") raise HTTPException(status_code=400, detail="Email and password are required")
try:
exists = db.execute(select(User).where(User.email == email)).scalar_one_or_none() exists = db.execute(select(User).where(User.email == email)).scalar_one_or_none()
if exists: if exists:
raise HTTPException(status_code=409, detail="Email already registered") raise HTTPException(status_code=409, detail="Email already registered")
@@ -81,13 +97,21 @@ def register(req: RegisterRequest, db: Session = Depends(get_db)):
db.add(user) db.add(user)
db.commit() db.commit()
db.refresh(user) db.refresh(user)
return {"id": str(user.id), "email": user.email, "full_name": user.full_name, "is_admin": user.is_admin} return {"id": str(user.id), "email": user.email, "full_name": user.full_name, "is_admin": user.is_admin}
except HTTPException:
raise
except SQLAlchemyError as e:
db.rollback()
raise HTTPException(status_code=500, detail=f"Database error: {str(e)}")
except Exception as e:
db.rollback()
raise HTTPException(status_code=500, detail=f"Internal error: {str(e)}")
@app.post("/auth/login") @app.post("/auth/login")
def login(req: LoginRequest, db: Session = Depends(get_db)): def login(req: LoginRequest, db: Session = Depends(get_db)):
email = req.email.strip().lower() email = req.email.strip().lower()
try:
user = db.execute(select(User).where(User.email == email)).scalar_one_or_none() user = db.execute(select(User).where(User.email == email)).scalar_one_or_none()
if not user or not verify_password(req.password, user.password_hash): if not user or not verify_password(req.password, user.password_hash):
raise HTTPException(status_code=401, detail="Invalid credentials") raise HTTPException(status_code=401, detail="Invalid credentials")
@@ -96,6 +120,12 @@ def login(req: LoginRequest, db: Session = Depends(get_db)):
token = create_access_token(user_id=str(user.id)) token = create_access_token(user_id=str(user.id))
return {"access_token": token, "token_type": "bearer"} return {"access_token": token, "token_type": "bearer"}
except HTTPException:
raise
except SQLAlchemyError as e:
raise HTTPException(status_code=500, detail=f"Database error: {str(e)}")
except Exception as e:
raise HTTPException(status_code=500, detail=f"Internal error: {str(e)}")
@app.get("/auth/me") @app.get("/auth/me")