Files
template-web-backend-python/code/app/welcome.py
admin user 6037476842
All checks were successful
__APP_NAME__ — build & deploy / ¿Credenciales de build listas? (push) Successful in 0s
__APP_NAME__ — build & deploy / Calidad + build + push (push) Has been skipped
__APP_NAME__ — build & deploy / ¿Cluster del tenant listo? (push) Has been skipped
__APP_NAME__ — build & deploy / Helm upgrade --install (push) Has been skipped
feat(welcome): página de bienvenida en / del Golden Path (shape 1.2.0)
2026-06-10 23:07:02 +00:00

138 lines
6.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ruff: noqa: E501 (HTML embebido: líneas largas intencionales, no se parten para no romper el render)
"""
Página de bienvenida por defecto del Golden Path `web-backend/python`.
Servida en la ruta raíz `/`. Es lo primero que ve el tenant cuando su
plataforma queda lista: explica cómo usar su entorno y deja claro que, en
cuanto haga su primer commit + push, su desarrollo reemplazará esta página.
Los placeholders `__APP_NAME__`, `__REPO_OWNER__` y `__REPO_NAME__` los
sustituye `repo-provisioner` server-side al scaffoldear el repo del tenant.
"""
WELCOME_HTML = """<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>__APP_NAME__ — Tu plataforma Cove</title>
<style>
:root {
--copper: #b5651d;
--copper-soft: #b5651d18;
--ink: #1c1917;
--muted: #6b6660;
--surface: #ffffff;
--bg: #faf8f5;
--border: #ece7e0;
--ok: #15803d;
--ok-bg: #dcfce7;
}
* { box-sizing: border-box; }
body {
font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
background: var(--bg); color: var(--ink);
margin: 0; padding: 3rem 1rem; line-height: 1.6;
}
.card {
max-width: 760px; margin: 0 auto; background: var(--surface);
border: 1px solid var(--border); border-radius: 16px;
padding: 2.5rem 2.75rem; box-shadow: 0 8px 30px #1c191708;
}
.brand { display: flex; align-items: center; gap: .6rem; font-weight: 700;
letter-spacing: .02em; color: var(--copper); font-size: 1.05rem; }
.brand .dot { width: 12px; height: 12px; border-radius: 50%; background: var(--copper); }
h1 { font-size: 1.9rem; margin: 1.2rem 0 .3rem; letter-spacing: -.02em; }
.sub { color: var(--muted); margin: 0 0 1.5rem; }
.pill { display: inline-flex; align-items: center; gap: .5rem; font-size: .82rem;
font-weight: 600; padding: .35rem .8rem; border-radius: 999px;
background: var(--copper-soft); color: var(--copper); }
.status { display: inline-flex; align-items: center; gap: .5rem; font-size: .82rem;
font-weight: 600; padding: .35rem .8rem; border-radius: 999px;
background: #f4f4f4; color: var(--muted); margin-left: .5rem; }
.status.ok { background: var(--ok-bg); color: var(--ok); }
.status .led { width: 8px; height: 8px; border-radius: 50%; background: currentColor; }
.callout {
border-left: 3px solid var(--copper); background: var(--copper-soft);
padding: 1rem 1.2rem; border-radius: 0 10px 10px 0; margin: 1.75rem 0;
font-weight: 500;
}
h2 { font-size: 1.05rem; margin: 2rem 0 .8rem; }
ol { padding-left: 0; counter-reset: step; list-style: none; margin: 0; }
ol li { counter-increment: step; position: relative; padding: .55rem 0 .55rem 2.6rem; }
ol li::before {
content: counter(step); position: absolute; left: 0; top: .5rem;
width: 1.7rem; height: 1.7rem; border-radius: 50%;
background: var(--copper); color: #fff; font-size: .82rem; font-weight: 700;
display: flex; align-items: center; justify-content: center;
}
code, pre { font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; }
code { background: #f4f1ec; padding: .15rem .45rem; border-radius: 5px; font-size: .88em; }
pre { background: var(--ink); color: #f5f0e9; padding: .9rem 1.1rem; border-radius: 10px;
overflow-x: auto; font-size: .85rem; margin: .4rem 0 0; }
.links { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 2rem;
padding-top: 1.5rem; border-top: 1px solid var(--border); }
.links a { text-decoration: none; font-size: .85rem; font-weight: 600;
color: var(--ink); border: 1px solid var(--border); padding: .45rem .9rem;
border-radius: 8px; transition: border-color .15s, color .15s; }
.links a:hover { border-color: var(--copper); color: var(--copper); }
footer { text-align: center; color: var(--muted); font-size: .78rem; margin-top: 2rem; }
</style>
</head>
<body>
<div class="card">
<div class="brand"><span class="dot"></span> CORALWARE · COVE</div>
<h1>Tu plataforma está lista 🎉</h1>
<p class="sub">Bienvenido. Este es tu entorno <strong>__APP_NAME__</strong>, corriendo en tu propio cluster.</p>
<span class="pill">__APP_NAME__</span>
<span id="health" class="status"><span class="led"></span> comprobando…</span>
<div class="callout">
📦 <strong>En cuanto hagas tu primer <code>commit</code> + <code>push</code>, tu desarrollo
reemplazará esta página.</strong> Esto es solo la bienvenida por defecto del Golden Path.
</div>
<h2>Cómo empezar</h2>
<ol>
<li>
Clona tu repositorio:
<pre>git clone https://gitea.coralsafety.com/__REPO_OWNER__/__REPO_NAME__.git</pre>
</li>
<li>Edita tu código en <code>code/</code> — la app es FastAPI (Python). Tu ruta <code>/</code> reemplaza esta página.</li>
<li>
Haz commit y push a <code>main</code>:
<pre>git add .
git commit -m "Mi primer cambio"
git push origin main</pre>
</li>
<li>El CI construye la imagen y la despliega automáticamente en tu cluster (~35 min).</li>
<li>Recarga esta misma URL — <strong>aquí verás tu desarrollo</strong>.</li>
</ol>
<div class="links">
<a href="https://gitea.coralsafety.com/__REPO_OWNER__/__REPO_NAME__" target="_blank">📂 Tu repositorio</a>
<a href="/docs">📘 API Docs (Swagger)</a>
<a href="/health">💚 Health</a>
<a href="/demo">🧩 Demo</a>
</div>
<footer>Coralware IDP · Golden Path <code>web-backend/python</code></footer>
</div>
<script>
fetch('/health').then(function (r) { return r.json(); }).then(function (d) {
var el = document.getElementById('health');
var ok = d.status === 'ok';
el.className = 'status' + (ok ? ' ok' : '');
el.innerHTML = '<span class="led"></span> ' + (ok ? 'En línea · DB: ' + d.db : 'Estado: ' + d.status);
}).catch(function () {
var el = document.getElementById('health');
el.innerHTML = '<span class="led"></span> /health no responde';
});
</script>
</body>
</html>
"""