01 Puls · desktop 1440×1280 · jasny · persona: klient owner (tenant aion-marketing, tryb aion) · linia zgięcia 810: nad nią pasek zdrowia + usage/quota + blockery, pod nią zdarzenia

Puls

Snapshot 03:07 · aion-marketing.pl + dev.aion-marketing.pl · tryb aion · 5 pomiarów, 4 z dowodem, 1 bez pomiaru

Otwórz Directus

Usage vs quota

30 dni · group=dayLIVE · 03:05
Jednostki dziennieΣ 3 412 unitsdzieńdziś
5 sie12 sie19 sie26 sie3 wrz
41.20 / 50 USD
cost_usd_month82%
≥ 80% kwoty · prognoza 49.8 USD do 30.09
limit z clients.json.limitsLIVE · 03:05
Usage i grupowanie service / provider

Blockery do wydania

4 blockery + 1 blockedLIVE · 03:07

Ostatnie zdarzenia

10 z 212 · audit logLIVE · 03:07
02 Puls · desktop 1440×1280 · data-theme="operator" · persona: operator Aion · te same dane, dodatkowo tenant switcher, link „wszystkie tenanty” i tooltip kill-gate na Commerce · akcent operatora = stalowy (≠ warn)

Puls

Snapshot 03:07 · aion-marketing.pl + dev.aion-marketing.pl · tryb aion · 5 pomiarów, 4 z dowodem, 1 bez pomiaru · wszystkie tenanty

Otwórz Directus

Usage vs quota

30 dni · group=dayLIVE · 03:05
Jednostki dziennieΣ 3 412 unitsdzieńdziś
5 sie12 sie19 sie26 sie3 wrz
41.20 / 50 USD
cost_usd_month82%
≥ 80% kwoty · prognoza 49.8 USD do 30.09
limit z clients.json.limitsLIVE · 03:05
Usage i grupowanie service / provider

Blockery do wydania

4 blockery + 1 blockedLIVE · 03:07

Ostatnie zdarzenia

10 z 212 · audit logLIVE · 03:07
03 Puls · stany 1440×760 · loading (skeleton, pulsowanie tła bez gradientu i opacity) · empty (checklist montażu z runbooka §1–§8) · error / degraded (Directus 503 → reszta read-only) · blocked (LOCAL-GATED, brak klucza — nie „partial done”)
Loading skeleton · pasek zdrowia + usage · brak tekstu „ładowanie…”
Empty świeży tenant · checklist runbooka, nie ilustracja

Tenant zmontowany w 2 z 8 kroków

Puls zacznie mierzyć po pierwszym buildzie. Kolejność jak w runbooku wdrożenia.

  1. §1Tenant w hub clients.json + AION_TENANT_KEY02.09
  2. §2modules.json · tryb, pluginy, sloty02.09
  3. §3Directus · schema.snapshot.json applyzrób
  4. §4Seed treści · authors, globals, 1 stronazrób
  5. §5Tracking · consent v2 deny + GA4 IDzrób
  6. §6WebMCP · packs site-nav contactzrób
  7. §7Pierwszy build · npm run buildzrób
  8. §8Smoke · / · /api/webmcp · sitemapzrób
Error · degraded Directus 503 → Puls read-only
Tryb ograniczony

Directus nie odpowiada. Build, gate i akcje zapisu wyłączone. Usage i zdarzenia z ostatniego snapshotu 02:55.

Directus /server/health → 503

3 próby co 10 s · ostatnia 03:07:41 · poprzedni OK 02:55

GET https://aion-marketing.pl/directus/server/health
503 Service Unavailable · 2 104 ms
upstream: pm2 aion-marketing-directus · restarts 3/5 (10 min)
{"status":"error","checks":{"pg:responseTime":"timeout"}}
Pełny log LIVE · 03:07 · 3 próby
Directus 503 pg:responseTime timeout · pm2 restart 3/5 awariaLIVE · 03:07
Blocked LOCAL-GATED · brak AION_TENANT_KEY

Blocked — Puls bez hub

Brak klucza tenanta w środowisku. Usage, quota i flush do hub nie działają. To nie jest częściowo gotowe — bez klucza tryb aion nie ma dowodu.

Zmienna
AION_TENANT_KEY
Źródło
hub · clients.json · aion-marketing
Skutek
usage/quota = UNVERIFIED · ExitHarness bez sensu · build bez meteringu
••••••••••••
UNVERIFIED · dopóki brak klucza
Usage vs quota brak dostępu hub /api/usage · 401 bez klucza blockedUNVERIFIED
04 Puls · mobile 390×844 · owner w drodze: zdrowie + blockery + 3 akcje · menu systemu → drawer (ikona), AionLine → ikona ekosystemu w topbarze · bez wykresu, quota jako pasek
05 Spec · decyzje projektowe · Puls · sesja 03.09 · kontrakt BRIEF §1–§7 · źródło treści docs/admin-ui-views.md §2.1

Cel i hierarchia — odpowiedź w 5 sekund

Pytanie 1: „czy strona żyje?” → pasek 5 StatusTile w jednym rzędzie, jedna wysokość, lewa krawędź niesie stan. Wzrok skanuje krawędzie: dwie kolorowe (warn, kreskowana unknown) na pięć — reszta cisza. Pytanie 2: „co blokuje wydanie?” → GateTable po prawej, licznik mono w kolorze warn jako pierwszy znak w wierszu, każdy wiersz = deep link do widoku, który naprawia. Wykres usage jest trzeci w hierarchii (lewa kolumna, szerszy, ale bez koloru stanu poza paskiem quoty). Zdarzenia pod zgięciem — to kontekst, nie decyzja.

Zgięcie 810: nad nim mieszczą się nagłówek, 5 kafli, usage + blockery. Operator widzi wszystko, co decyzyjne, bez scrolla; zdarzenia zaczynają się tuż pod linią, żeby zachęcić do przewinięcia.

Kolor = stan · co jest badge'em, co ciszą

  • Cisza (OK): kafel bez badge'a. Zostaje ikona check + słowo w kolorze --ok („sprawny”, „exit 0”, „obecny”) + LIVE · hh:mm. Zielony pojawia się tylko obok dowodu — tooltip kafla niesie komendę / endpoint / kod odpowiedzi.
  • Badge tylko dla: warn („blokuje wydanie”), critical („awaria”), unknown („bez dowodu”, kreskowany), blocked („blocked”, neutralny + kłódka). Nigdy badge „OK”.
  • Lewa krawędź kafla: --warn / --critical tylko przy problemie; OK = --line; unknown = kreskowana. Tło karty nigdy nie jest kolorowe.
  • Licznik blockerów (3 · 1 · 1) w kolorze warn, mono, 18 px — to jedyny „głośny” element GateTable. Wiersz commerce ma kłódkę zamiast liczby: to nie blocker wydania, to blokada włączenia.
  • Wykres słupki w --blue zmieszanym z powierzchnią (55%), dzisiejszy pełny --blue. Blue nie jest kolorem stanu — dane ≠ alarm. Alarm quoty niesie wyłącznie pasek + badge warn.

Akcent vs warn — rozjazd z tokenami hub

W tokens.css hub --accent-op = --warn (ten sam bursztyn) i --accent-cl = --teal. BRIEF §2 tego zakazuje, więc propozycja v2:

TokenJasnyOperatorRola
--accent-opgranatstal jasnaoperator — chłodny, bo statusy są ciepłe
--accent-clmiedź ciemnapiasekklient — ciepło marki, L ≠ warn o ≥ 12 pkt
--warnbursztynbursztyntylko stan

Test desaturacji: primary CTA „Rebuild” (accent) i badge „blokuje wydanie” (warn) różnią się jasnością w obu motywach — w szarości CTA jest wypełnionym ciemnym/jasnym blokiem, badge tintowanym tekstem. --accent = --accent-cl w :root, --accent-op w [data-theme="operator"]. --purple zadeklarowany, nieużyty.

Etykiety wiarygodności — skąd LIVE, skąd UNVERIFIED

Kafel / sekcjaDowód (tooltip)Etykieta
DirectusGET /directus/server/health → 200LIVE · 03:07
Ostatni buildnpm run build exit 0 · log pm2LIVE · 02:55
SEO gaterunSeoGate · 4 blockery / 3 rekordyLIVE · 02:55
WebMCP bridgecheck-webmcp-html dist/ + GET /api/webmcp → 200LIVE · 02:55
ExitHarnessostatni skan 27.08 — starszy niż buildUNVERIFIED
Usage vs quotahub /api/usage?tenant&group=day + clients.json.limitsLIVE · 03:05
Blockeryagregat trzech źródeł — etykieta = najstarsze źródłoLIVE · 03:07

Reguła: etykieta czasu należy do pomiaru, nie do renderu strony. Kafel bez pomiaru z bieżącego builda dostaje UNVERIFIED nawet, jeśli poprzedni wynik był PASS.

Shell wg AIONLINE-CONTRACT

  • Menu systemu 244 px lewo: brand „AIOS Admin” + persona, tenant (operator: przełącznik, klient: statyczny kreskowany), 12 pozycji IA, stopka ModeBadge aion + „build ok · 12 min”.
  • Aktywna pozycja = jedyne użycie akcentu poza primary CTA i focus ring (tint 14% + krawędź 3 px inset).
  • Liczniki w menu tylko tam, gdzie jest stan: SEO 4 (warn), Tracking 1 (warn), Usage 82% (neutralny). Puls bez licznika — Puls jest licznikiem.
  • Commerce z kłódką i kreskowanym obrysem; tooltip „kill-gate Discovery — wymaga profiles: ["commerce"]” pokazany na 02.
  • Topbar bez dzwonka i profilu — są w AionLine (prawo, 56 px): systemy, inbox 3, obecność 2, avatar, logout, ≪. Liczniki w AionLine neutralne (tekst na tekście), bo to nie stan produktu.

Stany i mobile

  • Loading: skeleton pulsuje zmianą background-color (surface-2 ↔ surface-3) — zero gradientu, zero opacity, ≤ 1,2 s cykl.
  • Empty: EmptyChecklist = 8 kroków runbooka §1–§8 z odhaczonymi 2; każdy nieskończony ma link „zrób”. Brak ilustracji.
  • Error / degraded: baner „Tryb ograniczony” + ErrorPanel z logiem (503, pm2 restarts) i „Spróbuj ponownie”; kafel Directus przechodzi w fail z badge critical. Reszta widoku zostaje read-only ze snapshotem 02:55.
  • Blocked: brak AION_TENANT_KEY = BLOCKED, nie partial. ConcealField pokazuje kropki, „pokaż 5 s” wyłączone (nie ma czego pokazać), CTA „Uzupełnij klucz”. Kafel usage → blocked + UNVERIFIED.
  • Mobile 390: tylko zdrowie (5 wierszy 44 px), quota jako pasek, blockery, 3 akcje w stałej stopce (Rebuild primary). Wykres i zdarzenia pominięte — owner w drodze podejmuje decyzję, nie analizuje.

Komponenty użyte (BRIEF §5) i dane

.status-tile (ok / warn / fail / unknown) · .stat-card (licznik quoty) · .chart-bars (30 div-ów, wysokość w %) · .gate-table · .event-stream · .mode-badge · .conceal · .empty-checklist · .skeleton · .blocked-banner · .badge + .quiet + .verify. Nieużyte tu, zdefiniowane wspólnie: .kill-lock .diff-panel .tabs .drawer.

Dane: tenant aion-marketing, artykuły lejek-dwustopniowy intencja-nie-keyword nie-sprzedajemy-pakietow koszt-pozyskania-klienta-cac, autorzy andrzej-niemiec aion-niemiec, quota cost_usd_month: 50, pipeline data → seo-gate → astro build → pagefind. Liczby usage są snapshotem projektowym — proposal, do podmiany na live przy wdrożeniu.

Typografia: system stack, sentence case, tytuł 26/700, sekcje 15/650, treść 13, meta 11, mono dla czasu, ID, slugów, hostów. Zero uppercase, zero letter-spacing, zero opacity, zero gradientów, zero cieni poza inset-krawędzią aktywnej pozycji menu.