Convertere

Builder Flow v9 — Osobne hostingu per persona, backend jako API, brak współdzielonego systemu plików

Czym jest Builder Flow v9?

Builder Flow v9 to proces, w którym każda persona ma własny, niezależny hosting — osobny serwer, osobna domena, osobny nginx, osobny SSL. Komunikacja między landing page a wspólnym silnikiem odbywa się wyłącznie przez backend API. Żadnego współdzielonego systemu plików, żadnych symlinków, żadnego bezpośredniego dostępu do "cudzego" kodu.

Kluczowe różnice względem v8:

Aspektv8v9 ✅
HostingWszystko na jednym serwerzeKażda persona na osobnym hoście / VPS
Współdzielenie koduSymlink do _app/Brak — każdy hosting ma własny frontend
Komunikacja frontend ↔ backendBezpośredni dostęp do plikówWyłącznie przez API (REST/GraphQL)
BackendWspółdzielony plikowoOsobny serwer backendu, dostępny tylko przez API
IzolacjaLogiczna (symlinki)Fizyczna (osobne procesy, osobne porty, osobne VPS)
CięcieW razie awarii jednego hosta — reszta działaAwaria jednego hosta — tylko ta persona offline

Architektura — osobne hostingu, backend przez API

INTERNET
=========

prywaciarz.example.com         firmowiec.example.com
    (Host A)                       (Host B)
    │                              │
    │ Landing page                 │ Landing page
    │ Checkout                     │ Checkout
    │ Thank you                    │ Thank you
    │ Frontend SPA                 │ Frontend SPA
    │                              │
    └──────────┬───────────────────┘
               │ API (HTTPS)
               ▼
          api.example.com
          (Host C — Backend)
          │
          │ REST API / GraphQL
          │ Baza danych
          │ Autoryzacja
          │ Wspólna logika
          │
          └── app.10s.pl (opcjonalnie)
              (Host D — neutralna app)

Zasady architektury:

  1. Każdy hosting to osobny VPS / Docker container — osobny nginx, osobny proces, osobne IP
  2. Frontend na hoście persony — statyczne HTML/CSS (landing, checkout, thank-you)
  3. Backend na osobnym hoście — API, baza danych, logika biznesowa
  4. Brak współdzielonego FS — żadnych NFS, symlinków, shared volume
  5. Komunikacja TYLKO przez API — frontend ↔ backend przez HTTPS
  6. Aplikacja (dashboard) może być SPA — ładowana z frontendu persony, dane z API backendu

Faza 0: Brainstorming

mkdir -p /root/projects/<projekt>/.superpowers/sdd
cat > /root/projects/<projekt>/.superpowers/sdd/brainstorming-brief.md << 'EOF'
# Brainstorming — produkt
- Jaki problem rozwiązuje ten produkt?
- Jaka jest jedna zdaniowa definicja?
- Jakie są kryteria sukcesu?
- Ilu person spodziewasz się na start? (wpływa na liczbę hostingów)
EOF
opencode run --prompt 'Przeczytaj brainstorming-brief.md. Zadaj pytania, zapisz odpowiedzi do brainstorming-report.md.' --auto

Faza 0.5: Persona Discovery

cat > /root/projects/<projekt>/.superpowers/sdd/persona-discovery-brief.md << 'EOF'
# Persona Discovery
Dla KAŻDEJ persony: tożsamość, motywacje, płatność, prywatność, język, customer journey.
Output: persona-discovery-report.md z 2-5 personami.
EOF
opencode run --prompt 'Przeczytaj brainstorming-report.md i persona-discovery-brief.md. Wykonaj Persona Discovery. Zapisz do persona-discovery-report.md.' --auto

Faza 0.75: Marketing Campaigns

cat > /root/projects/<projekt>/.superpowers/sdd/marketing-campaigns-brief.md << 'EOF'
# Marketing Campaigns per Persona
Dla każdej: kanały, targetowanie, budżet, KPI, keywords.
Output: marketing-campaigns-report.md
EOF
opencode run --prompt 'Przeczytaj persona-discovery-report.md i marketing-campaigns-brief.md. Wygeneruj marketing-campaigns-report.md.' --auto

Faza 0.8: Domain & Hosting Strategy (NOWOŚĆ v9)

CEO definiuje osobny hosting dla każdej persony oraz osobny hosting backendu.

Krok 0.8.1: Brief domain & hosting

cat > /root/projects/<projekt>/.superpowers/sdd/hosting-strategy-brief.md << 'EOF'
# Hosting Strategy — osobne hostingu per persona, backend jako API

## Cel
Dla KAŻDEJ persony: domena, hosting, nginx, SSL. Osobno dla backendu.

## Wymagane — dla każdej persony

### 1. Domena
- Nazwa domeny (np. prywaciarz.example.com)
- Czy domena jest dostępna?
- Czy jest SSL? (Let's Encrypt, Cloudflare)

### 2. Hosting
- Gdzie hostowane? (VPS, Docker, Netlify, Vercel, Cloudflare Pages)
- Jaki system? (Ubuntu, Alpine, Docker)
- Jaki web server? (nginx, Caddy, Apache)
- State files czy SPA? (statyczne HTML czy framework JS)

### 3. Frontend
- Co jest na tym hoście? (landing, checkout, thank-you, app SPA)
- Jakie zasoby? (RAM, CPU, storage)
- Czy potrzebuje build toola? (npm, vite, webpack)

### 4. API Backend (wspólny)
- Oddzielny hosting dla backendu
- REST API czy GraphQL?
- Baza danych (PostgreSQL, SQLite, MySQL)
- Autoryzacja (JWT, API keys, OAuth)
- Rate limiting (ile requestów na minutę z jednej domeny)

### 5. Komunikacja
- Frontend → Backend: fetch('/api/...') przez HTTPS
- Backend → Frontend: JSON responses
- CORS: dozwolone origins tylko z domen person
- Żadnego bezpośredniego dostępu do plików backendu

## Przykład: Persona "Prywaciarz"
- Domena: prywaciarz.example.com
- Hosting: VPS Hetzner CX22 ($5/mies) lub Netlify (free)
- SSL: Let's Encrypt przez Certbot
- Frontend: statyczne HTML w /var/www/html/
- App: SPA pobierająca dane z api.example.com

## Przykład: Persona "Firmowiec"
- Domena: firmowiec.example.com
- Hosting: VPS Hetzner CX22 ($5/mies) lub Cloudflare Pages (free)
- Frontend: statyczne HTML
- App: SPA pobierająca dane z api.example.com

## Przykład: Backend
- Domena: api.example.com
- Hosting: VPS Hetzner CX32 ($10/mies) — więcej RAM dla bazy
- Stack: FastAPI + PostgreSQL + Redis
- CORS: allow origins prywaciarz.example.com, firmowiec.example.com

## Output
Plik hosting-strategy-report.md — hosting per persona + backend.
EOF
opencode run --prompt '
Przeczytaj persona-discovery-report.md, domain-strategy-report.md, marketing-campaigns-report.md i hosting-strategy-brief.md.
Wygeneruj hosting-strategy-report.md. Dla każdej persony: domena, hosting, frontend. Dla backendu: domena, stack, API, CORS, baza danych.
' --auto

Krok 0.8.2: Przykład — Hosting Strategy

Persona: Prywaciarz

AspektWartość
Domenaprywaciarz.example.com
HostingDocker container na VPS, port 3001
Nginxreverse proxy, SSL, statyczne pliki
FrontendHTML/CSS w /srv/prywaciarz/
AppSPA pobierająca dane z api.example.com
CORSorigin: prywaciarz.example.com
Koszt$5/mies (VPS) lub $0 (Netlify)

Persona: Firmowiec

AspektWartość
Domenafirmowiec.example.com
HostingDocker container na VPS, port 3002
FrontendHTML/CSS w /srv/firmowiec/
AppSPA pobierająca dane z api.example.com
CORSorigin: firmowiec.example.com
Koszt$5/mies (VPS) lub $0 (Cloudflare Pages)

Backend (wspólny)

AspektWartość
Domenaapi.example.com
HostingDocker container, port 3000
StackFastAPI (Python) + PostgreSQL
APIREST: GET/POST/PUT/DELETE /api/v1/*
AutoryzacjaJWT token (Bearer)
CORSallow: prywaciarz.example.com, firmowiec.example.com
Rate limit100 req/min per origin
Koszt$10/mies (VPS)

Faza 1: Specyfikacja przez superpowers SDD

cat > .superpowers/sdd/phase-1-brief.md << 'EOF'
# Phase 1: Specyfikacja biznesowa
Persony, user stories, MVP scope, przepływ biznesowy (od reklamy do API calla).
Output: phase-1-report.md
EOF
opencode run --prompt 'Przeczytaj brainstorming-report.md, persona-discovery-report.md, hosting-strategy-report.md i phase-1-brief.md. Wygeneruj phase-1-report.md.' --auto
cat > .superpowers/sdd/phase-2-brief.md << 'EOF'
# Phase 2: Specyfikacja techniczna

## Architektura (v9 — osobne hostingu, API communication)
- prywaciarz.example.com → Host A (frontend: landing, checkout, thank-you, app SPA)
- firmowiec.example.com → Host B (frontend: landing, checkout, thank-you, app SPA)
- api.example.com → Host C (backend: REST API, baza danych, autoryzacja)

## API Endpoints (wszystkie przez HTTPS)
- GET /api/v1/health — health check
- POST /api/v1/auth/login — logowanie (JWT)
- POST /api/v1/auth/verify — weryfikacja tokena
- GET /api/v1/user/profile — profil użytkownika
- GET /api/v1/sessions?limit=10&offset=0 — lista sesji
- GET /api/v1/sessions/{id} — szczegóły sesji
- POST /api/v1/sessions — dodaj sesję
- GET /api/v1/stats/dashboard — statystyki dashboardu

## CORS
- Access-Control-Allow-Origin: https://prywaciarz.example.com, https://firmowiec.example.com
- Access-Control-Allow-Methods: GET, POST, PUT, DELETE
- Access-Control-Allow-Headers: Authorization, Content-Type

## Model danych
- users: id, email, pin_hash, created_at
- sessions: id, user_id, date, duration, pressure, status, notes
- devices: id, user_id, name, last_seen

## Output
Plik phase-2-report.md
EOF
opencode run --prompt 'Przeczytaj phase-1-report.md i phase-2-brief.md. Wygeneruj phase-2-report.md.' --auto
cat > .superpowers/sdd/phase-3-brief.md << 'EOF'
# Phase 3: Specyfikacja wizualna

## Kategoria A: Landing Pages (per hosting, per domena)
Dla każdej: domena, hosting, URL, cel, sekcje, CTA, komponenty DaisyUI

## Kategoria B: Checkout Pages (per hosting)
Dla każdej: URL, kroki, formularze, metody płatności

## Kategoria C: Thank You Pages (per hosting)
Dla każdej: URL, co widzi po zakupie

## Kategoria D: Aplikacja (SPA na froncie, dane z API)
- HTML szkielet z JS pobierającym dane z api.example.com
- Dashboard: fetch('/api/v1/stats/dashboard') → render
- Sesje: fetch('/api/v1/sessions') → render
- Profil: fetch('/api/v1/user/profile') → render

## Output
Plik phase-3-report.md
EOF
opencode run --prompt 'Przeczytaj phase-1-report.md, phase-2-report.md i phase-3-brief.md. Wygeneruj phase-3-report.md.' --auto

Faza 1.5: Hooks & Angles

cat > /root/projects/<projekt>/.superpowers/sdd/hooks-brief.md << 'EOF'
# Hooks & Angles — 10+ powodów
Dla każdego: headline, body, persona, kanał, emocja.
Output: hooks-report.md
EOF
opencode run --prompt 'Przeczytaj persona-discovery-report.md, domain-strategy-report.md, marketing-campaigns-report.md i hooks-brief.md. Wygeneruj hooks-report.md.' --auto

Faza 1.75: Ad Creatives

cat > /root/projects/<projekt>/.superpowers/sdd/ad-creatives-brief.md << 'EOF'
# Ad Creatives
Dla każdej persony × kanał: platforma, nagłówek, opis, CTA, URL docelowy (domena persony na jej hostingu), wariant B.
Output: ad-creatives-report.md
EOF
opencode run --prompt 'Przeczytaj persona-discovery-report.md, domain-strategy-report.md, hooks-report.md i ad-creatives-brief.md. Wygeneruj ad-creatives-report.md.' --auto

Faza 2: Design System — DaisyUI per hosting

Każdy hosting ma własny motyw DaisyUI. Aplikacja (SPA) pobiera dane z API i renderuje neutralny UI.

<!-- prywaciarz.example.com — Host A, port 3001, data-theme="dark" -->
<!DOCTYPE html>
<html lang="pl" data-theme="dark">
<head>
  <link href="https://cdn.jsdelivr.net/npm/daisyui@5" rel="stylesheet">
  <script>
    tailwind.config = { daisyui: { themes: [{ dark: { "primary": "#22c55e", "base-100": "#0f172a" } }] } }
  </script>
<!-- firmowiec.example.com — Host B, port 3002, data-theme="corporate" -->
<!DOCTYPE html>
<html lang="pl" data-theme="corporate">
<head>
  <link href="https://cdn.jsdelivr.net/npm/daisyui@5" rel="stylesheet">
  <script>
    tailwind.config = { daisyui: { themes: [{ corporate: { "primary": "#1e3a5f", "base-100": "#ffffff" } }] } }
  </script>

Faza 3: Landing Pages — każda na swoim hostingu

Krok 3.1: Landing page na Host A (prywaciarz.example.com)

# Na serwerze Host A (prywaciarz.example.com, port 3001)
mkdir -p /srv/prywaciarz/checkout /srv/prywaciarz/thank-you /srv/prywaciarz/app

opencode run --prompt '
Stwórz landing page w /srv/prywaciarz/index.html.

ZASADY:
1. DaisyUI dark (primary: #22c55e, base-100: #0f172a)
2. TYLKO klasy DaisyUI
3. Język: techniczny, konkretny
4. App to SPA pobierające dane z API: https://api.example.com/api/v1/...
5. WSZYSTKIE zapytania do API przez fetch()

SEKCJE: Hero, Problem, Rozwiązanie, Korzyści, Jak działa, Cena (0.05 XMR), FAQ, Footer
CTA: "Kup za Monero →" → /checkout/
' --auto

Krok 3.2: Landing page na Host B (firmowiec.example.com)

# Na serwerze Host B (firmowiec.example.com, port 3002)
mkdir -p /srv/firmowiec/checkout /srv/firmowiec/thank-you /srv/firmowiec/app

opencode run --prompt '
Stwórz landing page w /srv/firmowiec/index.html.

ZASADY:
1. DaisyUI corporate (primary: #1e3a5f, base-100: #ffffff)
2. TYLKO klasy DaisyUI
3. Język: formalny, biznesowy
4. App to SPA pobierające dane z API: https://api.example.com/api/v1/...

SEKCJE: Hero, Problem, Rozwiązanie, Korzyści, Cena, Jak działa, FAQ, Footer
CTA: "Zamów dla firmy →" → /checkout/
' --auto

Faza 3.5: Checkout + Thank You na hostingu persony

Checkout na Host A (prywaciarz.example.com)

opencode run --prompt '
Stwórz /srv/prywaciarz/checkout/index.html.

Kroki: 1. Wybierz krypto (Monero/BTC) → 2. Wyślij → 3. Czekaj → 4. Link
CTA: "Już wysłałem — sprawdź →" → /thank-you/
Link do app: /app/ (SPA na tym samym hostingu, dane z API)
DaisyUI dark.
' --auto

Thank You na Host A

opencode run --prompt '
Stwórz /srv/prywaciarz/thank-you/index.html.

"Gratulacje! Jesteś teraz anonimowy."
"Twój link: https://prywaciarz.example.com/app/?token=abc123"
CTA: "Przejdź do aplikacji →" → /app/ (SPA, dane z API)
DaisyUI dark.
' --auto

Checkout na Host B (firmowiec.example.com)

opencode run --prompt '
Stwórz /srv/firmowiec/checkout/index.html.

Kroki: 1. Dane firmy → 2. Plan → 3. Płatność → 4. Potwierdzenie
CTA: "Zamów i zapłać" → /thank-you/
Link do app: /app/ (SPA na tym samym hostingu, dane z API)
DaisyUI corporate.
' --auto

Thank You na Host B

opencode run --prompt '
Stwórz /srv/firmowiec/thank-you/index.html.

"Dziękujemy za zamówienie!"
"Panel admina: https://firmowiec.example.com/app/?token=xyz789"
CTA: "Przejdź do panelu →" → /app/ (SPA, dane z API)
DaisyUI corporate.
' --auto

Faza 4: Aplikacja SPA na każdym hostingu (dane z API)

Aplikacja to SPA (Single Page Application) — HTML + JS, który pobiera dane z API backendu. Każdy hosting ma swoją kopię SPA, ale wszystkie pobierają dane z tego samego API.

Krok 4.1: SPA dashboard na Host A z API callem

opencode run --prompt '
Stwórz /srv/prywaciarz/app/index.html — SPA dashboard.

ZASADY:
1. DaisyUI light — neutralny, zero brandingu persony
2. Wszystkie dane pobierane z API: https://api.example.com/api/v1/...
3. Fetch API przez JavaScript (async/await)
4. Obsługa błędów: jeśli API nie odpowiada, pokaż alert

STRUKTURA SPA:
- Navbar z linkami do /app/, /app/sessions, /app/profile
- Dashboard: fetch("/api/v1/stats/dashboard") → render statystyk
- Tabela: fetch("/api/v1/sessions?limit=5") → render table table-zebra
- Alert: jeśli fetch fail, alert alert-error

PRZYKŁAD KODU:
<script>
async function loadDashboard() {
  try {
    const res = await fetch("https://api.example.com/api/v1/stats/dashboard", {
      headers: { "Authorization": "Bearer " + getToken() }
    });
    const data = await res.json();
    document.getElementById("stats").innerHTML = renderStats(data);
  } catch(e) {
    document.getElementById("stats").innerHTML = "<div class=\"alert alert-error\">Nie można załadować danych</div>";
  }
}
window.onload = loadDashboard;
</script>
' --auto

Krok 4.2: SPA na Host B (ten sam kod, inne API URL)

SPA na Host B (firmowiec.example.com) ma ten sam kod, ale pobiera dane z tego samego API:

# Ten sam kod SPA, to samo API: https://api.example.com/api/v1/...
# Różni się tylko domeną hostingu (firmowiec.example.com)
# API to to samo — CORS akceptuje obie domeny
cp /srv/prywaciarz/app/index.html /srv/firmowiec/app/index.html

Faza 5: Backend API na osobnym hostingu (Host C)

Krok 5.1: Backend API

# Na serwerze Host C (api.example.com, port 3000)

opencode run --prompt '
Stwórz backend API w /srv/api/.

Stack: FastAPI (Python) + PostgreSQL

Endpointy:
- GET /api/v1/health → {"status": "ok"}
- POST /api/v1/auth/login → {"token": "jwt..."}
- GET /api/v1/user/profile → {"email": "...", "sessions_count": 12}
- GET /api/v1/sessions?limit=10&offset=0 → [{"id":1, "date":"...", ...}]
- GET /api/v1/sessions/{id} → {"id":1, "date":"...", "duration":60, ...}
- POST /api/v1/sessions → {"id": 2, ...}
- GET /api/v1/stats/dashboard → {"completed":12, "total":20, "hours":24, "compliance":85}

CORS:
- allow_origins = ["https://prywaciarz.example.com", "https://firmowiec.example.com"]
- allow_methods = ["GET", "POST", "PUT", "DELETE"]
- allow_headers = ["Authorization", "Content-Type"]

Autoryzacja:
- JWT token w header Authorization: Bearer <token>
- Token ważny 24h
- Rate limiting: 100 req/min per origin

Uruchomienie:
- uvicorn main:app --host 0.0.0.0 --port 3000
- Nginx reverse proxy: api.example.com → localhost:3000
' --auto

Krok 5.2: API — przykładowa odpowiedź

// GET https://api.example.com/api/v1/stats/dashboard
// Authorization: Bearer eyJ...

{
  "completed": 12,
  "total": 20,
  "hours": 24,
  "compliance": 85,
  "last_session": "2026-07-20",
  "next_session": "2026-07-22",
  "sessions": [
    {"id": 1, "date": "2026-07-20", "duration": 60, "status": "completed"},
    {"id": 2, "date": "2026-07-18", "duration": 45, "status": "completed"},
    {"id": 3, "date": "2026-07-16", "duration": 60, "status": "interrupted"}
  ]
}

Faza 6: Nginx — każdy hosting ma własny config

Host A — prywaciarz.example.com

# /etc/nginx/sites-available/prywaciarz.example.com
server {
    listen 443 ssl;
    server_name prywaciarz.example.com;

    ssl_certificate /etc/letsencrypt/live/prywaciarz.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/prywaciarz.example.com/privkey.pem;

    root /srv/prywaciarz;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }

    # app SPA — statyczne pliki, dane z API
    location /app/ {
        alias /srv/prywaciarz/app/;
        try_files $uri $uri/ /app/index.html;
    }
}

Host B — firmowiec.example.com

# /etc/nginx/sites-available/firmowiec.example.com
server {
    listen 443 ssl;
    server_name firmowiec.example.com;

    ssl_certificate /etc/letsencrypt/live/firmowiec.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/firmowiec.example.com/privkey.pem;

    root /srv/firmowiec;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }

    location /app/ {
        alias /srv/firmowiec/app/;
        try_files $uri $uri/ /app/index.html;
    }
}

Host C — api.example.com

# /etc/nginx/sites-available/api.example.com
server {
    listen 443 ssl;
    server_name api.example.com;

    ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Faza 7: Symulacja lokalna (prototypowanie)

W fazie prototypu, zanim kupisz osobne VPS, możesz symulować architekturę na jednym serwerze przez osobne porty i osobne katalogi:

# Symulacja 3 hostingów na jednym serwerze:
# Host A: prywaciarz.example.com → localhost:3001 → /srv/prywaciarz/
# Host B: firmowiec.example.com → localhost:3002 → /srv/firmowiec/
# Host C: api.example.com → localhost:3000 → /srv/api/

# 1. Uruchom backend API na porcie 3000
cd /srv/api && uvicorn main:app --host 0.0.0.0 --port 3000 &

# 2. Uruchom serwer statyczny dla Host A na porcie 3001
cd /srv/prywaciarz && python3 -m http.server 3001 --bind 0.0.0.0 &

# 3. Uruchom serwer statyczny dla Host B na porcie 3002
cd /srv/firmowiec && python3 -m http.server 3002 --bind 0.0.0.0 &

# 4. Test — Host A (prywaciarz)
curl -s http://127.0.0.1:3001/ | head -5
# Oczekiwane: HTML landing page z Incognito Browser

# 5. Test — Host B (firmowiec)
curl -s http://127.0.0.1:3002/ | head -5
# Oczekiwane: HTML landing page z EnterpriseShield

# 6. Test — API (backend)
curl -s http://127.0.0.1:3000/api/v1/health
# Oczekiwane: {"status": "ok"}

# 7. Test — SPA na Host A pobiera dane z API
curl -s http://127.0.0.1:3001/app/ | grep -c "api.example.com"
# Oczekiwane: > 0 (SPA ładuje dane z API)

Faza 8: Weryfikacja — izolacja fizyczna

Krok 8.1: Weryfikacja — każdy hosting jest niezależny

# 1. Sprawdź czy każdy hosting działa na swoim porcie
for port in 3001 3002 3000; do
  echo "Port $port: $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:$port/ || echo 'DOWN')"
done

# 2. Sprawdź czy Host A nie ma dostępu do plików Host B
curl -s http://127.0.0.1:3001/../firmowiec/index.html | head -3
# Oczekiwane: 404 lub puste (brak dostępu)

# 3. Sprawdź czy Host B nie ma dostępu do plików Host A
curl -s http://127.0.0.1:3002/../prywaciarz/index.html | head -3
# Oczekiwane: 404 lub puste

# 4. Sprawdź czy API dostępne tylko przez swój port
curl -s http://127.0.0.1:3001/api/v1/health
# Oczekiwane: 404 (Host A nie ma API)

Krok 8.2: Weryfikacja — API communication

# 1. SPA na Host A powinno zawierać fetch do API
grep -c 'api.example.com' /srv/prywaciarz/app/index.html || true
# Oczekiwane: > 0 (SPA ładuje dane z API)

# 2. SPA na Host B powinno zawierać fetch do tego samego API
grep -c 'api.example.com' /srv/firmowiec/app/index.html || true
# Oczekiwane: > 0 (ten sam backend)

# 3. Żaden hosting nie powinien mieć bezpośredniego dostępu do plików backendu
ls /srv/prywaciarz/main.py 2>/dev/null && echo "❌ ACCESS" || echo "✅ NO ACCESS"
ls /srv/firmowiec/main.py 2>/dev/null && echo "❌ ACCESS" || echo "✅ NO ACCESS"
# Oczekiwane: NO ACCESS dla obu

Krok 8.3: Raport do zatwierdzenia

hermes kanban --board convertere comment <card-id> \
  "[CEO] ✅ Prototyp v9 — osobne hostingu, API communication:

🔒 prywaciarz.example.com (Host A:3001):
  - Landing, checkout, thank-you, app SPA
  - Dane z API: https://api.example.com/api/v1/*
  - DaisyUI dark

🏢 firmowiec.example.com (Host B:3002):
  - Landing, checkout, thank-you, app SPA
  - Dane z API: https://api.example.com/api/v1/*
  - DaisyUI corporate

⚙️ api.example.com (Host C:3000):
  - FastAPI + PostgreSQL
  - CORS: prywaciarz, firmowiec
  - JWT auth, rate limiting

Weryfikacja:
✅ HTTP 200 — każdy hosting na swoim porcie
✅ Żaden hosting nie ma dostępu do plików innego
✅ SPA na obu hostingach ładuje dane z tego samego API
✅ API dostępne tylko na swoim porcie
✅ Zero współdzielonego systemu plików
⏳ Czekam na zatwierdzenie"

Architektura v9 — pełna wizualizacja

                    PRODUKCJA
                    =========

┌──────────────────────┐   ┌──────────────────────┐   ┌──────────────────────┐
│  Host A              │   │  Host B              │   │  Host C              │
│  prywaciarz.example  │   │  firmowiec.example   │   │  api.example.com     │
│  ────────────────    │   │  ────────────────    │   │  ────────────────    │
│  VPS / Docker        │   │  VPS / Docker        │   │  VPS / Docker        │
│  Port 443 (SSL)      │   │  Port 443 (SSL)      │   │  Port 443 (SSL)      │
│                      │   │                      │   │                      │
│  /srv/prywaciarz/    │   │  /srv/firmowiec/     │   │  /srv/api/           │
│  ├── index.html      │   │  ├── index.html      │   │  ├── main.py         │
│  ├── checkout/       │   │  ├── checkout/       │   │  ├── database.py     │
│  ├── thank-you/      │   │  ├── thank-you/      │   │  ├── models.py       │
│  └── app/            │   │  └── app/            │   │  └── requirements.txt│
│      └── index.html  │   │      └── index.html  │   │                      │
│          (SPA)       │   │          (SPA)       │   │  API endpoints:      │
│                      │   │                      │   │  /api/v1/health      │
│  fetch() ────────────┼───┼── fetch() ───────────┼──→│  /api/v1/auth/*      │
│                      │   │                      │   │  /api/v1/user/*      │
│                      │   │                      │   │  /api/v1/sessions/*  │
│                      │   │                      │   │  /api/v1/stats/*     │
└──────────────────────┘   └──────────────────────┘   └──────────────────────┘

                    SYMULACJA LOKALNA (prototyp)
                    ============================

┌──────────────────────┐   ┌──────────────────────┐   ┌──────────────────────┐
│  localhost:3001      │   │  localhost:3002      │   │  localhost:3000      │
│  (prywaciarz)        │   │  (firmowiec)         │   │  (api)               │
│  python3 http.server │   │  python3 http.server │   │  uvicorn main:app    │
│  /srv/prywaciarz/    │   │  /srv/firmowiec/     │   │  /srv/api/           │
└──────────────────────┘   └──────────────────────┘   └──────────────────────┘

Porównanie v8 → v9

Aspektv8v9 ✅
HostingJeden serwerOsobne VPS / Docker per persona + backend
Współdzielenie koduSymlink do _app/Brak — każdy hosting ma własny frontend
KomunikacjaBezpośredni dostęp do plikówTylko przez API (HTTPS)
AplikacjaStatyczne HTML z symlinkaSPA z fetch() do API backendu
BackendWspółdzielony plikowoOsobny serwer: FastAPI + PostgreSQL
IzolacjaLogiczna (symlinki)Fizyczna (osobne procesy, porty, VPS)
CORSNiepotrzebnyWymagany — allow origins per persona
AwariaJeden host = wszystko padaAwaria Host A = tylko Prywaciarz offline
SkalowanieSkaluje się całośćKażdą personę można skalować osobno
Koszt produkcji1 VPS (np. $5/mies)3+ VPS (np. $5+$5+$10 = $20/mies)
Koszt prototypu$0 (jeden serwer)$0 (symulacja na portach)

Playbook: 60-minutowy Builder Flow v9 (symulacja lokalna)

Przygotowanie (2 min):

Brainstorming + Persona Discovery (8 min):

Hosting Strategy (5 min):

Marketing + Hooks + Ads (8 min):

Specyfikacja (5 min):

Landing Pages per hosting (10 min):

SPA + API (10 min):

Uruchomienie (5 min):

Weryfikacja (7 min):


Mierzenie sukcesu

MetrykaTargetJak mierzyć
Hosty uruchomione3+curl -s http://127.0.0.1:3001/ && curl -s http://127.0.0.1:3002/ && curl -s http://127.0.0.1:3000/api/v1/health
HTTP 200 na każdym100%for port in 3001 3002 3000; do curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:$port/; done
Brak dostępu do plików innego hosta404`curl -s http://127.0.0.1:3001/../firmowiec/index.html \head -1`
API dostępne tylko na swoim porcie404curl -s http://127.0.0.1:3001/api/v1/health
SPA ładuje dane z API> 0grep -c 'api.example.com' /srv/prywaciarz/app/index.html
CORS skonfigurowany2 origins`grep -c 'prywaciarz\firmowiec' /srv/api/main.py`
Zero współdzielonego FSbrak`ls /srv/prywaciarz/main.py 2>/dev/null && echo FAIL \\echo OK`
Czas od pomysłu do prototypu< 60 minStoper

Źródła (Linki URL)

Źródła (Pliki)