Files
WebWizard/docs/architecture.md

6.8 KiB

WebWizard - MVP Architektúra

Tento dokument definuje technickú architektúru pre prvú verziu (MVP) projektu WebWizard. Cieľom je maximálna jednoduchosť, rýchlosť vývoja a nulová závislosť na komplexných infraštruktúrach (databáza, cloud služby).


1. Celková architektúra systému

Systém funguje na princípe Single-Page Application (SPA) komunikujúcej s tenkým Backendom cez AJAX.

[ Používateľ (Prehliadač) ]
      |
      | AJAX (POST /ajax.php)
      v
[ PHP Backend (ajax.php) ] <----> [ Súborový systém (JSON & HTML) ]
      |
      | Lokálne API Call (HTTP)
      v
[ AI Engine (DAIAPI) ]

Princípy:

  • Stateless Backend: PHP neudržiava session v pamäti, identita používateľa sa posiela v každej požiadavke.
  • File-based Persistence: Všetky dáta sú v JSON súboroch.
  • Local AI Integration: Systém využíva lokálnu inštanciu DAIAPI, čo znižuje latenciu a náklady.
  • Decoupled Frontend: Frontend je čisté HTML/JS, ktoré možno hostovať kdekoľvek.

2. Použité technológie

  • Backend: PHP 8.2+ (bez frameworku).
  • Frontend: Vanilla JavaScript (ES6+), HTML5, Vanilla CSS.
  • AI: DAIAPI (lokálne HTTP rozhranie pre LLM).
  • Server: Apache/Nginx s podporou .htaccess (na ochranu dátových priečinkov).
  • Balíčkovací manažér: Composer (voliteľne pre pomocné knižnice).

3. Adresárová štruktúra

/
├── data/               # NEPRÍSTUPNÉ Z WEBU (.htaccess deny all)
│   ├── users/          # <user_id>.json
│   ├── projects/       # <project_id>.json
│   └── llm/            # Fronta úloh pre AI (prikazy.json)
├── sites/              # PRÍSTUPNÉ Z WEBU (Vygenerované weby)
│   └── a8f7c3d1/       # Konkrétny vygenerovaný web
│       ├── index.html
│       ├── assets/
│       ├── images/
│       └── config.json # Kópia konfigurácie pre daný export
├── src/                # PHP Logika
│   ├── Actions/        # Triedy pre jednotlivé AJAX akcie
│   ├── Services/       # AI Engine (LLMpool.php), FileStorage, Renderer
│   ├── Prompts/        # Externé prompty (.txt, .md)
│   └── Utils/          # Helpery
├── public/             # Root webservera
│   ├── index.html      # Hlavná aplikácia (Wizard)
│   ├── ajax.php        # Jediný vstupný bod pre API
│   ├── css/
│   └── js/
├── vendor/             # Composer závislosti
└── composer.json

4. Štruktúra dát (JSON)

Používateľ (data/users/<user_id>.json)

{
  "user_id": "u_9b12ef44",
  "created_at": "2026-06-11T10:00:00Z",
  "projects": ["p_a8f7c3d1", "p_b2c3d4e5"]
}

Projekt (data/projects/<project_id>.json)

{
  "project_id": "p_a8f7c3d1",
  "user_id": "u_9b12ef44",
  "status": "in_progress",
  "current_step": 3,
  "wizard_data": {
    "business_type": "restaurant",
    "name": "Pizza Marco",
    "city": "Košice"
  },
  "generated_at": null,
  "site_path": "/sites/a8f7c3d1/"
}

5. Identifikácia používateľa

Riešenie: LocalStorage + HTTP Header.

  1. Pri prvej návšteve JS skontroluje localStorage.getItem('ww_user_id').
  2. Ak neexistuje, pošle požiadavku na action=initSession.
  3. Backend vygeneruje unikátny hash (napr. bin2hex(random_bytes(8))) a vráti ho.
  4. JS ho uloží do localStorage.
  5. V každej ďalšej AJAX požiadavke sa tento ID posiela v HTTP hlavičke X-User-ID.

Zdôvodnenie:

  • Čistejšie API: Payload obsahuje len dáta súvisiace s akciou, identita je v metadátach (hlavičkách).
  • Jednoduchšia autorizácia na úrovni backendu ešte pred parsovaním JSON tela.
  • LocalStorage je pre SPA prirodzenejší a nevyžaduje riešenie CSRF tokenov v takej miere ako automaticky posielané cookies.

6. AJAX Komunikácia

Všetky požiadavky smerujú na public/ajax.php.

Formát požiadavky:

POST /ajax.php Content-Type: application/json X-User-ID: u_9b12ef44

{
  "action": "saveStep",
  "project_id": "p_a8f7c3d1",
  "payload": {
    "step": 2,
    "data": { "name": "Pizza Marco" }
  }
}

Zoznam akcií:

  • initSession: Vytvorí nového používateľa.
  • listProjects: Vráti zoznam projektov používateľa.
  • createProject: Inicializuje nový projekt.
  • saveStep: Uloží rozpracované dáta z wizardu.
  • generateWebsite: Spustí AI generovanie a vytvorí súbory.
  • getProjectStatus: Pre polling počas generovania.

7. Generovanie a publikovanie (Asynchrónny proces)

Kvôli eliminácii timeoutov a stabilite generovania využíva systém LLM Pool.

Workflow:

  1. Vytvorenie úlohy: AJAX akcia generateWebsite nezavolá AI hneď. Zapíše JSON súbor do /data/llm/<task_id>.json, ktorý obsahuje vstupné dáta z wizardu a cieľové cesty.
  2. Spracovanie (LLMpool.php):
    • Skript spúšťaný cez Cron (napr. každú minútu) prechádza zložku /data/llm/.
    • Pre každú úlohu načíta príslušný Prompt zo zložky /src/Prompts/.
    • Nahradí premenné v prompte (napr. [BUSINESS_TYPE]) reálnymi dátami.
    • Pošle požiadavku do DAIAPI.
  3. Dynamické generovanie:
    • Systém nepoužíva fixné HTML šablóny.
    • AI inštruujeme, aby vygenerovalo kompletný kód (HTML/CSS) na mieru.
  4. Zápis a Cleanup:
    • Po úspešnom vygenerovaní skript vytvorí súbory v /sites/<project_id>/.
    • Až po úspešnom zápise sa úloha z /data/llm/ odstráni.
    • Retry mechanizmus: Ak DAIAPI zlyhá, súbor s úlohou ostáva v zložke a skript sa ho pokúsi spracovať v ďalšom behu.

8. Správa dát a Limity (Storage Management)

  1. Ochrana dát: .htaccess v priečinku /data/ s obsahom Deny from all.
  2. Uploady:
    • Limit na veľkosť súboru (napr. max 2MB pre logo).
    • Kontrola povolených prípon (jpg, png, svg) a overenie MIME typu na strane PHP.
  3. Storage Cleanup:
    • Ak celkový objem dát v /sites/ presiahne stanovenú kvótu, systém automaticky premaže najstaršie projekty (FIFO - First In, First Out).
  4. Sanitizácia: PHP htmlspecialchars() pri renderovaní, ak je to potrebné, a validácia vstupov proti Path Traversal.

9. Budúce rozširovanie

  • Databáza: Trieda FileStorageService sa nahradí DatabaseStorageService implementujúcou rovnaké rozhranie.
  • Vlastné domény: Webserver sa nakonfiguruje tak, aby doména smerovala do konkrétneho /sites/<id>/ priečinka. Relatívne URL toto umožňujú bez zmeny kódu.
  • Editor: Pridá sa nová AJAX akcia updateContent, ktorá prepíše konkrétne časti v index.html alebo v config.json a znova vyrenderuje stránku.
  • Auth: Pridá sa tabuľka (alebo JSON) credentials, ktorá prepojí user_id s emailom a heslom.