CLAUDE - Nachtschicht Instruktionen
Version: 1.1 (Korrigiert) Datum: 2025-10-25 Agent: Claude (KI-Agent für Nachtschicht) Projekt: Appiyon - Admin-Panel Implementierung
🎯 Deine Aufgabe
Du bist verantwortlich für die vollständige Implementierung des Admin-Panels gemäß der Nachtschicht-To-Do-Liste.
Hauptziel: Admin-Panel unter https://appisym.go4family.net/admin funktionsfähig machen
WICHTIG: Admin-Panel = UI (EasyAdmin CRUDs im Dev Layer) für Entities aus ALLEN Layern!
📚 PFLICHTLEKTÜRE - VOR dem Start
Du MUSST diese Dateien ZUERST lesen:
Main Instructions (KRITISCH!)
- Pfad:
.appi/.kalendion/main-instructions.md - Zweck: Grundlegende Entwicklungsrichtlinien
- Enthält: 3 Goldene Regeln, Migration-Standards, Quality-Checklists
- Pfad:
Appi-Laws (KRITISCH!)
- Pfad:
.appi/.kalendion/appi-laws.md - Zweck: 12 architektonische Gesetze
- STRIKTE Einhaltung - KEINE Ausnahmen!
- Pfad:
Nachtschicht To-Do (Arbeitsliste)
- Pfad:
.appi/.kalendion/nachtschicht-todo.md - Zweck: Detaillierte Aufgabenliste
- Enthält: 7 Phasen mit 100+ Tasks
- Pfad:
Admin-Panel Dokumentation (NEU - WICHTIG!)
- Pfad:
doku/docs/entwicklung/architecture-admin-panel.md - Zweck: Admin-Panel Architektur verstehen
- MUSS gelesen werden! Erklärt das richtige Konzept!
- Pfad:
⚠️ WICHTIG: Starte NICHT mit der Arbeit bevor du diese Dateien gelesen hast!
🎯 Admin-Panel - Richtiges Verständnis
Was ist das Admin-Panel?
✅ Admin-Panel = Web-UI (EasyAdmin)
✅ Im Dev Layer (nur Controller!)
✅ Zeigt Entities aus ALLEN Layern
✅ Für Users mit ROLE_ADMIN
✅ Verwaltet globale Stammdaten
❌ NICHT ein separates System
❌ NICHT mit eigenen Entities
❌ NICHT im Infrastructure Layer
❌ KEINE separate admins-TabelleKritisches Konzept:
Entities BLEIBEN in ihren Layern!
Foundation/Geo/Entity/Country.php ← Entity hier!
Dev/Admin/Controller/CountryCrudController.php ← CRUD hier (zeigt auf Entity)!Migrations BLEIBEN in ihren Layern!
migrations/3_foundation/Version0001_geo.php ← Migration hier!Admins = Users mit ROLE_ADMIN
KEINE separate admins-Tabelle!
Admins sind Users aus Identity-System mit ROLE_ADMIN!🔴 DIE 3 GOLDENEN REGELN
Regel 1: Dokumentation ZUERST lesen
NIEMALS Code schreiben ohne die relevanten Doku-Seiten gelesen zu haben!Regel 2: Appi-Laws STRIKT einhalten
Die 12 Architectural Laws sind NICHT optional!
Bei EINEM Verstoß → Code NICHT schreiben, erst korrigieren!Regel 3: KEINE Abkürzungen nehmen
Qualität vor Geschwindigkeit!
"Langsam und richtig" ist schneller als "schnell und falsch mit späteren Korrekturen"📋 ARBEITSABLAUF - Schritt für Schritt
Phase 1: Vorbereitung
Dokumentation lesen (siehe oben)
Admin-Panel testen
bash# Browser öffnen https://appisym.go4family.net/admin # Fehler dokumentieren # Alle Error-Messages notieren # Stack-Traces speichernEntwicklungsumgebung prüfen
bash# Cache clearen php bin/console cache:clear # Composer dependencies composer install # Database-Status php bin/console doctrine:migrations:status
Phase 2: Modul-Implementierung (pro Modul)
Für JEDES Modul folgst du diesem EXAKTEN Workflow:
Schritt 1: Alte Version studieren
# Beispiel für Geo-Modul:
# 1. Alte Version öffnen
cat .appi/.kalendion/Core/Geo/README.md
# 2. Alle Dateien durchgehen
find .appi/.kalendion/Core/Geo -type f -name "*.php"
# 3. Verstehen:
# - Welche Entities gibt es?
# - Welche Funktionalität?
# - Welche Business-Rules?⏱️ Zeit nehmen! Nicht überfliegen, VERSTEHEN!
Schritt 2: Migration prüfen/erstellen
Migration BLEIBT im Layer-Ordner!
WENN Migration existiert:
# Beispiel: Foundation/Geo
cat migrations/3_foundation/Version0001_geo.php
# Prüfen:
# ✅ Alle Tabellen korrekt?
# ✅ Enums mit CHECK constraints?
# ✅ Foreign Keys mit ON DELETE?
# ✅ Alle Indices definiert?WENN Migration NICHT existiert (ab Core Layer):
# 1. Alte Migration finden
find .appi/.kalendion/database/migrations -name "*geo*"
# 2. Neue Migration im richtigen Layer-Ordner erstellen
# migrations/3_foundation/Version0001_geo.php ← HIER!
# 3. Migration umschreiben:
# - Enums via CHECK constraints (nicht Foreign Keys!)
# - Ein Modul = Eine Datei
# - Alle Tables + Constraints in CREATE (kein ALTER!)Schritt 3: Entity im RICHTIGEN Layer erstellen
Entity BLEIBT in ihrem Layer!
// ✅ RICHTIG - Entity in Foundation/Geo
// src/Appi/Foundation/Geo/Entity/Country.php
namespace App\Appi\Foundation\Geo\Entity;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: CountryRepository::class)]
#[ORM\Table(name: 'countries')]
class Country
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private ?int $id = null;
#[ORM\Column(type: 'string', length: 255)]
private string $name;
#[ORM\Column(type: 'string', length: 2)]
private string $iso2;
// KEIN team_id - globale Daten!
// Nur Getters/Setters (KEINE Business-Logic!)
}❌ FALSCH - Entity NICHT im Dev oder Infrastructure Layer!
Checkliste pro Entity:
- [ ] Im RICHTIGEN Layer (Foundation/Core/Domain - NICHT Dev/Infrastructure!)
- [ ] Doctrine Annotations korrekt
- [ ] Enums verwendet (nicht Foreign Keys)
- [ ] KEINE Business-Logic in Entity
- [ ] KEINE save(), create() Methoden
- [ ] Nur Getters/Setters
Schritt 4: Repository erstellen
Repository IM SELBEN Layer wie Entity!
// src/Appi/Foundation/Geo/Repository/CountryRepositoryInterface.php
namespace App\Appi\Foundation\Geo\Repository;
use App\Appi\Foundation\Geo\Entity\Country;
interface CountryRepositoryInterface
{
public function save(Country $country): void;
public function findById(int $id): ?Country;
public function findAll(): array;
}
// src/Appi/Foundation/Geo/Repository/CountryRepository.php
namespace App\Appi\Foundation\Geo\Repository;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
class CountryRepository extends ServiceEntityRepository implements CountryRepositoryInterface
{
public function save(Country $country): void
{
$this->getEntityManager()->persist($country);
$this->getEntityManager()->flush();
}
// ... weitere Methoden
}In services.yaml registrieren:
services:
App\Appi\Foundation\Geo\Repository\CountryRepositoryInterface:
class: App\Appi\Foundation\Geo\Repository\CountryRepositorySchritt 5: Admin-Panel Integration prüfen
FRAGE: Braucht dieses Modul eine Admin-UI?
JA, wenn:
- ✅ Globale Daten (KEIN team_id)
- ✅ Müssen vom Admin verwaltet werden
- ✅ Stammdaten (Countries, Languages, Industries, etc.)
- ✅ Müssen existieren BEVOR System funktioniert
NEIN, wenn:
- ❌ Mandanten-Daten (mit team_id)
- ❌ Business-Daten (Principals, Users, CRM)
- ❌ Von normalen Users verwaltet
WENN JA → CRUD-Controller im Dev Layer erstellen:
// ✅ RICHTIG - CRUD Controller im Dev/Admin/Controller
// src/Appi/Dev/Admin/Controller/CountryCrudController.php
namespace App\Appi\Dev\Admin\Controller;
use App\Appi\Foundation\Geo\Entity\Country; // ← Import aus Foundation!
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use Symfony\Component\Security\Http\Attribute\IsGranted;
#[IsGranted('ROLE_ADMIN')] // Nur Users mit ROLE_ADMIN
class CountryCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return Country::class; // ← Zeigt auf Foundation Entity!
}
public function configureFields(string $pageName): iterable
{
yield TextField::new('name', 'Name');
yield TextField::new('iso2', 'ISO 2');
yield TextField::new('iso3', 'ISO 3');
}
public function configureCrud(Crud $crud): Crud
{
return $crud
->setEntityLabelInSingular('Country')
->setEntityLabelInPlural('Countries')
->setDefaultSort(['name' => 'ASC']);
}
}Dashboard Integration:
// src/Appi/Dev/Admin/Controller/DashboardController.php
namespace App\Appi\Dev\Admin\Controller;
use App\Appi\Foundation\Geo\Entity\Country; // ← Import aus Foundation!
use Symfony\Component\Security\Http\Attribute\IsGranted;
#[IsGranted('ROLE_ADMIN')]
class DashboardController extends AbstractDashboardController
{
public function configureMenuItems(): iterable
{
yield MenuItem::linkToDashboard('Dashboard', 'fa fa-home');
// Geo-Daten (aus Foundation Layer)
yield MenuItem::section('Geo-Daten');
yield MenuItem::linkToCrud('Countries', 'fa fa-globe', Country::class);
yield MenuItem::linkToCrud('Languages', 'fa fa-language', Language::class);
}
}Schritt 6: Migration ausführen + Testen
# 1. Migration ausführen
php bin/console doctrine:migrations:execute --up Version0001_geo
# 2. Prüfen: Tabellen erstellt?
php bin/console dbal:run-sql "SELECT table_name FROM information_schema.tables WHERE table_schema='public'"
# 3. Prüfen: Constraints funktionieren?
php bin/console dbal:run-sql "SELECT constraint_name FROM information_schema.table_constraints WHERE table_name='countries'"
# 4. Admin-Panel testen (falls CRUD erstellt)
# Browser: https://appisym.go4family.net/admin
# Navigiere zu "Countries"
# Teste: List, Create, Edit, DeleteBei Fehlern:
- Error-Message dokumentieren
- Migration rollback:
doctrine:migrations:execute --down Version0001_geo - Migration korrigieren
- Erneut ausführen
Schritt 7: Dokumentation aktualisieren
# 1. Changelog aktualisieren
echo "## $(date +%Y-%m-%d) - Geo Module" >> doku/docs/entwicklung/changelog.md
echo "- Added Country, Language, Currency entities" >> doku/docs/entwicklung/changelog.md
echo "- Added Admin CRUDs for Geo module" >> doku/docs/entwicklung/changelog.md
# 2. Docs bauen
cd doku
npm run docs:build🔍 QUALITÄTSSICHERUNG - Nach JEDEM Modul
Checkliste (ALLES muss ✅ sein):
Code-Qualität:
- [ ] Appi-Laws 1-12 eingehalten
- [ ] Entity im RICHTIGEN Layer (Foundation/Core/Domain - NICHT Dev!)
- [ ] Enums statt Foreign Keys
- [ ] Command/Handler Pattern befolgt
- [ ] Repository-Interfaces verwendet
- [ ] KEINE Business-Logic in Entities
Migration-Qualität:
- [ ] Migration im RICHTIGEN Layer-Ordner (3_foundation, 4_core, etc.)
- [ ] Ein Modul = Eine Datei
- [ ] CREATE statt ALTER (Non-Live!)
- [ ] Enums mit CHECK constraints
- [ ] Foreign Keys mit ON DELETE
- [ ] Alle Indices definiert
Admin-Panel:
- [ ] CRUD Controller im Dev/Admin/Controller (NICHT Infrastructure!)
- [ ] Zeigt auf Entity aus richtigem Layer
- [ ]
#[IsGranted('ROLE_ADMIN')]verwendet - [ ] Dashboard aktualisiert
Testing:
- [ ] Migration erfolgreich ausgeführt
- [ ] Tabellen korrekt erstellt
- [ ] Constraints funktionieren
- [ ] Admin-Panel CRUD funktioniert
- [ ] KEINE Console-Errors
- [ ] KEINE Browser-Errors
Wenn EINE Checkbox NICHT ✅ → STOPP! Erst korrigieren!
🚫 ABSOLUTE DON'Ts - NIEMALS machen!
- ❌ Entity im Dev oder Infrastructure Layer → Entity bleibt in Foundation/Core/Domain!
- ❌ Migration im falschen Ordner → Migration in richtigen Layer-Ordner!
- ❌ Separate admins-Tabelle → Admins sind Users mit ROLE_ADMIN!
- ❌ CRUD Controller im Infrastructure → CRUD Controller im Dev/Admin/Controller!
- ❌ ALTER TABLE in Non-Live → Direkt in CREATE korrigieren!
- ❌ Foreign Keys zu Enums → CHECK Constraint verwenden!
- ❌ Business Logic in Entities → Handler verwenden!
- ❌ team_id in Foundation/Core → NUR in Dev!
- ❌ Multiple Migration Files pro Modul → EIN File pro Modul!
- ❌ Code ohne Doku lesen → IMMER zuerst Doku lesen!
- ❌ Laws ignorieren → Laws sind NICHT optional!📊 PROGRESS TRACKING
Nach jedem abgeschlossenen Modul:
- Checkbox in nachtschicht-todo.md abhaken
- Status-Update schreiben
- Commit:
git add .
git commit -m "feat(geo): Implement Geo module with Country/Language/Currency
- Added Country, Language, Currency entities in Foundation/Geo
- Added repositories with interfaces
- Added Admin CRUDs in Dev/Admin/Controller
- Migration executed successfully
- Tests passing
🤖 Generated with Claude Code"🎯 ERFOLGSKRITERIEN
Du bist fertig, wenn:
Admin-Panel:
- ✅ Keine Fehler beim Aufrufen
- ✅ Login funktioniert (User mit ROLE_ADMIN)
- ✅ Dashboard zeigt Stats
- ✅ Alle CRUDs funktionieren
Module:
- ✅ Alle Entities in richtigen Layern
- ✅ Alle Migrations in richtigen Layer-Ordnern
- ✅ Alle Admin-CRUDs im Dev/Admin/Controller
- ✅ Alle Migrationen erfolgreich
- ✅ Alle Tests grün
Code-Qualität:
- ✅ Appi-Laws eingehalten
- ✅ Keine Console-Errors
- ✅ Keine Browser-Errors
🔒 SECURITY REMINDER
Admin-Zugriff:
- Admins = Users mit ROLE_ADMIN
- KEINE separate admins-Tabelle
- Alle Admin-Controller mit
#[IsGranted('ROLE_ADMIN')]
Security Config:
# config/packages/security.yaml
security:
providers:
app_user_provider:
entity:
class: App\Appi\Shared\Identity\Entity\User
property: email
firewalls:
admin:
pattern: ^/admin
provider: app_user_provider
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }📝 ZUSAMMENFASSUNG
Admin-Panel:
- ✅ UI (EasyAdmin) im Dev Layer
- ✅ Zeigt Entities aus ALLEN Layern
- ✅ Für Users mit ROLE_ADMIN
Workflow pro Modul:
- Entity im richtigen Layer (Foundation/Core/Domain)
- Migration im richtigen Layer-Ordner (3_foundation, 4_core, etc.)
- Repository im selben Layer wie Entity
- CRUD Controller im Dev/Admin/Controller (falls Admin-UI nötig)
- Dashboard aktualisieren
- Testen & Dokumentieren
Merke:
"Entities bleiben in ihren Layern! Admin-Panel ist nur das UI!" "Admins sind Users mit ROLE_ADMIN - keine separate Tabelle!"
🚀 LOS GEHT'S!
# 1. Dokumentation lesen
cat .appi/.kalendion/main-instructions.md
cat .appi/.kalendion/appi-laws.md
cat doku/docs/entwicklung/architecture-admin-panel.md # WICHTIG!
cat .appi/.kalendion/nachtschicht-todo.md
# 2. Admin-Panel testen
# Browser: https://appisym.go4family.net/admin
# 3. Fehler beheben
# 4. Mit Modul-Implementierung starten
# Viel Erfolg! 🎯Remember:
"Entities bleiben in ihren Layern!" "Migrations bleiben in ihren Layer-Ordnern!" "Admin-Panel ist nur UI im Dev Layer!" "Admins sind Users mit ROLE_ADMIN!"
Du schaffst das! 💪