مخزن اختصاصی برنامهٔ وب؛ محتوای پوشهٔ web در ریشهٔ مخزن قرار گرفت. تاریخچهٔ پروژهٔ ربات (agy-bot) در این مخزن وجود ندارد و هیچ وابستگی runtime به آن نیست.
57 lines
1.6 KiB
Python
57 lines
1.6 KiB
Python
"""Projects domain: projects, their Git repositories and per-project credentials."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
from datetime import datetime
|
|
|
|
from app.domain.base import new_id, utcnow
|
|
|
|
|
|
@dataclass(slots=True, kw_only=True)
|
|
class Project:
|
|
organization_id: str
|
|
name: str
|
|
slug: str
|
|
description: str = ""
|
|
created_by_user_id: str | None = None
|
|
default_branch: str = "main"
|
|
id: str = field(default_factory=new_id)
|
|
created_at: datetime = field(default_factory=utcnow)
|
|
|
|
|
|
@dataclass(slots=True, kw_only=True)
|
|
class ProjectGitRepo:
|
|
"""The Git repository attached to a project.
|
|
|
|
Named ``ProjectGitRepo`` rather than ``ProjectRepository`` on purpose: the
|
|
latter collided with the *infrastructure* repository that manages ``Project``
|
|
rows, and the shadowing silently broke every Git endpoint at runtime.
|
|
"""
|
|
|
|
project_id: str
|
|
provider: str = "gitea"
|
|
owner: str = ""
|
|
repo_name: str = ""
|
|
clone_url: str = ""
|
|
web_url: str = ""
|
|
default_branch: str = "main"
|
|
id: str = field(default_factory=new_id)
|
|
created_at: datetime = field(default_factory=utcnow)
|
|
|
|
@property
|
|
def full_name(self) -> str:
|
|
return f"{self.owner}/{self.repo_name}"
|
|
|
|
|
|
@dataclass(slots=True, kw_only=True)
|
|
class ProjectGitCredential:
|
|
"""Per-project Git identity. The password is encrypted at rest and never
|
|
returned to the frontend."""
|
|
|
|
project_id: str
|
|
username: str
|
|
encrypted_password: str
|
|
id: str = field(default_factory=new_id)
|
|
created_at: datetime = field(default_factory=utcnow)
|