Add live HTTPS door cards and screenshots to the catalog.
Some checks are pending
offline / test (push) Waiting to run

Homepage bottom of zapier.georgelambert.org lists each public
service with a description, screenshot, and link. UI-REVIEW.pdf
and the walkthrough document those doors.
This commit is contained in:
George Lambert 2026-09-11 20:15:53 -04:00
parent acf902e361
commit d31c4317af
21 changed files with 696 additions and 108 deletions

View file

@ -283,7 +283,7 @@ def page_shell(now: str, body: str, switch_to_md: bool, title: str) -> str:
padding:.4rem .75rem; border-radius:999px;
}}
.format-switch:hover {{ background:rgba(255,255,255,.28); }}
main {{ max-width:52rem; margin:0 auto; padding:1.5rem 1.25rem 3rem; }}
main {{ max-width:64rem; margin:0 auto; padding:1.5rem 1.25rem 3rem; }}
h1 {{ margin:.4rem 0 .6rem; font-size:1.85rem; }}
h2 {{ border-top:1px solid var(--line); padding-top:.8rem; margin-top:1.8rem; color:var(--accent-deep); }}
ul {{ padding-left:1.2rem; }}
@ -300,6 +300,14 @@ def page_shell(now: str, body: str, switch_to_md: bool, title: str) -> str:
.card p {{ margin:0 0 .7rem; color:var(--muted); font-size:13px; }}
.card a.act {{ display:inline-block; background:var(--accent); color:#fff; text-decoration:none;
border-radius:8px; padding:.28rem .6rem; font:650 12px system-ui; }}
.live {{ display:grid; grid-template-columns:repeat(auto-fill,minmax(280px,1fr)); gap:.9rem; }}
.live article {{ background:#fff; border:1px solid var(--line); border-radius:12px; overflow:hidden;
box-shadow:0 1px 2px rgba(23,26,38,.05), 0 8px 24px rgba(23,26,38,.06); }}
.live img {{ display:block; width:100%; height:140px; object-fit:cover; object-position:top; background:#eef0fe; }}
.live .body {{ padding:.75rem .9rem 1rem; }}
.live h3 {{ margin:0 0 .35rem; font-size:14px; }}
.live p {{ margin:0 0 .65rem; color:var(--muted); font-size:13px; }}
.live a.host {{ display:block; font:12px ui-monospace, Menlo, monospace; color:var(--accent); word-break:break-all; margin-bottom:.55rem; }}
</style>
</head>
<body>
@ -375,6 +383,8 @@ def main() -> None:
"verae-staff-session",
"verae-staff-ui",
"verae-staff-iam",
"verae-keep",
"verae-bootstrap",
):
pkg_root = ROOT / "packages" / pkg
if pkg in {"zapier-user-docs", "overview", "docs-master", "verae-ops"}:
@ -401,6 +411,17 @@ def main() -> None:
p = pkg_root / name
if p.exists():
copy_tree(p, SITE / "packages" / pkg / name)
ui_docs = ROOT / "packages" / "ui-docs"
for name in ("WALKTHROUGH.md", "REPORT.md", "UI-REVIEW.pdf"):
p = ui_docs / name
if p.exists():
copy_tree(p, SITE / "packages" / "ui-docs" / name)
copy_tree(
ui_docs / "screenshots",
SITE / "packages" / "ui-docs" / "screenshots",
ignore=shutil.ignore_patterns(".DS_Store"),
)
zap_app = ROOT / "packages" / "zappier" / "zapier-app" / "README.md"
if zap_app.exists():
copy_tree(zap_app, SITE / "packages" / "zappier" / "zapier-app" / "README.md")
@ -547,6 +568,12 @@ def main() -> None:
("verae-jobs-events", "jobs.events mailbox"),
("verae-nats-accounts", "NATS leaf/internal policy"),
("zapier-decisions", "Decisions and action log"),
("UI-Docs", "UI walkthrough and screenshot PDF"),
("verae-staff-session", "Staff cookie login"),
("verae-staff-ui", "Shared staff review HTML"),
("verae-staff-iam", "Staff users, roles, permissions"),
("verae-keep", "Host keep-alive"),
("verae-bootstrap", "Clone + deps per server type"),
]
git_lis = "".join(
f'<li><a href="https://git.georgelambert.org/marchon/{name}">{name}</a> '
@ -561,6 +588,7 @@ def main() -> None:
("user-docs/README.pdf", "User guide index"),
("packages/verae-zapier-simulator/README.pdf", "Simulator README"),
("packages/verae-fleet/docs/CONSOLE.pdf", "Operator console"),
("packages/ui-docs/UI-REVIEW.pdf", "UI review (screenshots + live doors)"),
("overview/README.pdf", "System overview"),
("overview/INDEX.pdf", "Documentation index"),
("docs/modules-pdf/", "Module PDFs (book)"),
@ -583,6 +611,70 @@ def main() -> None:
("sphinx/verae-zapier-modules.pdf", "Sphinx LaTeX PDF"),
]
LIVE_DOORS = [
("portal.png", "https://portal.zapier.georgelambert.org/portal/", "Customer portal",
"Public signup, sign-in, API key, statement, invoices. Access-web door."),
("api.png", "https://api.zapier.georgelambert.org/health", "Customer API",
"Direct customer API (x-api-key). Not Zapier."),
("leaf.png", "https://leaf.zapier.georgelambert.org/health", "S2S leaf",
"Server-to-server NATS leaf plane. No billing subjects."),
("zap.png", "https://zap.zapier.georgelambert.org/health", "Zapier plane",
"Only Zapier Platform HTTPS. Cloud never talks to NATS."),
("staff.png", "https://staff.zapier.georgelambert.org/", "Staff plane",
"CS / sales / accounting door after IAM."),
("iam.png", "https://iam.zapier.georgelambert.org/", "Staff IAM",
"Named staff users, roles, permissions, sessions."),
("login.png", "https://login.zapier.georgelambert.org/health", "Staff session",
"Shared staff cookie; proxies IAM when STAFF_IAM_URL is set."),
("cs.png", "https://cs.zapier.georgelambert.org/", "Customer service",
"Review prepaid balance and apply credits (USD)."),
("sales.png", "https://sales.zapier.georgelambert.org/", "Sales",
"Per-customer quote, tier, and multiplier."),
("acct.png", "https://acct.zapier.georgelambert.org/", "Accounting",
"QuickBooks IIF and accounting CSV export."),
("mw.png", "https://mw.zapier.georgelambert.org/health", "Middleware",
"Zapier /zapier/v1, jobs, archive, chain (MOCK_VERAE in lab)."),
("fleet.png", "https://fleet.zapier.georgelambert.org/", "Operator console",
"Fleet replicas, Trace, Docs. Pause/stop honored by keep."),
("docs.png", "https://zapier.georgelambert.org/", "This catalog",
"Colored PDF documentation site."),
("git.png", "https://git.georgelambert.org/", "Forgejo",
"Independent module repos (SSH 2223)."),
]
def live_section() -> str:
live_dir = ROOT / "packages" / "ui-docs" / "screenshots" / "live"
dest = SITE / "live"
dest.mkdir(parents=True, exist_ok=True)
cards_html = []
for fname, href, title, desc in LIVE_DOORS:
src = live_dir / fname
img = ""
if src.exists():
copy_tree(src, dest / fname)
img = f'<img src="/live/{fname}" alt="{title}"/>'
cards_html.append(
f'<article>{img}<div class="body"><h3>{title}</h3>'
f'<a class="host" href="{href}">{href}</a>'
f"<p>{desc}</p>"
f'<a class="act" href="{href}">Open</a></div></article>'
)
review = ""
pdf = ROOT / "packages" / "ui-docs" / "UI-REVIEW.pdf"
if pdf.exists():
copy_tree(pdf, SITE / "packages" / "ui-docs" / "UI-REVIEW.pdf")
review = (
'<p>Screenshot atlas with usage notes: '
'<a href="/packages/ui-docs/UI-REVIEW.pdf">UI-REVIEW.pdf</a>.</p>'
)
return (
f'<section><h2>Live services (NS1 · HTTPS)</h2>'
f"<p>Each name is on Let&rsquo;s Encrypt via Caddy on "
f"<strong>NS1.GEORGELAMBERT.ORG</strong>. NATS, keep, and archive workers stay on loopback.</p>"
f"{review}"
f'<div class="live">{"".join(cards_html)}</div></section>'
)
def extra_section(items: list[tuple[str, str]]) -> str:
lis = "".join(
f'<li><a href="{h}">{lab}</a></li>'
@ -615,6 +707,7 @@ def main() -> None:
</ul>
</section>
{extra_section(extra_pdf)}
{live_section()}
"""
rest_md = f"""
{cards("md")}
@ -640,6 +733,7 @@ def main() -> None:
</ul>
</section>
{extra_section(extra_md)}
{live_section()}
"""
(SITE / "index.html").write_text(