diff --git a/README.md b/README.md index 9011220..5bd6f3c 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,8 @@ The project documentation remains in the Both carry `hreflang` alternates and a language switch; the layout picks its few interface strings from the page's `lang`. A content change to one page belongs in the other in the same change. `check_site.rb` fails if the German page, its -alternates or its search terms go missing. +alternates or its search terms go missing, and if either page or `llms.txt` +loses the stack section (the terms are listed in `STACK` in that script). ## Local verification diff --git a/de/index.md b/de/index.md index 9ffbf2e..fc24f38 100644 --- a/de/index.md +++ b/de/index.md @@ -52,6 +52,18 @@ an ein geschlossenes Produkt anzupassen. +## Worauf es läuft + +Ein selbst gehosteter E-Commerce-Stack aus bewährten Open-Source-Bausteinen, gestartet +mit Docker Compose: + +- **Backend:** Python und FastAPI, mit asynchronem SQLAlchemy auf PostgreSQL und Redis für Hintergrundjobs. +- **Storefront und Backoffice:** Angular, angebunden über die API. Es ist headless, du kannst also dein eigenes Frontend mitbringen. +- **Konten:** Keycloak-Single-Sign-on für Kundschaft und Team. +- **Zahlung und Versand:** Stripe für Zahlungen, DHL für den Versand. +- **Dokumente und Dateien:** Paperless-ngx für Buchhaltungsbelege, MinIO als S3-kompatibler Speicher. +- **Betrieb:** Prometheus, Grafana und OpenTelemetry. + ## So fängst du an
diff --git a/index.md b/index.md index d9abcf3..92e7d8d 100644 --- a/index.md +++ b/index.md @@ -49,6 +49,18 @@ product. +## What it runs on + +A self-hosted e-commerce stack built from well-known open-source parts, started with +Docker Compose: + +- **Backend:** Python and FastAPI, with async SQLAlchemy on PostgreSQL and Redis for background jobs. +- **Storefront and back office:** Angular, talking to the API. It is headless, so you can bring your own frontend. +- **Accounts:** Keycloak single sign-on for customers and staff. +- **Payment and shipping:** Stripe for payments, DHL for shipping. +- **Documents and files:** Paperless-ngx for accounting documents, MinIO as S3-compatible storage. +- **Operations:** Prometheus, Grafana and OpenTelemetry. + ## How to start
diff --git a/llms.txt b/llms.txt index 96edea4..0183e43 100644 --- a/llms.txt +++ b/llms.txt @@ -16,6 +16,16 @@ A German version of the website is at {{ site.url }}/de/. - [admin_frontend](https://github.com/OpenTaberna/admin_frontend): Role-protected back office for products, inventory, orders and returns. - [wiki](https://github.com/OpenTaberna/wiki): Source-controlled documentation for setup, architecture and operation. +## Stack + +- Backend: Python, FastAPI, async SQLAlchemy, PostgreSQL, Redis for background jobs. +- Storefront and back office: Angular (headless; any frontend can use the API). +- Accounts: Keycloak single sign-on. +- Payment and shipping: Stripe, DHL. +- Documents and files: Paperless-ngx, MinIO (S3-compatible). +- Operations: Prometheus, Grafana, OpenTelemetry. +- Deployment: self-hosted with Docker Compose. + ## Documentation The [OpenTaberna wiki](https://wiki.opentaberna.de) is the project's documentation site and single source of truth. Begin with the [Getting Started guide](https://github.com/OpenTaberna/wiki/blob/main/Getting-Started.md). This website deliberately does not duplicate those instructions. diff --git a/scripts/check_site.rb b/scripts/check_site.rb index 7a4327c..ba1ba15 100755 --- a/scripts/check_site.rb +++ b/scripts/check_site.rb @@ -84,6 +84,18 @@ def internal_target(reference) fail!("#{path}: has lost the language switch to #{expected[:switch]}") unless html.match?(/]*href="#{Regexp.escape(expected[:switch])}"/) end +STACK = [ + "FastAPI", "PostgreSQL", "Redis", "Keycloak", "Angular", "Stripe", "DHL", + "Paperless-ngx", "MinIO", "Prometheus", "Grafana", "OpenTelemetry", "Docker Compose", +].freeze +{ "index.html" => "What it runs on", "de/index.html" => "Worauf es läuft", "llms.txt" => "## Stack" }.each do |path, heading| + text = read(path) + next unless text + + fail!("#{path}: has lost the #{heading.inspect} section") unless text.include?(heading) + STACK.each { |term| fail!("#{path}: stack section has lost #{term.inspect}") unless text.include?(term) } +end + german = read("de/index.html") if german h1 = german[%r{]*>(.*?)}m, 1].to_s.downcase @@ -170,6 +182,7 @@ def internal_target(reference) sections = [ "What OpenTaberna is", "What it is made of", + "What it runs on", "How to start", "Licence and intent", "Founders",