b2in/dev/entwicklung.md
Kevin Adametz 07816dce19 Kontaktdaten: Telefon +49 521 986 20 100, E-Mail interior@b2in.eu
Lang-Dateien (Kontaktformular, Impressum, Datenschutz, de/en), Support-Link im Partnerportal,
WhatsApp-Schreibweise und Platzhalter im Admin. ContactDetailsSeeder ersetzt die alten Werte in
den gespeicherten CMS-Einträgen (beide Sprachen), Marken und Magazin; Display-Folien und
Info-Tablet (CABINET-Showroom) bleiben unberührt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:29:34 +00:00

14 KiB
Raw Blame History

B2in – Projektdokumentation

Stand: 09.10.2026 · Version: v2.0.6 · Live: b2in.eu (Website), portal.b2in.eu (Portal)

Projektübersicht

B2in ist eine Laravel-Anwendung für mehrere Domains. Im Zentrum stehen zwei Teile:

  • Website b2in.eu mit zwei Welten. Die Welt B2in Interior zeigt hochwertige Einrichtung von CABINET, Rotpunkt Küchen, Febrü und Otterpohl Möbelservice, dazu Showroom, Magazin und Kontakt. Die Welt Immobilien betrifft internationale Projekte in Dubai.
  • Portal portal.b2in.eu mit Website-CMS, Store Displays mit Info-Tablet, Partnerverwaltung, Produkten, Regionen und Monitoring.

Im Oktober 2026 ging der Interior-Relaunch live (v2.0.0). Seitdem wird per Git-Tag ausgeliefert und der Betrieb überwacht.

Die Domains b2a, Stileigentum und Style2own bleiben erreichbar, werden aber nicht weiterentwickelt.


Domains und Welten

Domain Zweck Oberfläche
b2in.eu Website B2in Interior und Immobilien-Welt Livewire, Tailwind CSS v4, eigenes Theme b2in
portal.b2in.eu Portal: CMS, Displays, Partner, Admin Livewire, Volt, Flux UI Pro
cabinet.b2in.eu Display-Player und Short-Links im Showroom (public/_cabinet) statisches HTML/JS, holt Daten über die Display-API
b2a, Stileigentum, Style2own Landingpages (geparkt) eigene Themes

Die Welt einer Seite ergibt sich aus b2in_world() in app/helpers.php, das Logo je Welt aus ThemeHelper::getLogoPath().

Welt Farben Schriften
Interior (Standard) Tanne, Creme, Sand, Ocker (#a8741f als Akzent) Inter, EB Garamond
Immobilien Anthrazit, Dynamic Blue Inter, IBM Plex Sans

Lokal laufen die Domains unter *.test (siehe CLAUDE.md).


Technik

Bereich Einsatz
Framework Laravel 12, PHP 8.4
Oberfläche Livewire 4, Volt, Flux UI Pro 2, Alpine.js, Tailwind CSS v4
Anmeldung Laravel Fortify, Sanctum, Rollen über Spatie Laravel-Permission
Mehrsprachigkeit Deutsch/Englisch: Lang-Dateien und Spatie Laravel-Translatable
CMS eigenes Paket packages/flux-cms (Inhalte, Mediathek) und App-Module (Marken, Magazin, Referenzen)
Build Vite, je Theme ein Build unter public/build/<theme>, Portal unter public/build/portal
Fehler und Betrieb GlitchTip (Sentry-SDK), /health, Uptime Kuma, ntfy
Tests Pest 3, SQLite im Arbeitsspeicher
Entwicklung Dev Container: php, composer, npm direkt, ohne Sail

Website B2in Interior

Seiten

Pfad Inhalt
/ Hero mit Bilder-Slideshow und Infokarte, Gründerleiste (Marcel Scheibe), Weiche Privat/Projekt, Kernmarken, „Aus der Region gefertigt“, „Gebaut auf Expertise und Vertrauen“, Vereine (Sponsoring), Live-Ansicht des Showroom-Displays, Immobilien-Teaser, Kontakt-CTA
/marken Hero, Gründerleiste, die vier Kernmarken, Bildpause mit Zitat, Herkunft, Netzwerk, Wachstum, CTA
/marken/{slug} Markenseite: Einleitung, Abschnitte mit aufklappbaren Vertiefungen, Leistungen, Galerie (Realisiertes Projekt / Aus der Werkstatt / Inspiration), Handwerk-Abschluss, weitere Marken
/about Mission, Gründerleiste, Geschichte, Werte, Partner-CTA
/magazin, /magazin/{slug} Magazin der Interior-Welt; alte Adressen /magazin/1 … /5 leiten per 301 weiter
/faq allgemeine Fragen und Bereiche „Für Ihr Zuhause“ und „Für Projekte und Objekte“
/contact Kontaktformular
/referenzen Referenzen-Modul; zurzeit ausgeblendet (Schalter im CMS)
/impressum, /privacy, /terms, /cookie-policy Rechtstexte (Stand 06.10.2026: DDG, MStV, TDDDG)
/embed/display/{display} schreibgeschützte Einbettung eines Displays (nur veröffentlichte Playlists)

Stillgelegte Seiten leiten dauerhaft um: /netzwerk, /interior, /partner und /service auf /marken, /ecosystem auf /partner, /portfolio auf /immobilien.

Bausteine

  • Hero-Slideshow: elf Bilder, im CMS pflegbar. Je Bild Marke und Motiv in der Infokarte. Überblendung alle 7 Sekunden (einstellbar 3–30), Pause bei Hover und Fokus, Steuerung per Pfeiltasten. Eine Fortschrittslinie im Bild zeigt die verbleibende Zeit. Auf dem Handy steht die Karte unter dem Bild.
  • Gemeinsamer Hero-Stil auf Start, Marken, Über uns und Kontakt: Goldverlauf als Rahmen, Zeile über der Überschrift, Vertrauenspunkte.
  • Termin-Widget: WhatsApp zuerst (+49 521 986 20 100, zugleich Telefonnummer; E-Mail interior@b2in.eu), darunter das Formular.
  • Live-Display: Die Startseite zeigt, was im Showroom läuft, vergrößerbar und im Vollbild.
  • Sprache: Deutsch und Englisch, Umschaltung über die Sitzung (SetLocale).

Inhalte: CMS vor Lang-Datei

Jede Sektion liest zuerst das CMS (cms_theme_section() über config/cms_section_map.php). Fehlt der Eintrag, gilt die Lang-Datei resources/lang/{de,en}/b2in.php. Bilder kommen bevorzugt aus public/img/assets (WebP-Fassungen) und sonst aus der Mediathek (theme_image_url(), media_url()).


Immobilien-Welt

  • Seiten unter /immobilien: Übersicht, Projekt (/immobilien/{slug}), Magazin, Über B2in, FAQ, Kontakt. Eigene Navigation, eigenes Logo, blaues Farbschema.
  • Projekte als CmsProject mit Preis in AED und Umrechnung in EUR/USD (PriceHelper). Die Projekte sind zurzeit nicht freigegeben und im Portal nicht verlinkt.
  • Magazin der Immobilien-Welt: drei Beiträge (Escrow, Al Jaddaf, Turnkey).

Magazin

Beiträge als CmsArticle (Titel, Untertitel und Inhalt je Sprache, Welt interior oder immobilien, Autor, Lesezeit, Veröffentlichung).

Welt Veröffentlicht
Interior „Nach Maß statt von der Stange“, „Küche planen“
Immobilien Escrow, Al Jaddaf, Turnkey
offline Supply-Chain, Local for Local (seit 08.10.2026)

Absätze im Inhalt trennt eine Leerzeile. Datum und Lesezeit stehen im deutschen Format.


CMS im Portal

Unter CMS ▸ Website-Inhalte:

Bereich Funktion
Übersicht Einstieg mit Kennzahlen
Inhalte Seitenbaum (config/cms_pages.php): je Seite die Sektionen mit Beschreibung. Felder je Sprache (DE/EN), Listen als Wiederholfelder, Bilder über die Mediathek. Vorschau der Seite daneben im Rahmen. Eine fehlende Sektion lässt sich aus der Lang-Datei anlegen.
Marken die vier Kernmarken: Texte, Logo, Titelbild, Merkmale, Leistungen, Abschnitte, Galerie mit Rubriken, Fertigungsort, CTA. Alle Textfelder je Sprache, Bilder und Rubriken gelten für beide Sprachen.
Magazin Beiträge beider Welten
Referenzen Modul vorhanden, Seite und Menüpunkt zurzeit ausgeblendet
Medien Mediathek mit Sammlungen (Marken, Magazin, Website), Alternativtexten je Sprache und Bildgrößen. Alle auf der Website verwendeten Bilder sind übernommen.

Hinweise zur Pflege:

  • FAQ: Jede Frage hat das Feld category. Leer heißt allgemeine Frage oben, sonst steht dort der Bereich. Überschrift und Symbol der Bereiche stehen in categories.
  • Vorschau im Portal: Die Website erlaubt das Einbetten nur durch sich selbst und das Portal (frame-ancestors, AllowPortalFraming).
  • Übersetzungen prüfen: php artisan cms:untranslated listet alles, was auf der englischen Seite fehlt oder noch deutsch ist.

Store Displays und Info-Tablet

Unter Cabinet ▸ Store Displays:

Bereich Funktion
Übersicht Kennzahlen, Status des Info-Tablets
Mediathek Bilder und Videos der Displays (Uploads oder externe URLs)
Module Inhalte nach Typ: video-display (Video-Playlist), b2in (Marken-Slides mit Interior-Logo, Bilddauer mit Nachkommastelle), offers (Angebote). Vorschau je Modul und je Folie.
Displays physische Geräte mit Playlists (Entwurf und veröffentlicht), Test-Displays, Vorschau-Links mit Token
Info-Tablet Öffnungszeiten (7 Tage), Tagesausnahmen mit Rücksetzung um Mitternacht, Status (offen, Hinweis, geschlossen, Warnung), Kontakt; Schnellschalter unter /info/status

API: Die Displays fragen die API zyklisch ab, ein Neustart ist nach Änderungen nicht nötig. Medien-URLs sind relativ gespeichert und funktionieren dadurch auf jedem Host.

Endpunkt Zweck
/api/display/{display}/config, /check Konfiguration und Änderungsprüfung je Gerät
/api/display/overview Übersicht aller Geräte
/api/display/preview/{token} Entwurf über Vorschau-Token
/api/display/module/{module}/preview Vorschau eines Moduls
/api/cabinet-tablet/status, /check Info-Tablet

Short-Links: cabinet.b2in.eu/go.php?z=CODE mit Klickzählung in public/_cabinet/clicks.log. Die Datei schreibt der Player im Betrieb, deshalb ist sie nicht versioniert.


Partner, Produkte, Regionen

Diese Bereiche haben eine Grundarchitektur. Seit dem Frühjahr kamen keine neuen Funktionen hinzu.

Bereich Funktionen
Rollen Super-Admin, Admin, Retailer, Manufacturer, Broker, Customer
Partner Einladung per Mail mit Token, Setup-Wizard, Registrierungscodes mit QR (/reg/{role}), Impersonation, Anonymisieren statt Löschen
Produkte Produkte, Varianten, Kategorien, Marken, Kuration (curate_products)
Regionen Hubs mit PLZ-Gebieten (Import einzeln, Bereich oder CSV)

Betrieb

Die vollständige Anleitung steht in dev/betrieb/README.md.

Auslieferung per Git-Tag

  • Remotes: origin = forge.adametz.media (Quelle für den Deploy, auf dem Server über den Alias forge-b2in), NAS = Sicherung.
  • Ausgeliefert wird nur ein Tag vX.Y.Z, auf dem Server mit bash dev/betrieb/deploy.sh vX.Y.Z [--migrations] [--seed=…].
  • Das Skript bricht ab, bevor es etwas verändert, wenn im Verzeichnis von Hand geändert wurde, der Tag fehlt, ein Build-Manifest fehlt oder Migrationen ohne --migrations kommen. Rollback: dasselbe Skript mit dem vorigen Tag.
  • public/build ist versioniert, weil der Server kein Node hat. Vor dem Tag lokal npm run build:web && npm run build:portal ausführen.
  • Inhaltsänderungen laufen über idempotente Seeder. InteriorReleaseSeeder fasst alle Schritte des Relaunchs zusammen. Spätere Seeder nennt die jeweilige Tag-Notiz.

Überwachung

Was Wo
Fehler in PHP und im Browser GlitchTip errors.adametz.media, Projekte server-b2in und browser-b2in. Ohne Personenbezug: nur User-ID, keine Formularinhalte, E-Mails ausgeblendet.
Tiefer Health-Check /health mit Bearer-Token (MONITORING_HEALTH_TOKEN): Datenbank, Cache, Queue, Scheduler-Herzschlag, Plattenplatz
Externer Monitor Uptime Kuma auf /health und /up, Alarme per ntfy (Topic b2in-ops) und Mail
Geplante Aufgaben Cron schedule:run jede Minute: Herzschlag, cabinet:reset-overrides (0 Uhr), Aufräumen alter Jobs; bei Fehlschlag ein Alarm
Admin ▸ Monitoring Prüfungen, Version und Deploy-Zeit, geplante Aufgaben, letzte Fehler und Alarme, fehlgeschlagene Jobs, Test-Alarm

Eine Queue braucht B2in nicht, Mails gehen sofort raus.


Datenbank (Auszug)

Bereich Tabellen
Benutzer und Rollen users, roles, permissions, model_has_roles, personal_access_tokens
Partner partners, partner_invitations, registration_codes, hubs, hub_locations
Produkte products, product_variants, brands, categories, attributes, tags, collections …
Website-CMS flux_cms_contents (Sektionen je Gruppe/Schlüssel, Werte je Sprache), flux_cms_media, cms_brands (mit field_translations), cms_articles (mit world), cms_projects, cms_references
Displays displays, display_versions (Module), display_version_items, display_playlists, display_playlist_items, display_media, cabinet_tablet_settings
Altbestand Displays display_videos, display_footer_contents
System cache, jobs, failed_jobs, sessions

Tests

1197 Tests (Pest), alle grün (Stand 09.10.2026). Sie laufen auf SQLite im Arbeitsspeicher, die MySQL-Datenbank bleibt unberührt.

php artisan test --compact                       # alle
php artisan test --compact tests/Feature/FooTest.php

Wächtertests sichern bekannte Stolpersteine ab:

  • Klassenpfad und Namespace in gleicher Schreibweise, sonst Ausfall auf Linux
  • Lang-Sektionen und Section-Map decken sich
  • die Testsuite meldet nie an das echte GlitchTip

Wichtige Dateien und Dokumente

Datei Inhalt
CLAUDE.md Projektkontext für Entwicklung mit KI
dev/betrieb/README.md Deploy, Livegang, Monitoring (Runbook)
dev/2026-08-28/entwicklungsplan.md Verlauf des Interior-Relaunchs mit allen Nachträgen
dev/git-deploy-monitoring/ Baukasten Git-Deploy und Monitoring (projektübergreifend)
config/cms_pages.php Seitenbaum und Beschreibungen im CMS
config/cms_section_map.php Zuordnung Website-Sektion ↔ CMS-Eintrag
resources/lang/{de,en}/b2in.php Standardtexte der Website
resources/lang/{de,en}/b2in_legal.php Rechtstexte
database/seeders/data/brand-translations-en.json englische Markentexte
dev/DISPLAY_CMS_README.md, dev/DISPLAY_SETUP_LIVE.md Display-System
DOMAINS-CONFIG.md Domain-Konfiguration

Archive alter Entwürfe und stillgelegter Seiten liegen unter dev/2026-08-28/archiv-*, jeweils mit README.


Offene Punkte

  • Datenschutzerklärung: Der Absatz zur Fehlerprotokollierung (GlitchTip) fehlt noch. Ein Textvorschlag steht in dev/betrieb/README.md, Abschnitt 6.
  • OG-Bild img/assets/b2in-og-default.jpg fehlt. Geteilte Links zeigen deshalb kein Vorschaubild.
  • Freigaben:
    • Herstellerfreigabe der Texte von Rotpunkt und Febrü, mit Blick auf die EmpCo-Regeln
    • CABINET-Seitentext von Marcel
    • Waldflächen-Aussage bei Rotpunkt
  • Englische Markentexte einmal muttersprachlich gegenlesen lassen.
  • Logo TC Bad Salzuflen liegt nur in geringer Auflösung vor (72 × 80 px).
  • Mailzustellung: Im Frühjahr wurden Systemmails bei Gmail abgewiesen („sender is unauthenticated“). SPF, DKIM und DMARC der Absenderdomain prüfen.
  • Display-Feed: Festlegen, welches Display auf der Website läuft (referenzen.display_feed.display_id). Ohne Eintrag läuft das erste aktive Display mit veröffentlichter Playlist.

Diese Dokumentation wird mit jedem Release aktualisiert. Letzte Aktualisierung: 09.10.2026 (v2.0.6).