Skip to content

Appiyon - Hauptinstruktionen für KI-Agenten & Entwickler

Version: 1.0 Erstellt: 2025-10-25 Projekt: Appiyon (Symfony 7.3 + Doctrine ORM) Zweck: Zentrale Entwicklungsrichtlinien für konsistente, hochwertige Code-Generierung


🎯 Kernprinzipien

1. KEINE ABKÜRZUNGEN

Qualität vor Geschwindigkeit

diff
❌ FALSCH - Schnell etwas "zusammenbauen"
- Halbfertige Implementations
- "Das reicht erstmal"
- Fehlende Validierung
- Fehlende Tests
- Unvollständige Dokumentation

✅ RICHTIG - Gründlich und vollständig arbeiten
- Vollständige Implementation nach Standards
- Alle Edge Cases abdecken
- Validierung auf allen Ebenen (DB, Entity, UseCase)
- Tests für alle kritischen Pfade
- Klare, vollständige Dokumentation

Merke: Spätere Korrekturen kosten mehr Zeit als saubere Initial-Implementation!


📚 Dokumentation IMMER verwenden

Wo finde ich was?

Primäre Dokumentation: doku/docs/entwicklung/

ThemaDateiWann verwenden
🔴 Architectural Lawsarchitecture-laws.mdVOR JEDEM Code-Write
Installationinstallation.mdSetup, Dependencies
Environmentenvironment.md.env, Konfiguration
Databasedatabase.mdPostgreSQL, Doctrine
Entities erstellenguide-entities.mdNeue Entity anlegen
Use Casesguide-usecases.mdCommand/Handler Pattern
Eventsguide-events.mdEvent-System nutzen
Migrationsguide-migrations.mdDatenbank-Änderungen
Console Commandstools-commands.mdArtisan-ähnliche Commands
Testingtools-testing.mdPHPUnit Tests
Troubleshootingtroubleshooting-*.mdFehlersuche

Workflow für neue Features:

bash
1. Lese: architecture-laws.md          # Verstehe die Laws
2. Lese: guide-entities.md             # Wenn Entity benötigt
3. Lese: guide-usecases.md             # Für Command/Handler
4. Lese: guide-events.md               # Für Events
5. Lese: guide-migrations.md           # Für DB-Changes
6. Implementiere Feature                # JETZT erst Code schreiben
7. Lese: tools-testing.md              # Tests schreiben

NIEMALS Code schreiben ohne die relevanten Doku-Seiten gelesen zu haben!


🔴 Appi-Laws - STRIKTE Einhaltung

Die 12 Architectural Laws in architecture-laws.md sind NICHT optional!

Critical Laws Checkliste:

VOR jedem Code-Write prüfen:

  • [ ] Law 1: Importiere ich nur tiefere Layers? (Domain → Core → Foundation → Shared)
  • [ ] Law 2: Kommuniziere ich cross-domain nur via Events?
  • [ ] Law 3: Ist Infrastructure isoliert? (Admins ≠ Principals)
  • [ ] Law 4: Nutze ich Shared für Enums/Traits/Identity?
  • [ ] Law 5: Nutze ich principal_id korrekt? (users.principal_id = PRIMARY KEY)
  • [ ] Law 6: Habe ich team_id NUR in Dev Layer?
  • [ ] Law 7: Auth in Shared, Authz in Dev?
  • [ ] Law 8: Nutze ich Enums + CHECK statt Lookup-Tables?
  • [ ] Law 9: Folge ich Command/Handler Pattern?
  • [ ] Law 10: Sind Entities reine Datenstrukturen? (kein save(), create())
  • [ ] Law 11: Nutze ich Repository-Interfaces?
  • [ ] Law 12: Implementieren wichtige Events AuditableInterface?

Bei EINEM "Nein" → Code NICHT schreiben, erst korrigieren!


🗄️ Migration Standards

GOLDEN RULE: Non-Live = Arbeite in CREATE

sql
-- ❌ FALSCH - ALTER TABLE in Non-Live
CREATE TABLE users (...);

-- Später etwas vergessen:
ALTER TABLE users ADD COLUMN login_type VARCHAR(20);
ALTER TABLE users ADD CONSTRAINT chk_login_type CHECK (...);

-- ✅ RICHTIG - Direkt in CREATE korrigieren
CREATE TABLE users (
    principal_id INTEGER PRIMARY KEY,
    login_type VARCHAR(20) NOT NULL DEFAULT 'standard',
    CONSTRAINT chk_login_type CHECK (login_type IN ('standard', 'anonymous', 'device', 'qr_permanent'))
);

Migration File Structure

Ein Modul = Eine Migration-Datei

migrations/
├── 1_infrastructure/
│   └── Version0001_infrastructure.php     # ALLE Infrastructure-Tabellen
├── 2_shared/
│   ├── Version0002_identity.php           # ALLE Identity-Tabellen
│   └── Version0004_communication.php      # ALLE Communication-Tabellen
├── 3_foundation/
│   └── Version0005_media.php              # ALLE Media-Tabellen

NICHT:

❌ Version0002_teams.php
❌ Version0003_principals.php
❌ Version0004_users.php
❌ Version0005_crm_entries.php

✅ Version0002_identity.php  (enthält ALLES: teams, principals, users, crm_entries, etc.)

Migration Checklist:

VOR dem Schreiben:

  • [ ] Modul in EINER Datei zusammenfassen
  • [ ] Alle Abhängigkeiten beachten (teams → principals → users)
  • [ ] Enums via CHECK constraints, NICHT via foreign keys
  • [ ] SERIAL für auto-increment, nicht IDENTITY

WÄHREND des Schreibens:

  • [ ] CREATE TABLE mit ALLEN Feldern auf einmal
  • [ ] ALLE Constraints direkt in CREATE (nicht nachträglich)
  • [ ] Enums mit CHECK constraints
  • [ ] Foreign Keys mit ON DELETE CASCADE/SET NULL
  • [ ] Indices für Performance (foreign keys, unique constraints)

NACH dem Schreiben:

  • [ ] Migration in migrations/applied.txt eintragen
  • [ ] up() UND down() implementieren
  • [ ] Testen mit: php bin/console doctrine:migrations:execute --up VersionXXXX

Enum Integration in Migrations:

php
// ✅ RICHTIG - Enum Field mit CHECK Constraint
$this->addSql('CREATE TABLE principals (
    id SERIAL PRIMARY KEY,
    principal_type VARCHAR(50) NOT NULL,
    CONSTRAINT chk_principals_type CHECK (principal_type IN (\'person\', \'organization\'))
)');

// ❌ FALSCH - Foreign Key zu non-existent table
$this->addSql('CREATE TABLE principals (
    id SERIAL PRIMARY KEY,
    principal_type_id INTEGER NOT NULL,
    CONSTRAINT fk_principal_type FOREIGN KEY (principal_type_id) REFERENCES principal_types(id)
)');

Verfügbare Enums: src/Appi/Shared/Enums/

  • PrincipalType
  • EntityStatus
  • LocationType
  • OperationalStatus
  • CommunicationType

🏗️ Code-Struktur Standards

Entity Standards:

php
// ✅ RICHTIG
namespace App\Appi\Shared\Identity\Entity;

#[ORM\Entity(repositoryClass: UserRepository::class)]
#[ORM\Table(name: 'users')]
class User
{
    #[ORM\Id]
    #[ORM\Column(type: 'integer')]
    private int $principalId;  // Principal ID = User ID

    #[ORM\Column(type: 'string', enumType: LoginType::class)]
    private LoginType $loginType;

    // Getters/Setters only, NO business logic
}

// ❌ FALSCH - Active Record Pattern
class User extends Model
{
    public static function create() { }  // NO!
    public function save() { }           // NO!
}

UseCase Standards:

php
// ✅ Command (readonly DTO)
final readonly class CreateUserCommand
{
    public function __construct(
        public int $principalId,
        public LoginType $loginType,
        public ?string $username = null,
        public ?string $password = null
    ) {}
}

// ✅ Handler
final readonly class CreateUserHandler
{
    public function __construct(
        private UserRepositoryInterface $userRepository,
        private EventDispatcherInterface $eventDispatcher
    ) {}

    public function handle(CreateUserCommand $command): User
    {
        // 1. Validation
        $this->validate($command);

        // 2. Business Rules
        $user = new User();
        $user->setPrincipalId($command->principalId);
        $user->setLoginType($command->loginType);

        // 3. Persist
        $this->userRepository->save($user);

        // 4. Dispatch Event
        $this->eventDispatcher->dispatch(
            new UserCreatedEvent($user)
        );

        return $user;
    }

    private function validate(CreateUserCommand $command): void
    {
        // Validation logic
    }
}

Event Standards:

php
// ✅ RICHTIG - Implements AuditableInterface
final class UserCreatedEvent implements AuditableInterface
{
    public function __construct(
        private readonly User $user
    ) {}

    public function getEventName(): string
    {
        return 'user.created';  // {entity}.{action}
    }

    public function getAuditableType(): string
    {
        return User::class;
    }

    public function getAuditData(): array
    {
        return [
            'principal_id' => $this->user->getPrincipalId(),
            'login_type' => $this->user->getLoginType()->value
        ];
    }
}

✅ Quality Checklist

Code schreiben:

  • [ ] Relevante Doku gelesen (doku/docs/entwicklung/)
  • [ ] Appi-Laws 1-12 geprüft
  • [ ] Layer korrekt gewählt (Infrastructure/Shared/Foundation/Core/Domain/Dev)
  • [ ] Enums statt Foreign Keys verwendet
  • [ ] Command/Handler Pattern befolgt
  • [ ] Repository-Interface definiert
  • [ ] Event mit AuditableInterface erstellt

Migration schreiben:

  • [ ] Ein Modul = Eine Datei
  • [ ] CREATE statt ALTER (Non-Live!)
  • [ ] Alle Enums mit CHECK constraints
  • [ ] Alle Foreign Keys mit ON DELETE
  • [ ] Alle Indices definiert
  • [ ] up() UND down() implementiert

Testing:

  • [ ] Unit Tests für Handler geschrieben
  • [ ] Edge Cases abgedeckt
  • [ ] Validation Tests
  • [ ] Event Dispatch Tests

Dokumentation:

  • [ ] PHPDoc für alle public methods
  • [ ] README für neues Feature aktualisiert
  • [ ] Changelog aktualisiert

🚫 Absolute DON'Ts

diff
- ❌ "Das machen wir später" → NEIN! Jetzt richtig oder gar nicht
- ❌ ALTER TABLE in Non-Live → Direkt in CREATE korrigieren
- ❌ Foreign Keys zu Enums → CHECK Constraint verwenden
- ❌ Business Logic in Entities → Handler verwenden
- ❌ Cross-Domain Calls → Events verwenden
- ❌ team_id in Core/Foundation → NUR in Dev!
- ❌ Separate id + principal_id in users → principal_id IS id
- ❌ Multiple Migration Files pro Modul → EIN File pro Modul
- ❌ Code ohne Doku lesen → IMMER zuerst Doku lesen
- ❌ Laws ignorieren → Laws sind NICHT optional

📖 Weiterführende Dokumentation

Online: https://doku.appiyon.com/entwicklung/

Lokal: doku/docs/entwicklung/

Bei Unklarheiten:

  1. Doku lesen
  2. architecture-laws.md konsultieren
  3. Bestehenden Code als Referenz prüfen
  4. Nachfragen, nicht raten!

🎓 Zusammenfassung

3 Goldene Regeln:

  1. Dokumentation ZUERST lesen → Dann Code schreiben
  2. Appi-Laws STRIKT einhalten → Keine Ausnahmen
  3. KEINE Abkürzungen nehmen → Qualität über Geschwindigkeit

Bei Migration:

  • Non-Live = CREATE (kein ALTER TABLE!)
  • Ein Modul = Eine Datei
  • Enums = CHECK Constraints

Merke:

"Langsam und richtig ist schneller als schnell und falsch mit späteren Korrekturen!"


Diese Instruktionen sind die Grundlage für ALLE Code-Generierung in Appiyon.Bei Nichteinhaltung: Code wird abgelehnt und muss neu geschrieben werden.

Built with VitePress