Files
FDMTech/CMS_CONTRACT.md
T

33 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Kontrakt CMS FDMTech — v1
Właściciel schematu: backend CI4 w `/workspace/Sensory/sensory.fdmtech.pl`. Dedykowana baza CMS (grupa CI4 `cms`); renderer PDO nigdy nie korzysta z bazy ani tabel telemetrii. Brak konfiguracji/zmian produkcyjnych w ramach implementacji. Wszystkie daty CMS: UTC, `Y-m-d H:i:s`. Tabele bez prefiksu.
## `cms_pages`
`id` INT PK auto, `slug` VARCHAR(160) UNIQUE, `title` VARCHAR(200), `draft_json` MEDIUMTEXT (projekt GrapesJS), `draft_html` MEDIUMTEXT, `draft_css` MEDIUMTEXT, `draft_seo_title` VARCHAR(200), `draft_seo_description` VARCHAR(320), `published_html` MEDIUMTEXT NULL, `published_css` MEDIUMTEXT NULL, `seo_title` VARCHAR(200) NULL, `seo_description` VARCHAR(320) NULL, `published_title` VARCHAR(200) NULL, `status` VARCHAR(20) (`draft`/`published`), `published_at` DATETIME NULL, `version` INT (optymistyczna blokada), `created_by` INT, `updated_by` INT, `created_at`, `updated_at` DATETIME.
Slug pojedynczy: `[a-z0-9]+(?:-[a-z0-9]+)*`; `home` oznacza `/`. Slug jest stały po utworzeniu. `title` jest roboczy; publicznie używaj `published_title`. Zapis szkicu nie zmienia publicznych pól ani statusu. Publikacja atomowo ustawia HTML/CSS, tytuł, SEO i datę oraz tworzy rewizję. Wycofanie zmienia status na `draft`.
Odczyt PDO (parametryzowany):
```sql
SELECT id, slug, published_title AS title, published_html, published_css,
seo_title, seo_description, published_at
FROM cms_pages WHERE slug = :slug AND status = 'published'
AND published_at IS NOT NULL LIMIT 1;
```
Brak rekordu = 404 / jawny fallback aplikacji. Nigdy nie czytaj `draft_*`. Payload to fragment body HTML i osobny arkusz CSS po restrykcyjnej filtracji serwerowej. Renderer escapiuje tytuły/SEO, osadza HTML w kontenerze `<main id="cms-content">` (wymagane: CSS jest ograniczony do tego ID), CSS jako arkusz/element style; zalecany CSP bez skryptów treści. Nie wykonuje projektu JSON. Obrazy mają absolutne URL endpointu Sensory `/cms-media/{losowa-nazwa}`.
## `cms_settings`
`key` VARCHAR(80) PK, `value` TEXT (JSON), `updated_at` DATETIME.
Klucze: `site_name` (string), `contact_email` (string), `contact_phone` (string), `navigation` (tablica obiektów `{label:string,url:string}`). `SELECT \`key\`, \`value\` FROM cms_settings`. JSON dekodować i walidować typy, tekst/atrybuty escapować. Brak klucza: domyślna wartość renderera. Nawigacja dopuszcza lokalne ścieżki zaczynające się pojedynczym `/` i HTTPS.
## `cms_inquiries`
`id` INT PK auto, `name` VARCHAR(160), `email` VARCHAR(254), `company` VARCHAR(200) domyślnie pusty, `phone` VARCHAR(60) domyślnie pusty, `message` TEXT, `source` VARCHAR(160) domyślnie `audit`, `consent_at` DATETIME NOT NULL, `status` VARCHAR(20) domyślnie `new` (`new`, `in_progress`, `closed`), `created_at` DATETIME NOT NULL, `updated_at` DATETIME NOT NULL.
Renderer może INSERT wyłącznie jawnych pól: name, email, company, phone, message, source, consent_at, created_at, updated_at. Status nadawany przez DB. Walidacja: name 1–160, poprawny email <=254, company <=200, phone <=60, message 1–10000, source <=160. Zgoda wymagana; czas UTC po stronie serwera. CSRF, honeypot/rate limit i limity żądania są odpowiedzialnością formularza publicznego. Nie udostępniać odczytu skrzynki publicznie.
## Tabele prywatne
`cms_revisions` (snapshot projektu, HTML/CSS i metadanych przy publikacji), `cms_media` (metadane bezpiecznych obrazów). Renderer ich nie potrzebuje. Bez FK do użytkowników/telemetrii Sensory.
## Uprawnienia połączenia publicznego
SELECT tylko na `cms_pages` i `cms_settings`; INSERT tylko na `cms_inquiries`. Dla ścisłego oddzielenia szkiców nadać SELECT na wskazane kolumny publiczne `cms_pages` zamiast całej tabeli. Bez UPDATE/DELETE i bez dostępu do pozostałych baz. Dane dostępu PDO i CI4 dostarcza operator poza repo. Migracje uruchamia operator wyłącznie po weryfikacji docelowej bazy.