01 Obrazy — desktop jasny · owner (klient) · 1440×1280 · zgięcie 810

Kolejka ingestu

ingestImage · out: public/img/
2 wstrzymane filtry
Wszystkie 7 Wstrzymane 2 W toku 1 Gotowe 4 Stock 3
Plik → descriptive filenameTorWarianty (px)HashLicencjaStatus
lejek-dwustopniowy-schemat-etapow.webpIMG_4821.jpg → lejek-dwustopniowy
A
48076812001600
3f9a2c…e71b własne Aion Marketing gotowe
intencja-nie-keyword-rozmowa-z-klientem.webppexels-3184291.jpg → intencja-nie-keyword
A
4807681200
b81d04…2c9e Pexels CC0 · fot. fauxels gotowe
nie-sprzedajemy-pakietow-warsztat.webpDSC_0193.NEF → nie-sprzedajemy-pakietow
A własne Aion Marketing w toku · 2/4
koszt-pozyskania-klienta-cac-wykres.webpunsplash-photo-1554.jpg → koszt-pozyskania-klienta-cac
A Unsplash brak klucza czeka na licencję
aion-marketing-logo.svglogo-aion-marketing.svg → globals
Abez wariantów (svg)9c0e77…41aa własne znak towarowy gotowe
andrzej-niemiec-portret.webpIMG_4830.jpg → andrzej-niemiec
B
480768
5d6f1a…08cd własne Aion Marketing tor B wyłączony
realizacje-cedepe-hala-produkcyjna.webppixabay-2681039.jpg → realizacje
A
48076812001600
e2a4b9…7f30 Pixabay content licence gotowe
Descriptive filename powstaje z tytułu rekordu (descriptiveFilename); hash = sha256 wyjścia. „Czeka na licencję” blokuje publikację, nie build. sharp 0.33 · webp q82

Tory ingestu

A domyślnie · B flaga · C provider
przełączniki B/C: tylko operator
A
Warianty responsywne
domyślny tor dla każdego pliku

Sharp: resize do 480 · 768 · 1200 · 1600, WebP, EXIF z sidecar, opcjonalny overlay logo (logoPath).

  • hash wejścia i wyjścia (sha256)
  • sidecar .json obok pliku
  • fallback bez sharp: kopia + hash
aktywny
B
Micro noise / crop
flaga enableTorB · nie domyślnie

Lekka modulacja jasności/saturacji i przycięcie krawędzi — unikalny hash wyjścia dla stocku użytego na wielu tenantach.

  • 1 plik czeka na flagę (andrzej-niemiec-portret)
  • wymaga sharp (bez fallbacku)
wyłączony · 1 czeka tylko operator
C
AI img2img
provider aiFn · brak konfiguracji

Przekształcenie przez zewnętrzny provider (img2img) z zachowaniem kompozycji. Wynik oznaczony w sidecar creator i content credentials (WebMCP).

  • provider: null
  • koszt liczony w Usage jako resource: images.ai
brak provideraUNVERIFIED tylko operator
02 Obrazy — desktop operator · operator · data-theme=operator · 1440×1280

Kolejka ingestu

ingestImage · out: public/img/
2 wstrzymane filtry
Wszystkie 7 Wstrzymane 2 W toku 1 Gotowe 4 Stock 3
Plik → descriptive filenameTorWarianty (px)HashLicencjaStatus
lejek-dwustopniowy-schemat-etapow.webpIMG_4821.jpg → lejek-dwustopniowy
A
48076812001600
3f9a2c…e71b własne Aion Marketing gotowe
intencja-nie-keyword-rozmowa-z-klientem.webppexels-3184291.jpg → intencja-nie-keyword
A
4807681200
b81d04…2c9e Pexels CC0 · fot. fauxels gotowe
nie-sprzedajemy-pakietow-warsztat.webpDSC_0193.NEF → nie-sprzedajemy-pakietow
A własne Aion Marketing w toku · 2/4
koszt-pozyskania-klienta-cac-wykres.webpunsplash-photo-1554.jpg → koszt-pozyskania-klienta-cac
A Unsplash brak klucza czeka na licencję
aion-marketing-logo.svglogo-aion-marketing.svg → globals
Abez wariantów (svg)9c0e77…41aa własne znak towarowy gotowe
andrzej-niemiec-portret.webpIMG_4830.jpg → andrzej-niemiec
B
480768
5d6f1a…08cd własne Aion Marketing tor B wyłączony
realizacje-cedepe-hala-produkcyjna.webppixabay-2681039.jpg → realizacje
A
48076812001600
e2a4b9…7f30 Pixabay content licence gotowe
Descriptive filename powstaje z tytułu rekordu (descriptiveFilename); hash = sha256 wyjścia. „Czeka na licencję” blokuje publikację, nie build. sharp 0.33 · webp q82

Tory ingestu

A domyślnie · B flaga · C provider
operator: możesz przełączać B/C
A
Warianty responsywne
domyślny tor dla każdego pliku

Sharp: resize do 480 · 768 · 1200 · 1600, WebP, EXIF z sidecar, opcjonalny overlay logo (logoPath).

  • hash wejścia i wyjścia (sha256)
  • sidecar .json obok pliku
  • fallback bez sharp: kopia + hash
aktywny
B
Micro noise / crop
flaga enableTorB · nie domyślnie

Lekka modulacja jasności/saturacji i przycięcie krawędzi — unikalny hash wyjścia dla stocku użytego na wielu tenantach.

  • 1 plik czeka na flagę (andrzej-niemiec-portret)
  • wymaga sharp (bez fallbacku)
wyłączony · 1 czeka
C
AI img2img
provider aiFn · brak konfiguracji

Przekształcenie przez zewnętrzny provider (img2img) z zachowaniem kompozycji. Wynik oznaczony w sidecar creator i content credentials (WebMCP).

  • provider: null
  • koszt liczony w Usage jako resource: images.ai
brak provideraUNVERIFIED
03 Obrazy — stany · loading · empty · error · blocked · 1440×780
Loading skeleton kolejki · shimmer 1200 ms · bez opacity
Empty brak plików · checklist runbooka, nie ilustracja

Kolejka ingestu jest pusta

Żaden rekord w Directus nie ma jeszcze pliku. Cztery kroki — po ostatnim tor A wygeneruje warianty i sidecar.

  1. Włącz plugin aios-images w modules.json Moduły
  2. Wgraj plik do Directus files i przypnij do rekordu (artykuł / autor / realizacja) runbook §5
  3. Nadaj rekordowi tytuł — z niego powstaje descriptive filename descriptiveFilename
  4. Ustaw licencję (własne / stock) i uruchom ingest ingestImage
Stock BYOK jest opcjonalny — bez kluczy ingest działa dla plików własnych. Directus files
Error ingest przerwany · retry + log · fallback jawnie nazwany
ingest DSC_0193.NEF nie powiódł się 1 plik nieudany

Sharp nie dekoduje RAW (NEF). Tor A przełączył się na fallback „kopia + hash”, ale bez wariantów — plik nie trafi do <picture>. Skonwertuj do JPG/PNG i uruchom ponownie.

$ node packages/images/dist/ingest.js --in uploads/DSC_0193.NEF --title "Nie sprzedajemy pakietów — warsztat"
[ingest] tier A · widths 480,768,1200,1600
Error: Input buffer contains unsupported image format
    at Sharp.metadata (sharp/lib/input.js:490:19)
[ingest] fallback: copy + sha256 · variants: 0 · meta written
exit 1 · 0,9 s
Blocked LOCAL-GATED · brak kluczy stock i providera C = BLOCKED, nie „partial done”

Pobieranie ze stocka zablokowane BLOCKEDUNVERIFIED

Tenant w trybie standalone po Exit: brak BOT_STOCK_URL i żadnego klucza BYOK. Wyszukiwarka stock oraz tor C są niedostępne — kolejka plików własnych działa normalnie.

PEXELS_API_KEY brak klucza
PIXABAY_API_KEY brak klucza
UNSPLASH_ACCESS_KEY brak klucza
05 Obrazy — spec · decyzje, badge vs cisza, LIVE/UNVERIFIED, komponenty

Decyzje projektowe — Obrazy

  1. Kolejka jest tabelą, nie siatką miniatur. Operator porównuje hashe, tory i licencje pionowo; miniatura 40 px to tylko kotwica wzroku. Galeria zostaje w Directus files — panel nie duplikuje jej.
  2. Kolumna „Plik → descriptive filename” pokazuje wynik nazwy jako tytuł wiersza, a oryginał (IMG_4821.jpg) w mono pod nim. Nazwa opisowa jest tym, co trafi do HTML i sitemap obrazów — jest ważniejsza od źródła.
  3. Warianty jako lista szerokości w mono, bieżąca (użyta w og:image) obrysowana. Bez pasków postępu — ingest trwa sekundy, a lista mówi dokładnie, czego brakuje.
  4. Tory A/B/C to trzy karty na tym samym poziomie; A jest zawsze „on” i zablokowany (toggle z przerywanym obrysem), B/C przełącza tylko operator. Klient (01) widzi te same karty z notką „tylko operator” — ta sama IA, mniej uprawnień.
  5. ConcealField dla kluczy stock: stan „skonfigurowany” to cisza (muted check) + LIVE · 03:05; brak klucza to warn, nie critical — ingest plików własnych działa dalej. BOT_STOCK_URL nie jest sekretem i jest widoczny.
  6. Edytor sidecar jako .drawer nad treścią (board 01 — owner edytuje alt/caption/creator/copyright/keywords), nie w Directus: pola żyją w .json obok pliku. Drawer zajmuje 480 px prawej strony .main, nie wypycha AionLine. Board 02 pokazuje ten sam widok z zamkniętym drawerem — operator przełącza tory.

Co jest badge'em, co ciszą

SygnałFormaDowód
Plik gotowycisza: muted check „gotowe · LIVE”IngestResult.variants.length > 0
W tokustatus warn „w toku · 2/4 wariantów”kolejka ingestu
Czeka na licencjęstatus critical (blokuje publikację)meta.license puste
Tor B wyłączonystatus warn na karcie B + w wierszu plikuenableTorB: false
Tor C bez providerastatus unknown „UNVERIFIED” — nie mierzymyaiFn: undefined
Klucz stock OKConcealField •••• + ciszaenv obecny (nie wartość)
Brak wszystkich kluczyblocked-banner „BLOCKED · UNVERIFIED”standalone bez BYOK

Dane LIVE / UNVERIFIED na planszy

ElementŹródłoEtykieta
tiery A/B/C, pola sidecar, hashe sha256packages/images/src/ingest.ts (ImageMeta, IngestTier)LIVE
nazwy env stock, BOT_STOCK_URLpackages/images/src/stock-client.tsLIVE
slugi rekordów (lejek-dwustopniowy…)BRIEF §6LIVE
nazwy plików, szerokości wariantów, wartości hashprzykład redakcyjnyUNVERIFIED
liczby w pasku (7 / 5 / 2 z 3)snapshot planszyUNVERIFIED
„Cedepe hala produkcyjna” (realizacje)nazwa klienta z Hub (Sesja 02.09)UNVERIFIED

Tokeny — decyzja koloru akcentu

--accent-op = ciemny miód (jasny motyw) / jasne złoto (operator). Różni się od --warn (ochra) jasnością, nie tylko odcieniem — po desaturacji primary CTA i badge warn nie zlewają się. --accent-cl = głęboki granat (jasny) / jasny błękit (operator), różny od --teal. --purple zadeklarowany, nieużyty.

--accent-op --warn --accent-cl --teal --ok --critical --blue --muted

Użycie --accent na planszy: aktywna pozycja menu systemu, primary CTA, focus ring. Nic więcej. Aktywna zakładka i toggle „on” idą przez --text, żeby akcent nie konkurował ze statusem.

Shell — AIONLINE-CONTRACT

Menu systemu 244 px po lewej (brand „AIOS Admin”, tenant switcher tylko dla operatora, 12 pozycji IA §1, stopka: ModeBadge + build). AionLine 56 px po prawej: systemy Hub · Discovery · Panel · Create, inbox ekosystemu, obecność, profil, wyloguj, rozsuń. Topbar produktu bez dzwonka i profilu. Commerce w menu z kłódką i tooltipem „kill-gate Discovery”.

Board 01 = rola client/owner (jasny, tenant statyczny, brak akcji operatorskich). Board 02 = operator (data-theme="operator", switcher tenantów, pełne akcje). Ta sama IA w obu — różnią się tylko uprawnieniami.

Komponenty użyte (BRIEF §5) i hierarchia

.status-tile ×4 · .tbl (wariant .gate-table dla kolejki) · .tabs · .conceal ×4 (stock BYOK + BOT_STOCK_URL) · .mode-badge (stopka menu, karta BOT_STOCK_URL) · .drawer (edytor sidecar) · .skeleton · .empty-checklist · .blocked-banner · toggle (.toggle--locked dla A i dla B/C u klienta). Nieużyte celowo: .kill-lock (tylko menu Commerce), .chart-bars (wykres ingestu zmieściłby się dopiero pod 1280 px — trafi do Puls), .event-stream, .diff-panel.

Hierarchia: kolejka na pełnej szerokości nad zgięciem (7 wierszy × 44 px — siedem kolumn potrzebuje 1040 px), pod nią tory A/B/C (lewo) i stock BYOK (prawo). Sekrety w osobnej karcie, bo decydują o tym, czy kolejka w ogóle może pobierać ze stocka. Kolor statusu wyłącznie w kolumnie „Status”, na lewej krawędzi StatusTile i na liczniku menu (Obrazy 2 · warn). Tło kart bez obrysu; obrys 1 px tylko na wierszach, polach, toggle'ach i miniaturach.