294 lines
9.7 KiB
Python
294 lines
9.7 KiB
Python
# [DEF:GitSchemas:Module]
|
|
#
|
|
# @COMPLEXITY: 1
|
|
# @SEMANTICS: git, schemas, pydantic, api, contracts
|
|
# @PURPOSE: Defines Pydantic models for the Git integration API layer.
|
|
# @LAYER: API
|
|
# @RELATION: DEPENDS_ON -> backend.src.models.git
|
|
#
|
|
# @INVARIANT: All schemas must be compatible with the FastAPI router.
|
|
|
|
from pydantic import BaseModel, Field
|
|
from typing import Any, Dict, List, Optional
|
|
from datetime import datetime
|
|
from src.models.git import GitProvider, GitStatus, SyncStatus
|
|
|
|
# [DEF:GitServerConfigBase:Class]
|
|
# @COMPLEXITY: 1
|
|
# @PURPOSE: Base schema for Git server configuration attributes.
|
|
class GitServerConfigBase(BaseModel):
|
|
name: str = Field(..., description="Display name for the Git server")
|
|
provider: GitProvider = Field(..., description="Git provider (GITHUB, GITLAB, GITEA)")
|
|
url: str = Field(..., description="Server base URL")
|
|
pat: str = Field(..., description="Personal Access Token")
|
|
pat: str = Field(..., description="Personal Access Token")
|
|
default_repository: Optional[str] = Field(None, description="Default repository path (org/repo)")
|
|
default_branch: Optional[str] = Field("main", description="Default branch logic/name")
|
|
# [/DEF:GitServerConfigBase:Class]
|
|
|
|
# [DEF:GitServerConfigUpdate:Class]
|
|
# @PURPOSE: Schema for updating an existing Git server configuration.
|
|
class GitServerConfigUpdate(BaseModel):
|
|
name: Optional[str] = Field(None, description="Display name for the Git server")
|
|
provider: Optional[GitProvider] = Field(None, description="Git provider (GITHUB, GITLAB, GITEA)")
|
|
url: Optional[str] = Field(None, description="Server base URL")
|
|
pat: Optional[str] = Field(None, description="Personal Access Token")
|
|
default_repository: Optional[str] = Field(None, description="Default repository path (org/repo)")
|
|
default_branch: Optional[str] = Field(None, description="Default branch logic/name")
|
|
# [/DEF:GitServerConfigUpdate:Class]
|
|
|
|
# [DEF:GitServerConfigCreate:Class]
|
|
# @PURPOSE: Schema for creating a new Git server configuration.
|
|
class GitServerConfigCreate(GitServerConfigBase):
|
|
"""Schema for creating a new Git server configuration."""
|
|
config_id: Optional[str] = Field(None, description="Optional config ID, useful for testing an existing config without sending its full PAT")
|
|
# [/DEF:GitServerConfigCreate:Class]
|
|
|
|
# [DEF:GitServerConfigSchema:Class]
|
|
# @PURPOSE: Schema for representing a Git server configuration with metadata.
|
|
class GitServerConfigSchema(GitServerConfigBase):
|
|
"""Schema for representing a Git server configuration with metadata."""
|
|
id: str
|
|
status: GitStatus
|
|
last_validated: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
# [/DEF:GitServerConfigSchema:Class]
|
|
|
|
# [DEF:GitRepositorySchema:Class]
|
|
# @PURPOSE: Schema for tracking a local Git repository linked to a dashboard.
|
|
class GitRepositorySchema(BaseModel):
|
|
"""Schema for tracking a local Git repository linked to a dashboard."""
|
|
id: str
|
|
dashboard_id: int
|
|
config_id: str
|
|
remote_url: str
|
|
local_path: str
|
|
current_branch: str
|
|
sync_status: SyncStatus
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
# [/DEF:GitRepositorySchema:Class]
|
|
|
|
# [DEF:BranchSchema:Class]
|
|
# @PURPOSE: Schema for representing a Git branch metadata.
|
|
class BranchSchema(BaseModel):
|
|
"""Schema for representing a Git branch."""
|
|
name: str
|
|
commit_hash: str
|
|
is_remote: bool
|
|
last_updated: datetime
|
|
# [/DEF:BranchSchema:Class]
|
|
|
|
# [DEF:CommitSchema:Class]
|
|
# @PURPOSE: Schema for representing Git commit details.
|
|
class CommitSchema(BaseModel):
|
|
"""Schema for representing a Git commit."""
|
|
hash: str
|
|
author: str
|
|
email: str
|
|
timestamp: datetime
|
|
message: str
|
|
files_changed: List[str]
|
|
# [/DEF:CommitSchema:Class]
|
|
|
|
# [DEF:BranchCreate:Class]
|
|
# @PURPOSE: Schema for branch creation requests.
|
|
class BranchCreate(BaseModel):
|
|
"""Schema for branch creation requests."""
|
|
name: str
|
|
from_branch: str
|
|
# [/DEF:BranchCreate:Class]
|
|
|
|
# [DEF:BranchCheckout:Class]
|
|
# @PURPOSE: Schema for branch checkout requests.
|
|
class BranchCheckout(BaseModel):
|
|
"""Schema for branch checkout requests."""
|
|
name: str
|
|
# [/DEF:BranchCheckout:Class]
|
|
|
|
# [DEF:CommitCreate:Class]
|
|
# @PURPOSE: Schema for staging and committing changes.
|
|
class CommitCreate(BaseModel):
|
|
"""Schema for staging and committing changes."""
|
|
message: str
|
|
files: List[str]
|
|
# [/DEF:CommitCreate:Class]
|
|
|
|
# [DEF:ConflictResolution:Class]
|
|
# @PURPOSE: Schema for resolving merge conflicts.
|
|
class ConflictResolution(BaseModel):
|
|
"""Schema for resolving merge conflicts."""
|
|
file_path: str
|
|
resolution: str = Field(pattern="^(mine|theirs|manual)$")
|
|
content: Optional[str] = None
|
|
# [/DEF:ConflictResolution:Class]
|
|
|
|
|
|
# [DEF:MergeStatusSchema:Class]
|
|
# @PURPOSE: Schema representing unfinished merge status for repository.
|
|
class MergeStatusSchema(BaseModel):
|
|
has_unfinished_merge: bool
|
|
repository_path: str
|
|
git_dir: str
|
|
current_branch: str
|
|
merge_head: Optional[str] = None
|
|
merge_message_preview: Optional[str] = None
|
|
conflicts_count: int = 0
|
|
# [/DEF:MergeStatusSchema:Class]
|
|
|
|
|
|
# [DEF:MergeConflictFileSchema:Class]
|
|
# @PURPOSE: Schema describing one conflicted file with optional side snapshots.
|
|
class MergeConflictFileSchema(BaseModel):
|
|
file_path: str
|
|
mine: Optional[str] = None
|
|
theirs: Optional[str] = None
|
|
# [/DEF:MergeConflictFileSchema:Class]
|
|
|
|
|
|
# [DEF:MergeResolveRequest:Class]
|
|
# @PURPOSE: Request schema for resolving one or multiple merge conflicts.
|
|
class MergeResolveRequest(BaseModel):
|
|
resolutions: List[ConflictResolution] = Field(default_factory=list)
|
|
# [/DEF:MergeResolveRequest:Class]
|
|
|
|
|
|
# [DEF:MergeContinueRequest:Class]
|
|
# @PURPOSE: Request schema for finishing merge with optional explicit commit message.
|
|
class MergeContinueRequest(BaseModel):
|
|
message: Optional[str] = None
|
|
# [/DEF:MergeContinueRequest:Class]
|
|
|
|
# [DEF:DeploymentEnvironmentSchema:Class]
|
|
# @PURPOSE: Schema for representing a target deployment environment.
|
|
class DeploymentEnvironmentSchema(BaseModel):
|
|
"""Schema for representing a target deployment environment."""
|
|
id: str
|
|
name: str
|
|
superset_url: str
|
|
is_active: bool
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
# [/DEF:DeploymentEnvironmentSchema:Class]
|
|
|
|
# [DEF:DeployRequest:Class]
|
|
# @PURPOSE: Schema for dashboard deployment requests.
|
|
class DeployRequest(BaseModel):
|
|
"""Schema for deployment requests."""
|
|
environment_id: str
|
|
# [/DEF:DeployRequest:Class]
|
|
|
|
# [DEF:RepoInitRequest:Class]
|
|
# @PURPOSE: Schema for repository initialization requests.
|
|
class RepoInitRequest(BaseModel):
|
|
"""Schema for repository initialization requests."""
|
|
config_id: str
|
|
remote_url: str
|
|
# [/DEF:RepoInitRequest:Class]
|
|
|
|
|
|
# [DEF:RepositoryBindingSchema:Class]
|
|
# @PURPOSE: Schema describing repository-to-config binding and provider metadata.
|
|
class RepositoryBindingSchema(BaseModel):
|
|
dashboard_id: int
|
|
config_id: str
|
|
provider: GitProvider
|
|
remote_url: str
|
|
local_path: str
|
|
# [/DEF:RepositoryBindingSchema:Class]
|
|
|
|
# [DEF:RepoStatusBatchRequest:Class]
|
|
# @PURPOSE: Schema for requesting repository statuses for multiple dashboards in a single call.
|
|
class RepoStatusBatchRequest(BaseModel):
|
|
dashboard_ids: List[int] = Field(default_factory=list, description="Dashboard IDs to resolve repository statuses for")
|
|
# [/DEF:RepoStatusBatchRequest:Class]
|
|
|
|
|
|
# [DEF:RepoStatusBatchResponse:Class]
|
|
# @PURPOSE: Schema for returning repository statuses keyed by dashboard ID.
|
|
class RepoStatusBatchResponse(BaseModel):
|
|
statuses: Dict[str, Dict[str, Any]]
|
|
# [/DEF:RepoStatusBatchResponse:Class]
|
|
|
|
|
|
# [DEF:GiteaRepoSchema:Class]
|
|
# @PURPOSE: Schema describing a Gitea repository.
|
|
class GiteaRepoSchema(BaseModel):
|
|
name: str
|
|
full_name: str
|
|
private: bool = False
|
|
clone_url: Optional[str] = None
|
|
html_url: Optional[str] = None
|
|
ssh_url: Optional[str] = None
|
|
default_branch: Optional[str] = None
|
|
# [/DEF:GiteaRepoSchema:Class]
|
|
|
|
|
|
# [DEF:GiteaRepoCreateRequest:Class]
|
|
# @PURPOSE: Request schema for creating a Gitea repository.
|
|
class GiteaRepoCreateRequest(BaseModel):
|
|
name: str = Field(..., min_length=1, max_length=255)
|
|
private: bool = True
|
|
description: Optional[str] = None
|
|
auto_init: bool = True
|
|
default_branch: Optional[str] = "main"
|
|
# [/DEF:GiteaRepoCreateRequest:Class]
|
|
|
|
|
|
# [DEF:RemoteRepoSchema:Class]
|
|
# @PURPOSE: Provider-agnostic remote repository payload.
|
|
class RemoteRepoSchema(BaseModel):
|
|
provider: GitProvider
|
|
name: str
|
|
full_name: str
|
|
private: bool = False
|
|
clone_url: Optional[str] = None
|
|
html_url: Optional[str] = None
|
|
ssh_url: Optional[str] = None
|
|
default_branch: Optional[str] = None
|
|
# [/DEF:RemoteRepoSchema:Class]
|
|
|
|
|
|
# [DEF:RemoteRepoCreateRequest:Class]
|
|
# @PURPOSE: Provider-agnostic repository creation request.
|
|
class RemoteRepoCreateRequest(BaseModel):
|
|
name: str = Field(..., min_length=1, max_length=255)
|
|
private: bool = True
|
|
description: Optional[str] = None
|
|
auto_init: bool = True
|
|
default_branch: Optional[str] = "main"
|
|
# [/DEF:RemoteRepoCreateRequest:Class]
|
|
|
|
|
|
# [DEF:PromoteRequest:Class]
|
|
# @PURPOSE: Request schema for branch promotion workflow.
|
|
class PromoteRequest(BaseModel):
|
|
from_branch: str = Field(..., min_length=1, max_length=255)
|
|
to_branch: str = Field(..., min_length=1, max_length=255)
|
|
mode: str = Field(default="mr", pattern="^(mr|direct)$")
|
|
title: Optional[str] = None
|
|
description: Optional[str] = None
|
|
reason: Optional[str] = None
|
|
draft: bool = False
|
|
remove_source_branch: bool = False
|
|
# [/DEF:PromoteRequest:Class]
|
|
|
|
|
|
# [DEF:PromoteResponse:Class]
|
|
# @PURPOSE: Response schema for promotion operation result.
|
|
class PromoteResponse(BaseModel):
|
|
mode: str
|
|
from_branch: str
|
|
to_branch: str
|
|
status: str
|
|
url: Optional[str] = None
|
|
reference_id: Optional[str] = None
|
|
policy_violation: bool = False
|
|
# [/DEF:PromoteResponse:Class]
|
|
|
|
# [/DEF:GitSchemas:Module]
|