Centurio Süsteem- & modulidokumendid
🏛️ Platvorm arhitektuur 🔑 Login
Kõik moodulid / core_platform / Webseite & Shop
📘

Webseite & Shop

sites core_platform 🛡️ RLS Protected

Webseite & Shop — aus Code abgeleitete Prozess- und API-Dokumentation.

Fachliche Bestimmung: Website & Webshop veröffentlicht den Auftritt des Mandanten mehrsprachig mit geprüften Design-Themes, versionierten Pflicht-Rechtstexten und einem Shop, dessen Bestellungen als angenommenes Angebot ins ERP übergehen und – mit Einwilligung – als Marketing-Conversion zählen. Formulare erzeugen Leads und Newsletter-Einwilligungen im Double-Opt-in.

⚡ Töövoogud ja elutsüklid

Benutzerbefehl: website agent plan:command_website_agent

Kontrollitud püsivkava (durable_plan), algus: manuell_command.

1. website_agent
website_agent
{"key": "execute_command", "label": "Befehl prüfen, ausführen oder zur Freigabe vorlegen", "adapter": "agent.execute", "agent": "website_agent", "condition_fact": null}
Aktionen: website_agent

⚙️ Fachprozesse & Capabilities (System-Fachlogik)

Registrierte Fachoperationen und System-Capabilities dieses Moduls zur Steuerung von Workflows, Kaskaden und KI-Agenten.

Gesamt: 11 manual_entry: 1 engine: 9 durable_plan: 1
Capability & Schlüssel Fachliche Bezeichnung Ausführung / Coverage Risikostufe & Freigabe Effekte & Kaskaden
Agent-Einstieg website_agent agent_entry:website_agent
Agent-Einstieg website_agent
Quelle: code:module_agent_map
manual_entry
✓ Auto
Keine Seiteneffekte deklariert
Rechtstext-Vorlage erzeugen capability:sites.legal.draft
Op: sites.legal.draft
Intent: sites_legal_draft
Quelle: code:capability_registry
⚙️ Engine
✓ Auto Risiko: metadata
  • legal_text.drafted
Rechtstext veröffentlichen capability:sites.legal.publish
Op: sites.legal.publish
Intent: sites_legal_publish
Quelle: code:capability_registry
⚙️ Engine
🔒 Freigabe nötig Risiko: external_effect
  • legal_text.published
Shop-Artikel veröffentlichen capability:sites.offering.save
Op: sites.offering.save
Intent: sites_offering_save
Quelle: code:capability_registry
⚙️ Engine
✓ Auto Risiko: business_record
  • shop_offering.saved
Shop-Bestellung ans ERP übergeben capability:sites.order.handover
Op: sites.order.handover
Intent: sites_order_handover
Quelle: code:capability_registry
⚙️ Engine
✓ Auto Risiko: business_record
  • shop_order.erp_handover
  • quote.accepted
Shop-Bestellstatus ändern capability:sites.order.transition
Op: sites.order.transition
Intent: sites_order_transition
Quelle: code:capability_registry
⚙️ Engine
🔒 Freigabe nötig Risiko: business_record
  • shop_order.status_changed
Webseiten-Entwurf anlegen capability:sites.page.draft
Op: sites.page.draft
Intent: sites_page_draft
Quelle: code:capability_registry
⚙️ Engine
✓ Auto Risiko: business_record
  • site_page.drafted
Webseite veröffentlichen capability:sites.page.publish
Op: sites.page.publish
Intent: sites_page_publish
Quelle: code:capability_registry
⚙️ Engine
🔒 Freigabe nötig Risiko: external_effect
  • site_page.published
Webseite/Shop schalten capability:sites.site.publish
Op: sites.site.publish
Intent: sites_site_publish
Quelle: code:capability_registry
⚙️ Engine
🔒 Freigabe nötig Risiko: external_effect
  • site.status_changed
Design anwenden capability:sites.theme.apply
Op: sites.theme.apply
Intent: sites_theme_apply
Quelle: code:capability_registry
⚙️ Engine
✓ Auto Risiko: metadata
  • site.theme_changed
Benutzerbefehl: website agent plan:command_website_agent
Benutzerbefehl: website agent
Quelle: code:reviewed_execution_plan
durable_plan
✓ Auto
Keine Seiteneffekte deklariert

🧠 Fachprozess-Erzählung & Dual Knowledge Architektur

Synthese aus der ideologischen Blaupause (Meta-Fachlogik / Soll), der faktischen System-Implementierung (System-Fachlogik / Ist) und No-Code Customizing für KI-Consultants.

Dual Knowledge Layer
📖

Der durchgängige Businessprozess im Detail (End-to-End Fließtext-Erzählung)

Vom Seitenentwurf bis zur bezahlten Shop-Bestellung

1. Webseite einrichten und gestalten

Die Webseite (sites) trägt Name, Sprachen, Kontakt, Preisanzeige (brutto/netto), Versand und Formularschalter. Das Design kommt aus acht Themes (app.modules.sites.themes), die in hellem und dunklem Modus WCAG-AA-Kontrast erreichen; eigene Marken- und Akzentfarben werden gegen dieselben Paare geprüft (brand_problems), bevor sie gespeichert werden. Das Speichern des Designs verändert weder Veröffentlichungs- noch Shop-Status (cap:sites.theme.apply).

2. Seiten bauen

Seiten (site_pages) bestehen aus typisierten Bausteinen: Hero, Text, Bild + Text, Produktraster, Kontakt, Rechtstexte-Links, Kontaktformular, Newsletter, Aktion. Texte werden beim Speichern bereinigt (kein Script, kein Style, Links nur https/mailto/tel oder seiteninterne Pfade). Slugs sind je Sprache eindeutig; reservierte Pfade (shop, checkout, order, legal, form, cart, sitemap.xml) sind gesperrt. Entwürfe entstehen manuell oder KI-unterstützt (tool:generate_site_page_content, semantischer Einstieg site_page.generate mit Intent sites_page_generate); persistiert wird immer über cap:sites.page.draft, veröffentlicht wird mit dem Verwaltungsrecht (cap:sites.page.publish). Ohne KI-Provider erzeugt ein deterministischer Fallback den Entwurf.

3. Rechtstexte versionieren

Impressum, AGB, Widerrufsbelehrung, Datenschutz und Versandinformationen (legal_texts) entstehen als Gliederung aus den Stammdaten (cap:sites.legal.draft). Veröffentlichen (cap:sites.legal.publish) friert die Version mit Datum und Person ein; die Vorversion wird abgelöst, nicht überschrieben. Ohne alle Pflichttexte lässt sich die Webseite nicht veröffentlichen (cap:sites.site.publish).

4. Sortiment und Preise

Shop-Artikel (shop_product_offerings) verweisen auf Katalogprodukte. Preise sind Netto-Katalogpreise mit optionaler Netto-Überschreibung; der Steuersatz kommt vom Produkt oder aus der Mandanten-Standardregel. Die Anzeige folgt der Einstellung „brutto“ oder „netto“ mit Versandhinweis. Bestand begrenzt die Bestellmenge, außer der Artikel erlaubt Nachlieferung (allow_backorder).

5. Bestellen

Der Warenkorb wird serverseitig bepreist (POST /site/{slug}/{lang}/cart/price), inklusive Gutscheinrabatt (PromotionService) als negativer Position je Steuersatz und Versandposition. Der Checkout ist idempotent über ein signiertes Formular-Token, die Schaltfläche lautet „Zahlungspflichtig bestellen“. Bestellnummern werden unter Sperre vergeben; die Bestellung erhält ein Zugriffstoken, gespeichert wird nur dessen Hash. Gutscheine werden mit Bezug shop:{Bestellnummer} eingelöst; Klick-IDs werden nur mit Tracking-Einwilligung übernommen.

6. Bezahlen

Stripe Checkout und PayPal Orders werden über ihre Webhooks (/site/hooks/stripe/{slug}, /site/hooks/paypal/{slug}) bestätigt; Betrag und Währung müssen exakt zur Bestellung passen, Stripe-Signaturen älter als 300 Sekunden werden verworfen. Vorkasse/Rechnung bleibt „bestellt“. Den Status „bezahlt“ setzt nie eine Person von Hand und nie ein Agent.

7. Übergabe ins ERP und Marketing

Bei „bezahlt“ oder „bestellt“ übergibt SiteService.handover_to_erp die Bestellung: Kunde finden oder anlegen, Angebot anlegen und annehmen (portal_kind order, Kundenreferenz shop:{Nummer}), Ereignis QUOTE_ACCEPTED. Zusätzlich entsteht SHOP_ORDER_PAID; die MarketingEventBridge bildet daraus die Conversion und bestätigt sie finanziell. Storno und Erstattung kehren Gutscheineinlösungen um.

8. Formulare

Kontaktformular → Lead über LeadMarketingService (Honigtopf, Mindestausfüllzeit, Ratenbegrenzung). Newsletter → Bestätigungsmail; die Einwilligung wird erst beim bestätigenden POST gespeichert (Double-Opt-in).

🏛️

Meta-Fachlogik: Ideologische Blaupause, Soll-Weltbild & Normen

Meta-Fachlogik

  • Der Shop ist Kanal, nicht Buchhaltung: Bestellungen werden zu Angeboten und Aufträgen im ERP; Rechnungen, Zahlungsabgleich und Bestand bleiben in ihren Modulen.
  • Keine optimistischen Zustände: „bezahlt“ nur mit verifiziertem Anbieter-Webhook und passendem Betrag.
  • Recht ist versioniert: Veröffentlichte Rechtstexte werden nie überschrieben; jede Bestellung zeigt die zum Zeitpunkt gültige Fassung.
  • Privacy by Design: Kein Cookie, keine IP-Speicherung; Tracking nur mit Einwilligung je Zweck.
  • KI assistiert: Entwürfe und Vorschläge; Veröffentlichen, Design anwenden, Bestellstatus und Zahlung bleiben menschlich.
⚙️

Systemische Fachlogik: Faktische Umsetzung in Centurio ERP & Capabilities

Systemische Fachlogik

  • Services: SiteService, Themes app.modules.sites.themes, Zahlungen app.modules.sites.payments, Storefront app.modules.sites.public, Backoffice app.modules.sites.web.
  • Tabellen: sites, site_pages, legal_texts, shop_product_offerings, shop_orders, shop_order_events, shop_payment_settings (Geheimnisse verschlüsselt).
  • Ereignisse: SHOP_ORDER_PAID, QUOTE_ACCEPTED; Marketing-Bridge bestätigt die Conversion.
  • Rechte: Modul sites; Veröffentlichen und Zahlungseinstellungen erfordern Verwaltungsrecht.
  • KI: Agent website_agent, Capabilities sites_ops, Werkzeug generate_site_page_content, semantischer Einstieg site_page.generate (Intent sites_page_generate), Rolle website_editor.
  • Custom Fields/No-Code: Sites-Objekte sind nicht in CUSTOMIZABLE_OBJECTS und FORM_SURFACES, solange kein geprüfter Lese-/Schreibadapter mit echter Formularfläche existiert; es werden keine Scheinfelder angeboten.
🤖

KI-Consultant Leitfaden: Customizing- & No-Code-Konzept (Soll-Ist-Synthese)

AI Solution Architect Blueprint

KI-Consultant Blueprint

  1. Stand lesen (tool:get_site_overview, tool:get_site_readiness) und fehlende Pflichtpunkte nennen.
  2. Theme passend zur Branche vorschlagen (tool:suggest_site_theme) mit Kontrastnachweis.
  3. Seitenentwurf per KI-Auftrag (tool:generate_site_page_content) oder aus Bausteinen (tool:draft_site_page), Rechtstext-Gliederung (tool:draft_legal_from_stammdaten) nur nach Bestätigung anlegen – nie veröffentlichen.
  4. Sortimentslücken zeigen (tool:suggest_shop_articles); Auswahl bleibt menschlich.
  5. Keine Rechtsberatung; auf die Prüfung der Rechtstexte durch Fachleute hinweisen.

📚 Operative Prozessbegriffe & Transaktionsschnittstellen

Zentrale Fachbegriffe im Prozesszusammenhang (Operatives Modell)
Theme
Farb- und Typografiesatz mit geprüftem Kontrast (hell/dunkel)
Baustein
Typisierter Seitenabschnitt (Hero, Text, Formular …)
Rechtstext-Version
Eingefrorene veröffentlichte Fassung mit Datum und Person
Preisanzeige
Brutto (Verbraucher) oder netto (Geschäftskunden) mit Versandhinweis
Übergabe
Shop-Bestellung wird angenommenes Angebot im ERP
Double-Opt-in
Newsletter-Einwilligung erst nach bestätigtem Link
📥 Eingänge & Trigger (Inputs)
  • Stammdaten des Mandanten
  • Katalogprodukte mit Preis und Steuersatz
  • Zahlungsanbieter-Zugänge
  • Gutscheincodes aus dem Marketing
📤 Ausgänge & Arbeitsergebnisse (Outputs)
  • Veröffentlichte Webseite mit Sitemap
  • Shop-Bestellungen
  • Angenommene Angebote im ERP
  • Leads und Newsletter-Einwilligungen
  • Marketing-Conversions
⚡ Kaskaden & Folgeprozesse (Cascades)
  • shop order paid -> SHOP_ORDER_PAID -> conversion_confirmed
  • shop order paid/ordered -> handover -> QUOTE_ACCEPTED
  • shop order cancelled/refunded -> promotion_redemption_reversed
  • contact form -> crm_lead + marketing_lead_profile
  • newsletter confirm -> consent_record
🛡️ Nebenprozesse & Resilienz
  • Rechtstext-Aktualisierung
  • Bestellnachschlag per Token oder E-Mail
  • Ratenbegrenzung
💡 No-Code Checkliste & Praxistipps
  • Preisanzeige nach Zielgruppe wählen
  • Versandpauschale immer mit Steuersatz
  • Pflicht-Rechtstexte vor Veröffentlichung prüfen lassen
  • Zahlungsanbieter im Testmodus prüfen
  • Newsletter nur mit Double-Opt-in aktivieren

🗄️ Andme mudelid & väljad

SitePages site_pages RLS Aktiv
19 Kärgid / varud

Tabelle site_pages

Feldname Andme tüüp Kohustus Schlüssel Tööandjapidamis
site_id UUID Ja * FK ➔ sites.id Feld site_id
parent_id UUID Nein FK ➔ site_pages.id Feld parent_id
key VARCHAR(64) Ja * - Feld key
slug_i18n JSONB Ja * - Feld slug_i18n
title_i18n JSONB Ja * - Feld title_i18n
blocks JSONB Ja * - Feld blocks
seo_description_i18n JSONB Ja * - Feld seo_description_i18n
sort_order INTEGER Ja * - Feld sort_order
show_in_nav BOOLEAN Ja * - Feld show_in_nav
status VARCHAR(16) Ja * - Feld status
id UUID Nein PK Feld id
tenant_id UUID Ja * FK ➔ organizations.id Feld tenant_id
created_at DATETIME Ja * - Feld created_at
updated_at DATETIME Ja * - Feld updated_at
created_by UUID Nein - Feld created_by
updated_by UUID Nein - Feld updated_by
source_type VARCHAR(32) Nein - Feld source_type
source_id UUID Nein - Feld source_id
metadata JSONB Ja * - Feld metadata
Sites sites RLS Aktiv
29 Kärgid / varud

Tabelle sites

Feldname Andme tüüp Kohustus Schlüssel Tööandjapidamis
name VARCHAR(120) Ja * - Feld name
theme_key VARCHAR(32) Ja * - Feld theme_key
languages JSONB Ja * - Feld languages
default_language VARCHAR(8) Ja * - Feld default_language
tagline_i18n JSONB Ja * - Feld tagline_i18n
contact_email VARCHAR(255) Nein - Feld contact_email
phone VARCHAR(64) Nein - Feld phone
shop_enabled BOOLEAN Ja * - Feld shop_enabled
status VARCHAR(16) Ja * - Feld status
legal_ready_at VARCHAR(40) Nein - Feld legal_ready_at
brand_primary VARCHAR(7) Nein - Feld brand_primary
brand_accent VARCHAR(7) Nein - Feld brand_accent
logo_url VARCHAR(500) Nein - Feld logo_url
color_mode VARCHAR(8) Ja * - Feld color_mode
price_display VARCHAR(8) Ja * - Feld price_display
shipping_flat_net NUMERIC(12, 2) Nein - Feld shipping_flat_net
free_shipping_from_net NUMERIC(12, 2) Nein - Feld free_shipping_from_net
shipping_tax_rate NUMERIC(5, 2) Nein - Feld shipping_tax_rate
newsletter_enabled BOOLEAN Ja * - Feld newsletter_enabled
contact_form_enabled BOOLEAN Ja * - Feld contact_form_enabled
id UUID Nein PK Feld id
tenant_id UUID Ja * FK ➔ organizations.id Feld tenant_id
created_at DATETIME Ja * - Feld created_at
updated_at DATETIME Ja * - Feld updated_at
created_by UUID Nein - Feld created_by
updated_by UUID Nein - Feld updated_by
source_type VARCHAR(32) Nein - Feld source_type
source_id UUID Nein - Feld source_id
metadata JSONB Ja * - Feld metadata

🔌 Algsed punktid (UI ja API)

Art Teadus Lõpppunkt / tee Titel & Zweck Õigustamine
⚡ REST API GET /site/{slug}/
site_root
Semantic binding: inventory_only; mutation=False
sites
⚡ REST API GET /site/{slug}/sitemap.xml
sitemap
Semantic binding: inventory_only; mutation=False
sites
⚡ REST API GET /site/{slug}/{lang}/
site_home
Semantic binding: inventory_only; mutation=False
sites
⚡ REST API GET /site/{slug}/{lang}/checkout/return
checkout_return
Semantic binding: inventory_only; mutation=False
sites
⚡ REST API GET /site/{slug}/{lang}/form/newsletter-confirm
newsletter_confirm_page
Semantic binding: inventory_only; mutation=False
sites
⚡ REST API GET /site/{slug}/{lang}/legal/{kind}
site_legal
Semantic binding: inventory_only; mutation=False
sites
⚡ REST API GET /site/{slug}/{lang}/order/{order_number}
order_status
Semantic binding: inventory_only; mutation=False
sites
⚡ REST API GET /site/{slug}/{lang}/shop
shop_catalog_page
Semantic binding: inventory_only; mutation=False
sites
⚡ REST API GET /site/{slug}/{lang}/{page_slug}
site_page
Semantic binding: inventory_only; mutation=False
sites
⚡ REST API GET /sites
sites_dashboard
Semantic binding: inventory_only; mutation=False
sites
⚡ REST API GET /sites/legal
sites_legal
Semantic binding: inventory_only; mutation=False
sites
⚡ REST API GET /sites/legal/{legal_id}
sites_legal_edit
Semantic binding: inventory_only; mutation=False
sites
⚡ REST API GET /sites/orders
sites_orders
Semantic binding: inventory_only; mutation=False
sites
⚡ REST API GET /sites/orders/{order_id}
sites_order_detail
Semantic binding: inventory_only; mutation=False
sites
⚡ REST API GET /sites/pages
sites_pages
Semantic binding: inventory_only; mutation=False
sites
⚡ REST API GET /sites/pages/new
sites_page_new
Semantic binding: inventory_only; mutation=False
sites
⚡ REST API GET /sites/pages/{page_id}
sites_page_edit
Semantic binding: inventory_only; mutation=False
sites
⚡ REST API GET /sites/payments
sites_payments
Semantic binding: inventory_only; mutation=False
sites
⚡ REST API GET /sites/shop
sites_shop
Semantic binding: inventory_only; mutation=False
sites
⚡ REST API POST /site/hooks/paypal/{slug}
paypal_webhook
Semantic binding: operator_surface; mutation=True
sites
⚡ REST API POST /site/hooks/stripe/{slug}
stripe_webhook
Semantic binding: operator_surface; mutation=True
sites
⚡ REST API POST /site/{slug}/{lang}/cart/price
cart_price
Semantic binding: operator_surface; mutation=True
sites
⚡ REST API POST /site/{slug}/{lang}/checkout
checkout_submit
Semantic binding: operator_surface; mutation=True
sites
⚡ REST API POST /site/{slug}/{lang}/form/contact
contact_submit
Semantic binding: operator_surface; mutation=True
sites
⚡ REST API POST /site/{slug}/{lang}/form/newsletter
newsletter_submit
Semantic binding: operator_surface; mutation=True
sites
⚡ REST API POST /site/{slug}/{lang}/form/newsletter-confirm
newsletter_confirm
Semantic binding: operator_surface; mutation=True
sites
⚡ REST API POST /sites/legal/seed
sites_legal_seed
Semantic binding: operator_surface; mutation=True
sites
⚡ REST API POST /sites/legal/{legal_id}/save
sites_legal_save
Semantic binding: operator_surface; mutation=True
sites
⚡ REST API POST /sites/orders/{order_id}/handover
sites_order_handover
Semantic binding: operator_surface; mutation=True
sites
⚡ REST API POST /sites/orders/{order_id}/transit
sites_order_transit
Semantic binding: operator_surface; mutation=True
sites
⚡ REST API POST /sites/pages/ai-draft
sites_page_ai_draft
Semantic binding: operator_surface; mutation=True
sites
⚡ REST API POST /sites/pages/save
sites_page_save
Semantic binding: operator_surface; mutation=True
sites
⚡ REST API POST /sites/pages/{page_id}/ai-content
sites_page_ai_content
Semantic binding: operator_surface; mutation=True
sites
⚡ REST API POST /sites/pages/{page_id}/delete
sites_page_delete
Semantic binding: operator_surface; mutation=True
sites
⚡ REST API POST /sites/payments/save
sites_payments_save
Semantic binding: operator_surface; mutation=True
sites
⚡ REST API POST /sites/settings
sites_settings
Semantic binding: operator_surface; mutation=True
sites
⚡ REST API POST /sites/shop/save
sites_shop_save
Semantic binding: operator_surface; mutation=True
sites

🛡️ Määruse ja vastavus

Dieses Modul unterliegt folgenden gesetzlichen, regulatorischen und Revisionsstandards:

  • Töötlusvõime
  • Kliendi isolatsioon (postgreSQL RLS)