Skip to content

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:

  1. Main Instructions (KRITISCH!)

    • Pfad: .appi/.kalendion/main-instructions.md
    • Zweck: Grundlegende Entwicklungsrichtlinien
    • Enthält: 3 Goldene Regeln, Migration-Standards, Quality-Checklists
  2. Appi-Laws (KRITISCH!)

    • Pfad: .appi/.kalendion/appi-laws.md
    • Zweck: 12 architektonische Gesetze
    • STRIKTE Einhaltung - KEINE Ausnahmen!
  3. Nachtschicht To-Do (Arbeitsliste)

    • Pfad: .appi/.kalendion/nachtschicht-todo.md
    • Zweck: Detaillierte Aufgabenliste
    • Enthält: 7 Phasen mit 100+ Tasks
  4. 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!

⚠️ 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-Tabelle

Kritisches 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

  1. Dokumentation lesen (siehe oben)

  2. Admin-Panel testen

    bash
    # Browser öffnen
    https://appisym.go4family.net/admin
    
    # Fehler dokumentieren
    # Alle Error-Messages notieren
    # Stack-Traces speichern
  3. Entwicklungsumgebung 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

bash
# 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:

bash
# 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):

bash
# 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!

php
// ✅ 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!

php
// 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:

yaml
services:
    App\Appi\Foundation\Geo\Repository\CountryRepositoryInterface:
        class: App\Appi\Foundation\Geo\Repository\CountryRepository

Schritt 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:

php
// ✅ 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:

php
// 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

bash
# 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, Delete

Bei Fehlern:

  • Error-Message dokumentieren
  • Migration rollback: doctrine:migrations:execute --down Version0001_geo
  • Migration korrigieren
  • Erneut ausführen

Schritt 7: Dokumentation aktualisieren

bash
# 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!

diff
- ❌ 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:

  1. Checkbox in nachtschicht-todo.md abhaken
  2. Status-Update schreiben
  3. Commit:
bash
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:

yaml
# 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:

  1. Entity im richtigen Layer (Foundation/Core/Domain)
  2. Migration im richtigen Layer-Ordner (3_foundation, 4_core, etc.)
  3. Repository im selben Layer wie Entity
  4. CRUD Controller im Dev/Admin/Controller (falls Admin-UI nötig)
  5. Dashboard aktualisieren
  6. 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!

bash
# 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! 💪

Built with VitePress