184 lines
8.3 KiB
Python
184 lines
8.3 KiB
Python
import html
|
||
|
||
from fastapi import APIRouter, Depends
|
||
from fastapi.responses import HTMLResponse
|
||
|
||
from ..auth import require_user
|
||
from ..config import DEFAULT_GITEA_ORG, get_gitea_public_url, read_env_value
|
||
from ..templates.layout import page
|
||
|
||
router = APIRouter()
|
||
|
||
|
||
# Portal sections (the admin/agenda links shown in the navigation). role: minimum role that can
|
||
# actually use the section; viewers may see read-only data where a section allows it.
|
||
PORTAL_SECTIONS = [
|
||
("fa-server", "Služby", "/portal/apps",
|
||
"Přehled nasazených služeb: stav, dokumentace, prostředky (RAM/CPU), Git a akce.", "viewer (čtení) / developer / admin"),
|
||
("fa-list-check", "Úlohy", "/portal/jobs",
|
||
"Fronta a historie úloh (nasazení, skripty) včetně stavů a logů.", "developer / admin"),
|
||
("fa-file-lines", "Logy", "/portal/logs",
|
||
"Souhrnné čtení logů napříč všemi úlohami; filtr chyb a proklik na konkrétní řádek úlohy.", "developer / admin"),
|
||
("fa-calendar-days", "Plánované skripty", "/portal/scheduled-scripts",
|
||
"Cron-like skripty spouštěné na pozadí; úpravy jen pro administrátory.", "developer / admin"),
|
||
("fa-bell", "Alerting", "/portal/alerting/rules",
|
||
"Pravidla alertů a jejich skripty; úpravy jen pro administrátory.", "developer / admin"),
|
||
("fa-sliders", "Environment", "/portal/admin/environment",
|
||
"Bezpečná úprava hlavního appfactory.env (backup, validace) + navazující redeploy core služeb (Portal, Worker, Webhook, Monitor, Gateway, Gitea, Registry) přes job frontu.", "admin"),
|
||
("fa-rocket", "Nasazení", "/portal/deployments",
|
||
"Historie deploy běhů, stavů a výstupů z deploy procesu.", "developer / admin"),
|
||
("fa-triangle-exclamation", "Incidenty", "/portal/incidents",
|
||
"Evidované incidenty služeb.", "developer / admin"),
|
||
("fa-gears", "Workery", "/portal/workers",
|
||
"Stav workerů zpracovávajících úlohy.", "admin"),
|
||
("fa-users", "Users", "/portal/admin/users",
|
||
"Správa uživatelů a rolí (viewer / developer / admin).", "admin"),
|
||
("fa-clipboard-list", "Audit", "/portal/audit",
|
||
"Auditní log akcí provedených v portálu.", "admin"),
|
||
("fa-box-archive", "Zálohy", "/portal/backups",
|
||
"Vytváření, stažení a obnova záloh AppFactory. Obnova je jen pro administrátory.", "admin"),
|
||
]
|
||
|
||
# Public / API endpoints not gated by the portal login.
|
||
PUBLIC_ENDPOINTS = [
|
||
("GET", "/apps", "Veřejný JSON katalog služeb (název + odkaz na dokumentaci). Routuje se přes Caddy."),
|
||
("GET", "/portal/health", "Health endpoint portálu (HTTP 200, pokud portál běží)."),
|
||
("GET", "/apps/<app-id>/docs", "Swagger/OpenAPI dokumentace konkrétní služby."),
|
||
("GET", "/apps/<app-id>/health", "Health endpoint konkrétní služby."),
|
||
]
|
||
|
||
# Roles model.
|
||
ROLES = [
|
||
("guest", "Výchozí role nového účtu po prvním přihlášení. Bez přístupu – vidí jen výzvu požádat administrátora o přidělení práv."),
|
||
("viewer", "Pouze pro čtení: vidí jaké služby běží a jejich dokumentaci (Swagger). Bez Gitu, úprav, nasazení a mazání."),
|
||
("developer", "Vše co viewer + provozní workflow služeb: Git/klonování, nasazení, proměnné, prostředky, metadata. Nemůže mazat služby ani do Administrace."),
|
||
("admin", "Plný přístup: vše co developer + mazání služeb, správa záloh a jejich obnova, správa uživatelů, audit a admin-only operace."),
|
||
]
|
||
|
||
|
||
@router.get("/developers", response_class=HTMLResponse)
|
||
def developers_page(user=Depends(require_user)):
|
||
section_rows = ""
|
||
for icon, title, href, desc, roles in PORTAL_SECTIONS:
|
||
section_rows += f"""
|
||
<tr>
|
||
<td><a href="{href}"><i class="fa-solid {icon}" aria-hidden="true"></i> {html.escape(title)}</a></td>
|
||
<td><code>{html.escape(href)}</code></td>
|
||
<td>{html.escape(desc)}</td>
|
||
<td><span class="muted">{html.escape(roles)}</span></td>
|
||
</tr>
|
||
"""
|
||
|
||
endpoint_rows = ""
|
||
for method, path, desc in PUBLIC_ENDPOINTS:
|
||
endpoint_rows += f"""
|
||
<tr>
|
||
<td><span class="pill">{html.escape(method)}</span></td>
|
||
<td><code>{path}</code></td>
|
||
<td>{html.escape(desc)}</td>
|
||
</tr>
|
||
"""
|
||
|
||
role_rows = ""
|
||
for role, desc in ROLES:
|
||
role_rows += f"""
|
||
<tr>
|
||
<td><span class="pill pill-muted">{html.escape(role)}</span></td>
|
||
<td>{html.escape(desc)}</td>
|
||
</tr>
|
||
"""
|
||
|
||
gitea_url = get_gitea_public_url()
|
||
gitea_org = read_env_value("GITEA_ORG", DEFAULT_GITEA_ORG)
|
||
clone_base = gitea_url or "<gitea-url>"
|
||
clone_cmd = html.escape(f"git clone {clone_base}/{gitea_org}/<app-id>.git", quote=True)
|
||
|
||
return page(
|
||
"Pro vývojáře",
|
||
f"""
|
||
<div class="card">
|
||
<h2><i class="fa-solid fa-code" aria-hidden="true"></i> Pro vývojáře</h2>
|
||
<p class="muted">
|
||
Přehled všech sekcí portálu, veřejných endpointů a rolí. Portál běží za reverzní proxy
|
||
na cestě <code>/portal</code>; jednotlivé služby na <code>/apps/<app-id></code>.
|
||
</p>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h2><i class="fa-solid fa-cloud-arrow-up" aria-hidden="true"></i> Jak publikovat</h2>
|
||
<p class="muted">Postup od založení nové služby po nasazení změn.</p>
|
||
<ol class="publish-steps">
|
||
<li>
|
||
<strong>Vytvořte novou službu.</strong>
|
||
Otevřete <a href="/portal/new-app" target="_blank" rel="noopener">formulář Nová služba</a>;
|
||
vznikne Gitea repozitář, workspace a první nasazení.
|
||
</li>
|
||
<li>
|
||
<strong>Naklonujte repozitář.</strong>
|
||
<div class="cmd-row">
|
||
<input readonly value="{clone_cmd}" id="publish-clone">
|
||
<button type="button" onclick="return copyText(this)"><i class="fa-solid fa-copy" aria-hidden="true"></i> Kopírovat</button>
|
||
</div>
|
||
<span class="muted">Přesný příkaz pro konkrétní službu (HTTP i SSH) najdete také na stránce
|
||
<a href="/portal/apps">Služby</a>.</span>
|
||
</li>
|
||
<li>
|
||
<strong>Upravte kód.</strong>
|
||
Buď se řiďte souborem <code>AGENTS.md</code> v kořenové složce projektu, nebo úpravy
|
||
nechte provést AI (agent si <code>AGENTS.md</code> přečte sám).
|
||
</li>
|
||
<li>
|
||
<strong>Commit a push.</strong>
|
||
Zacommitujte a pushněte změny — build a nasazení se spustí automaticky
|
||
(worker je vždy spuštěný a změnu rovnou zpracuje).
|
||
</li>
|
||
<li>
|
||
<strong>Zkontrolujte výsledek.</strong>
|
||
Stav nasazení a běh služby ověříte na stránce
|
||
<a href="/portal/apps">Služby</a> (stav, health, dokumentace).
|
||
</li>
|
||
</ol>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h2><i class="fa-solid fa-diagram-project" aria-hidden="true"></i> Sekce portálu (agendy)</h2>
|
||
<table>
|
||
<tr>
|
||
<th>Sekce</th>
|
||
<th>Odkaz</th>
|
||
<th>Popis</th>
|
||
<th>Role</th>
|
||
</tr>
|
||
{section_rows}
|
||
</table>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h2><i class="fa-solid fa-plug" aria-hidden="true"></i> Veřejné / API endpointy</h2>
|
||
<table>
|
||
<tr>
|
||
<th>Metoda</th>
|
||
<th>Cesta</th>
|
||
<th>Popis</th>
|
||
</tr>
|
||
{endpoint_rows}
|
||
</table>
|
||
<p class="muted">
|
||
Veřejný katalog <code>/apps</code> vrací JSON se seznamem služeb a odkazy na jejich dokumentaci.
|
||
</p>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<h2><i class="fa-solid fa-user-shield" aria-hidden="true"></i> Role a oprávnění</h2>
|
||
<table>
|
||
<tr>
|
||
<th>Role</th>
|
||
<th>Co může</th>
|
||
</tr>
|
||
{role_rows}
|
||
</table>
|
||
</div>
|
||
""",
|
||
user=user,
|
||
)
|