486 lines
11 KiB
Markdown
486 lines
11 KiB
Markdown
# WebWizard - MVP Architektura
|
|
|
|
Tento dokument definuje technicku architekturu MVP. Zjednocuje projekt na jednoduchu stackovu liniu: PHP 8.2, JSON subory, Vanilla JavaScript a lokalne DAIAPI.
|
|
|
|
---
|
|
|
|
## 1. Principy MVP
|
|
|
|
* **AI website concierge, nie builder:** pouzivatel odpoveda na otazky, system pripravi export.
|
|
* **File-based persistence:** vsetky data su JSON subory.
|
|
* **AI negeneruje HTML:** AI vytvara iba strukturovany content JSON.
|
|
* **Renderer generuje HTML:** PHP rendering layer vytvara exportovatelny web z JSON dat.
|
|
* **Bez frameworkov:** ziadny backend ani frontend framework, ziadny build proces.
|
|
* **Bez domen a hostingu v MVP:** vystupom je exportovatelny webovy priecinok.
|
|
|
|
---
|
|
|
|
## 2. Celkova architektura
|
|
|
|
```ascii
|
|
[ Browser / Wizard UI ]
|
|
|
|
|
| AJAX POST /ajax.php
|
|
v
|
|
[ PHP API Layer ]
|
|
|
|
|
+--> [ JSON Storage: users, projects, consent, categories ]
|
|
|
|
|
+--> [ AI Queue: data/llm/*.json ]
|
|
|
|
|
v
|
|
[ LLMpool.php ]
|
|
|
|
|
v
|
|
[ Local DAIAPI ]
|
|
|
|
|
v
|
|
[ Content Layer: generated JSON ]
|
|
|
|
|
v
|
|
[ Rendering Layer: PHP renderer ]
|
|
|
|
|
v
|
|
[ Exported Website: HTML/CSS/assets/PHP form scripts ]
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Pouzite technologie
|
|
|
|
MVP pouziva:
|
|
|
|
* PHP 8.2,
|
|
* JSON subory,
|
|
* Composer volitelne,
|
|
* HTML,
|
|
* CSS,
|
|
* Vanilla JavaScript,
|
|
* lokalne DAIAPI.
|
|
|
|
MVP nepouziva:
|
|
|
|
* databazu,
|
|
* backend framework,
|
|
* React, Vue, Angular,
|
|
* TypeScript,
|
|
* build proces,
|
|
* cloud storage ako povinnu zavislost.
|
|
|
|
---
|
|
|
|
## 4. Adresarova struktura
|
|
|
|
```text
|
|
/
|
|
+-- data/ # Neverejne data
|
|
| +-- users/ # <user_id>.json
|
|
| +-- projects/ # <project_id>.json
|
|
| +-- consent/ # <project_id>.json alebo <user_id>.json
|
|
| +-- categories.json # Definicia kategorii a smart otazok
|
|
| +-- admin/
|
|
| | +-- pending_categories.json
|
|
| +-- llm/ # Fronta AI uloh
|
|
+-- exports/ # Exportovane weby
|
|
| +-- <project_id>/
|
|
| +-- index.html
|
|
| +-- config.json
|
|
| +-- assets/
|
|
| | +-- site.css
|
|
| | +-- site.js
|
|
| | +-- images/
|
|
| +-- messages/ # Iba lokalny formularovy mod
|
|
| +-- emailer.php # Iba SMTP mod
|
|
| +-- form-viewer.php # Iba lokalny formularovy mod
|
|
+-- src/
|
|
| +-- Actions/
|
|
| +-- Services/
|
|
| | +-- FileStorage.php
|
|
| | +-- DAIClient.php
|
|
| | +-- Renderer.php
|
|
| | +-- ConsentService.php
|
|
| +-- Prompts/
|
|
| +-- Templates/
|
|
| +-- Utils/
|
|
+-- public/
|
|
| +-- index.html
|
|
| +-- ajax.php
|
|
| +-- css/
|
|
| +-- js/
|
|
+-- vendor/
|
|
+-- composer.json
|
|
```
|
|
|
|
`data/` musi byt neverejne. Ak je webserver root nad projektom, priecinok `data/` musi byt chraneny pravidlom `.htaccess` alebo konfiguraciou servera.
|
|
|
|
---
|
|
|
|
## 5. Datove subory
|
|
|
|
### Pouzivatel
|
|
|
|
`data/users/<user_id>.json`
|
|
|
|
```json
|
|
{
|
|
"user_id": "u_9b12ef44",
|
|
"created_at": "2026-06-11T10:00:00Z",
|
|
"projects": ["p_a8f7c3d1"]
|
|
}
|
|
```
|
|
|
|
### Projekt
|
|
|
|
`data/projects/<project_id>.json`
|
|
|
|
```json
|
|
{
|
|
"project_id": "p_a8f7c3d1",
|
|
"user_id": "u_9b12ef44",
|
|
"status": "draft",
|
|
"current_step": 2,
|
|
"wizard_data": {},
|
|
"content": {
|
|
"generated": null,
|
|
"generated_at": null
|
|
},
|
|
"export": {
|
|
"path": "exports/p_a8f7c3d1",
|
|
"generated_at": null
|
|
},
|
|
"created_at": "2026-06-11T10:00:00Z",
|
|
"updated_at": "2026-06-11T10:05:00Z"
|
|
}
|
|
```
|
|
|
|
### Stavy projektu
|
|
|
|
* `draft` - wizard je rozpracovany,
|
|
* `queued` - AI uloha je vo fronte,
|
|
* `generating` - DAIAPI spracovava ulohu,
|
|
* `content_ready` - AI JSON je ulozeny,
|
|
* `rendering` - renderer vytvara export,
|
|
* `export_ready` - export je pripraveny,
|
|
* `failed` - generovanie alebo render zlyhalo.
|
|
|
|
---
|
|
|
|
## 6. Wizard Data Schema
|
|
|
|
`wizard_data` je kanonicky vstupny model pre AI aj renderer.
|
|
|
|
```json
|
|
{
|
|
"identity": {
|
|
"business_name": "Pizza Marco",
|
|
"tagline": "Poctiva pizza v Kosiciach",
|
|
"description": "Rodinna pizzeria zamerana na donasku a denne menu"
|
|
},
|
|
"contact": {
|
|
"email": "info@pizzamarco.sk",
|
|
"phone": "+421 900 000 000",
|
|
"address": "Hlavna 1, Kosice",
|
|
"city": "Kosice",
|
|
"region": "Kosicky kraj",
|
|
"socials": {
|
|
"facebook": "https://facebook.com/pizzamarco",
|
|
"instagram": "https://instagram.com/pizzamarco"
|
|
}
|
|
},
|
|
"services": {
|
|
"items": [
|
|
{
|
|
"name": "Donaska pizze",
|
|
"description": "Rozvoz po Kosiciach",
|
|
"price_from": "7 EUR"
|
|
}
|
|
],
|
|
"pricing_note": "Ceny su orientacne."
|
|
},
|
|
"visuals": {
|
|
"style": "modern",
|
|
"color_scheme": {
|
|
"primary": "#C62828",
|
|
"secondary": "#F8F1E7",
|
|
"accent": "#2E7D32",
|
|
"background": "#FFFFFF",
|
|
"text": "#1A1A1A"
|
|
},
|
|
"font_style": "sans",
|
|
"layout_density": "comfortable"
|
|
},
|
|
"modules": {
|
|
"pages": ["home"],
|
|
"sections": ["hero", "about", "services", "pricing", "gallery", "faq", "contact"],
|
|
"contact_form": {
|
|
"enabled": true,
|
|
"mode": "local",
|
|
"smtp": null,
|
|
"local_viewer": {
|
|
"password_hash": "$2y$..."
|
|
}
|
|
}
|
|
},
|
|
"assets": {
|
|
"logo": {
|
|
"uploaded": true,
|
|
"path": "assets/images/logo.png",
|
|
"alt": "Logo Pizza Marco"
|
|
},
|
|
"images": [
|
|
{
|
|
"path": "assets/images/interior.jpg",
|
|
"alt": "Interier pizzerie"
|
|
}
|
|
],
|
|
"image_source": "uploaded"
|
|
},
|
|
"language": {
|
|
"primary": "sk",
|
|
"additional": [],
|
|
"tone": "friendly"
|
|
},
|
|
"business_category": {
|
|
"group": "gastro",
|
|
"subcategory": "restaurant",
|
|
"custom_description": null
|
|
},
|
|
"smart_answers": {
|
|
"delivery": true,
|
|
"daily_menu": true,
|
|
"reservations": false,
|
|
"opening_hours": "Po-Pia 10:00-21:00"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Vyznam sekcii
|
|
|
|
* `identity` - nazov, slogan a popis firmy; AI nesmie tieto fakty menit.
|
|
* `contact` - kontaktne udaje pouzite v hlavicke, pate a formulari.
|
|
* `services` - zoznam sluzieb, produktov alebo balikov.
|
|
* `visuals` - dizajnovy smer, farby, typografia a hustota layoutu.
|
|
* `modules` - zoznam sekcii a konfiguracia funkcnych modulov.
|
|
* `assets` - logo, obrazky, alt texty a zdroj obrazkov.
|
|
* `language` - primarny jazyk a ton komunikacie.
|
|
* `business_category` - kategoria, podkategoria alebo vlastny typ podnikania.
|
|
* `smart_answers` - odpovede na dynamicke otazky podla segmentu.
|
|
|
|
---
|
|
|
|
## 7. GDPR suhlas
|
|
|
|
V kroku wizardu s identitou a kontaktom je povinny checkbox:
|
|
|
|
> Suhlasim so spracovanim zadanych udajov za ucelom vytvorenia webovej stranky.
|
|
|
|
Bez zaskrtnutia backend odmietne `saveStep` pre krok identity aj `generateWebsite`.
|
|
|
|
Suhlas sa uklada do `data/consent/<project_id>.json`:
|
|
|
|
```json
|
|
{
|
|
"project_id": "p_a8f7c3d1",
|
|
"user_id": "u_9b12ef44",
|
|
"consent_text_version": "webwizard-mvp-2026-06-11",
|
|
"consent_text": "Suhlasim so spracovanim zadanych udajov za ucelom vytvorenia webovej stranky.",
|
|
"accepted": true,
|
|
"accepted_at": "2026-06-11T10:05:00Z"
|
|
}
|
|
```
|
|
|
|
Backend eviduje cas suhlasu v UTC a verziu textu suhlasu. Ak sa text suhlasu zmeni, verzia sa zvysi a pouzivatel musi potvrdit novu verziu.
|
|
|
|
---
|
|
|
|
## 8. Identifikacia pouzivatela
|
|
|
|
MVP pouziva `localStorage` a HTTP hlavicku.
|
|
|
|
1. Frontend skontroluje `localStorage.getItem('ww_user_id')`.
|
|
2. Ak hodnota chyba, zavola `initSession`.
|
|
3. Backend vytvori `user_id`, ulozi `data/users/<user_id>.json` a vrati ho.
|
|
4. Frontend posiela `X-User-ID` v kazdej AJAX poziadavke.
|
|
|
|
`user_id` nie je plnohodnotna autentifikacia. Je to MVP identifikator rozpracovanych projektov v jednom prehliadaci.
|
|
|
|
---
|
|
|
|
## 9. AJAX API
|
|
|
|
Vsetky poziadavky smeruju na:
|
|
|
|
```text
|
|
POST /ajax.php
|
|
Content-Type: application/json
|
|
X-User-ID: u_9b12ef44
|
|
```
|
|
|
|
Priklad poziadavky:
|
|
|
|
```json
|
|
{
|
|
"action": "saveStep",
|
|
"project_id": "p_a8f7c3d1",
|
|
"payload": {
|
|
"step": 2,
|
|
"data": {}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Jednotny format odpovedi
|
|
|
|
Uspech:
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {}
|
|
}
|
|
```
|
|
|
|
Chyba:
|
|
|
|
```json
|
|
{
|
|
"success": false,
|
|
"error": {
|
|
"code": "ERROR_CODE",
|
|
"message": "Human readable message"
|
|
}
|
|
}
|
|
```
|
|
|
|
Ine formaty odpovedi nie su povolene.
|
|
|
|
### Akcie
|
|
|
|
* `initSession` - vytvori pouzivatela.
|
|
* `listProjects` - vrati projekty pouzivatela.
|
|
* `createProject` - vytvori projekt v stave `draft`.
|
|
* `saveStep` - ulozi cast `wizard_data` a validuje ju.
|
|
* `saveConsent` - ulozi GDPR suhlas s verziou textu.
|
|
* `generateWebsite` - zaradi AI ulohu do fronty.
|
|
* `getProjectStatus` - vrati stav projektu, chybu a cestu exportu.
|
|
* `renderWebsite` - pregeneruje HTML z uz existujuceho content JSON.
|
|
* `exportWebsite` - vrati informacie o exportnom priecinku alebo archive.
|
|
|
|
---
|
|
|
|
## 10. AI workflow
|
|
|
|
`generateWebsite` vytvori ulohu:
|
|
|
|
```json
|
|
{
|
|
"task_id": "t_123",
|
|
"project_id": "p_a8f7c3d1",
|
|
"status": "queued",
|
|
"attempt_count": 0,
|
|
"max_attempts": 3,
|
|
"created_at": "2026-06-11T10:10:00Z",
|
|
"wizard_data": {}
|
|
}
|
|
```
|
|
|
|
`LLMpool.php`:
|
|
|
|
1. zamkne ulohu,
|
|
2. nastavi projekt na `generating`,
|
|
3. nacita prompt zo `src/Prompts/`,
|
|
4. posle poziadavku do DAIAPI,
|
|
5. validuje, ze odpoved je JSON bez HTML,
|
|
6. ulozi `content.generated`,
|
|
7. spusti renderer,
|
|
8. nastavi stav `export_ready` alebo `failed`.
|
|
|
|
Retry pravidla:
|
|
|
|
* maximalne 3 pokusy,
|
|
* `attempt_count` sa zvysuje pri kazdom pokuse,
|
|
* posledna chyba sa ulozi do projektu,
|
|
* po prekroceni limitu sa stav nastavi na `failed`.
|
|
|
|
---
|
|
|
|
## 11. Kontaktny formular
|
|
|
|
### SMTP mod
|
|
|
|
Pouzivatel vyplni:
|
|
|
|
* SMTP host,
|
|
* port,
|
|
* username,
|
|
* password,
|
|
* encryption,
|
|
* recipient email.
|
|
|
|
Export obsahuje `emailer.php`, ktory odosiela spravy cez SMTP.
|
|
|
|
### Lokalny mod
|
|
|
|
Ak SMTP nie je nastaveny, formular uklada spravy do:
|
|
|
|
```text
|
|
messages/YYYY-MM-DD-HHMMSS.json
|
|
```
|
|
|
|
Export obsahuje `form-viewer.php`:
|
|
|
|
* prihlasenie heslom,
|
|
* PHP session,
|
|
* logout,
|
|
* zoznam sprav,
|
|
* detail spravy.
|
|
|
|
---
|
|
|
|
## 12. Website Quality Requirements
|
|
|
|
Kazdy export musi splnat:
|
|
|
|
* mobile responsive design,
|
|
* zakladne SEO meta tagy,
|
|
* OpenGraph meta tagy,
|
|
* alt texty pre obrazky,
|
|
* minimalne accessibility poziadavky,
|
|
* validny HTML,
|
|
* validny CSS,
|
|
* bez JavaScript chyb,
|
|
* ziadne externe zavislosti okrem explicitne povolenych,
|
|
* relativne URL,
|
|
* fungovanie bez build procesu.
|
|
|
|
Renderer nesmie zapisovat absolutne URL zavisle od konkretnej domeny.
|
|
|
|
---
|
|
|
|
## 13. Bezpecnostne minimum
|
|
|
|
* validacia vsetkych vstupov,
|
|
* escapovanie hodnot pri renderovani HTML,
|
|
* ochrana proti path traversal,
|
|
* upload limit pre logo a obrazky,
|
|
* kontrola pripony aj MIME typu,
|
|
* zakaz spustitelnych uploadov,
|
|
* limit velkosti AI vstupu,
|
|
* rate limit na AJAX akcie podla `user_id`,
|
|
* `data/` nepristupne z webu,
|
|
* formularove skripty nesmu citat subory mimo svoj exportny priecinok.
|
|
|
|
---
|
|
|
|
## 14. Buduce rozsirenia mimo MVP
|
|
|
|
* prihlasovanie emailom a heslom,
|
|
* databazove ulozisko,
|
|
* vlastne domeny,
|
|
* DNS a SSL,
|
|
* automaticke nasadenie na hosting,
|
|
* drag-and-drop editor,
|
|
* viacjazycnost jednym klikom,
|
|
* booking integracie,
|
|
* AI generovanie obrazkov.
|