add low-code
This commit is contained in:
@@ -5,7 +5,7 @@ import os
|
||||
import requests
|
||||
import yaml
|
||||
from fastapi import Depends, FastAPI, HTTPException
|
||||
from pydantic import BaseModel
|
||||
from pydantic import BaseModel, Field
|
||||
from sqlalchemy import delete, select
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
@@ -39,7 +39,7 @@ from backend.auth import ( # noqa: E402
|
||||
verify_password,
|
||||
)
|
||||
from backend.db import engine, get_db # noqa: E402
|
||||
from backend.models import Base, User, UserChatMessage # noqa: E402
|
||||
from backend.models import AutonomousPipeline, Base, User, UserChatMessage # noqa: E402
|
||||
|
||||
|
||||
class GenerationRequest(BaseModel):
|
||||
@@ -58,6 +58,24 @@ class ChatRequest(BaseModel):
|
||||
messages: list[ChatMessageIn]
|
||||
|
||||
|
||||
class JenkinsPhaseConfigIn(BaseModel):
|
||||
job: str = ""
|
||||
server_url: str = ""
|
||||
parameters: dict[str, str] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class LowCodePhaseIn(BaseModel):
|
||||
id: str
|
||||
name: str = ""
|
||||
description: str = ""
|
||||
jenkins: JenkinsPhaseConfigIn = Field(default_factory=JenkinsPhaseConfigIn)
|
||||
|
||||
|
||||
class AutonomousPipelineSave(BaseModel):
|
||||
title: str = ""
|
||||
phases: list[LowCodePhaseIn] = Field(default_factory=list)
|
||||
|
||||
|
||||
def validate_config(config_text: str):
|
||||
try:
|
||||
yaml.safe_load(config_text)
|
||||
@@ -169,6 +187,58 @@ def me(user: User = Depends(get_current_user)):
|
||||
return {"id": str(user.id), "email": user.email, "full_name": user.full_name, "is_admin": user.is_admin}
|
||||
|
||||
|
||||
@app.get("/pipelines/autonomous")
|
||||
def get_autonomous_pipeline(
|
||||
db: Session = Depends(get_db),
|
||||
user: User | None = Depends(get_current_user) if REQUIRE_AUTH_FOR_GENERATE else None,
|
||||
):
|
||||
if user is None:
|
||||
return {"title": "", "phases": [], "updated_at": None}
|
||||
row = db.get(AutonomousPipeline, user.id)
|
||||
if row is None:
|
||||
return {"title": "", "phases": [], "updated_at": None}
|
||||
defn = row.definition if isinstance(row.definition, dict) else {}
|
||||
phases = defn.get("phases", [])
|
||||
return {
|
||||
"title": row.title,
|
||||
"phases": phases,
|
||||
"updated_at": row.updated_at.isoformat() if row.updated_at else None,
|
||||
}
|
||||
|
||||
|
||||
@app.put("/pipelines/autonomous")
|
||||
def put_autonomous_pipeline(
|
||||
body: AutonomousPipelineSave,
|
||||
db: Session = Depends(get_db),
|
||||
user: User | None = Depends(get_current_user) if REQUIRE_AUTH_FOR_GENERATE else None,
|
||||
):
|
||||
if user is None:
|
||||
raise HTTPException(status_code=401, detail="Authentication required")
|
||||
try:
|
||||
row = db.get(AutonomousPipeline, user.id)
|
||||
dumped = [p.model_dump() for p in body.phases]
|
||||
if row is None:
|
||||
row = AutonomousPipeline(
|
||||
user_id=user.id,
|
||||
title=body.title,
|
||||
definition={"schema_version": 1, "phases": dumped},
|
||||
)
|
||||
db.add(row)
|
||||
else:
|
||||
row.title = body.title
|
||||
row.definition = {"schema_version": 1, "phases": dumped}
|
||||
db.commit()
|
||||
db.refresh(row)
|
||||
return {
|
||||
"title": row.title,
|
||||
"phases": row.definition.get("phases", []),
|
||||
"updated_at": row.updated_at.isoformat() if row.updated_at else None,
|
||||
}
|
||||
except SQLAlchemyError as e:
|
||||
db.rollback()
|
||||
raise HTTPException(status_code=500, detail=f"Database error: {str(e)}")
|
||||
|
||||
|
||||
@app.get("/chat/history")
|
||||
def chat_history(
|
||||
limit: int = 500,
|
||||
|
||||
@@ -4,7 +4,7 @@ import uuid
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from sqlalchemy import Boolean, DateTime, ForeignKey, String, Text
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from sqlalchemy.dialects.postgresql import JSONB, UUID
|
||||
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
|
||||
|
||||
|
||||
@@ -43,3 +43,26 @@ class UserChatMessage(Base):
|
||||
content: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_now, nullable=False)
|
||||
|
||||
|
||||
class AutonomousPipeline(Base):
|
||||
"""Low-code конвейер: фазы и вызов Jenkins с параметрами (один черновик на пользователя)."""
|
||||
|
||||
__tablename__ = "autonomous_pipelines"
|
||||
|
||||
user_id: Mapped[uuid.UUID] = mapped_column(
|
||||
ForeignKey("users.id", ondelete="CASCADE"),
|
||||
primary_key=True,
|
||||
)
|
||||
title: Mapped[str] = mapped_column(String(500), default="", nullable=False)
|
||||
definition: Mapped[dict] = mapped_column(
|
||||
JSONB,
|
||||
nullable=False,
|
||||
default=lambda: {"schema_version": 1, "phases": []},
|
||||
)
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True),
|
||||
default=_now,
|
||||
onupdate=_now,
|
||||
nullable=False,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user