Files
immorechner/README.md
2025-11-08 22:51:35 +01:00

17 KiB

Immorechner

Eine moderne Webanwendung zur Immobilienberechnung, entwickelt mit Symfony 7.3, PHP 8.4 und MariaDB.

Features

  • REST-API: Vollständige REST-API mit API Platform 4.2
  • Swagger/OpenAPI: Automatische interaktive API-Dokumentation (Swagger UI)
  • Web-Interface: Benutzerfreundliche Weboberfläche mit Twig-Templates
  • Immobilien-Management: Vollständige CRUD-Operationen für Immobilien mit automatischen Berechnungen
  • User Management: Benutzerverwaltung mit Rollenbasierter Zugriffskontrolle (USER, ADMIN, MODERATOR)
  • Docker-Setup: Vollständig containerisierte Entwicklungsumgebung
  • Datenbank-Migrationen: Versionskontrollierte Datenbankschema-Verwaltung mit Doctrine
  • CORS-Unterstützung: Konfigurierbare CORS-Einstellungen für API-Zugriffe
  • phpMyAdmin: Integriertes Datenbank-Verwaltungstool

Technologie-Stack

  • Backend: PHP 8.4
  • Framework: Symfony 7.3
  • Datenbank: MariaDB (Latest)
  • ORM: Doctrine 3.0
  • API: API Platform 4.2
  • Template Engine: Twig 3.22
  • Webserver: Apache 2.4 mit mod_rewrite
  • Container: Docker & Docker Compose
  • Datenbank-Tool: phpMyAdmin

Voraussetzungen

  • Docker Desktop (Windows/Mac) oder Docker Engine + Docker Compose (Linux)
  • Git

Installation

1. Repository klonen

git clone <repository-url>
cd immorechner

2. Docker-Container starten

docker-compose up -d --build

Dieser Befehl:

  • Baut das PHP 8.4 Image mit allen benötigten Extensions
  • Startet MariaDB
  • Startet phpMyAdmin
  • Startet den Apache-Webserver

3. Dependencies installieren

docker-compose exec web composer install

4. Bundle-Assets installieren

docker-compose exec web php bin/console assets:install public --symlink --relative

Dieser Schritt ist wichtig für die Swagger UI (CSS, JS, Bilder).

5. Datenbank-Schema erstellen

docker-compose exec web php bin/console doctrine:migrations:migrate --no-interaction

6. Cache leeren

docker-compose exec web php bin/console cache:clear

Verwendung

Anwendung aufrufen

Schnellstart API

Die vollständige API-Dokumentation mit allen Endpunkten, Beispielen und interaktiven Tests finden Sie im Abschnitt API-Dokumentation weiter unten.

Wichtigste Endpunkte:

  • Immobilien: /api/immobilies (GET, POST, PATCH, DELETE)
  • Benutzer: /api/users (GET, POST, PUT, DELETE)
  • Bundesländer: /api/bundeslands (GET, POST, PUT, DELETE)
  • Heizungstypen: /api/heizungstyps (GET, POST, PUT, DELETE)

Datenbank-Schema

User-Tabelle

Feld Typ Beschreibung
id INT Primärschlüssel (Auto-Increment)
name VARCHAR(255) Benutzername (min. 2 Zeichen)
email VARCHAR(255) E-Mail-Adresse (Unique)
role ENUM Benutzerrolle (user, admin, moderator)
created_at DATETIME Erstellungsdatum

Bundesland-Tabelle

Feld Typ Beschreibung
id INT Primärschlüssel (Auto-Increment)
name VARCHAR(100) Name des Bundeslandes (Unique)
grunderwerbsteuer DECIMAL(4,2) Grunderwerbsteuer in Prozent

Grunderwerbsteuer-Sätze (Stand 2025):

  • Baden-Württemberg, Bremen, Niedersachsen, Rheinland-Pfalz, Sachsen-Anhalt, Thüringen: 5,0%
  • Bayern: 3,5%
  • Hamburg, Sachsen: 5,5%
  • Berlin, Hessen, Mecklenburg-Vorpommern: 6,0%
  • Brandenburg, Nordrhein-Westfalen, Saarland, Schleswig-Holstein: 6,5%

Heizungstyp-Tabelle

Feld Typ Beschreibung
id INT Primärschlüssel (Auto-Increment)
name VARCHAR(100) Name des Heizungstyps (Unique)

Beispiele: Gasheizung, Wärmepumpe, Ölheizung, Fernwärme, etc.

Immobilien-Tabelle

Feld Typ Beschreibung
id INT Primärschlüssel (Auto-Increment)
verwalter_id INT Foreign Key zu User (Verwalter der Immobilie)
adresse VARCHAR(255) Vollständige Adresse (5-255 Zeichen)
wohnflaeche INT Wohnfläche in m² (ganze Zahl)
nutzflaeche INT Nutzfläche in m² (ganze Zahl)
garage BOOLEAN Hat Garage? (Standard: false)
zimmer INT Anzahl Zimmer (> 0)
baujahr INT Baujahr (1800-2100, optional)
typ ENUM Immobilientyp (wohnung, haus, grundstueck, gewerbe, buero)
beschreibung TEXT Freitextbeschreibung (optional)
etage INT Stockwerk (0-10, optional)
heizungstyp_id INT Foreign Key zu Heizungstyp (optional)
abschreibungszeit INT Abschreibungszeit in Jahren (0-100, optional)
bundesland_id INT Foreign Key zu Bundesland (optional)
kaufpreis INT Kaufpreis in Euro (ganze Zahl, optional)
created_at DATETIME Erstellungsdatum
updated_at DATETIME Letzte Aktualisierung

Berechnete Felder (nicht in DB gespeichert):

  • gesamtflaeche: Wohnfläche + Nutzfläche
  • kaufnebenkosten: Objekt mit Notar, Grundbuch, Grunderwerbsteuer und Gesamtsumme
    • Notarkosten: ca. 1,5% des Kaufpreises
    • Grundbuchkosten: ca. 0,5% des Kaufpreises
    • Grunderwerbsteuer: abhängig vom Bundesland (3,5% - 6,5%)

Entwicklung

Neue Entity erstellen

docker-compose exec web php bin/console make:entity

Migration erstellen

docker-compose exec web php bin/console doctrine:migrations:diff

Migration ausführen

docker-compose exec web php bin/console doctrine:migrations:migrate

Controller erstellen

docker-compose exec web php bin/console make:controller

Cache leeren

docker-compose exec web php bin/console cache:clear

Symfony Console aufrufen

docker-compose exec web php bin/console

Docker-Befehle

Container starten

docker-compose up -d

Container stoppen

docker-compose down

Container neu bauen

docker-compose up -d --build

Container-Logs anzeigen

# Alle Container
docker-compose logs -f

# Nur Web-Container
docker-compose logs -f web

# Nur Datenbank-Container
docker-compose logs -f db

In Container einloggen

# Web-Container (PHP/Apache)
docker-compose exec web bash

# Datenbank-Container
docker-compose exec db bash

Composer-Befehle ausführen

docker-compose exec web composer require <paket-name>
docker-compose exec web composer update
docker-compose exec web composer dump-autoload

Projekt-Struktur

immorechner/
├── bin/                    # Symfony Console und andere Binaries
├── config/                 # Symfony Konfigurationsdateien
├── docker/                 # Docker-Konfigurationsdateien
│   └── apache/            # Apache VirtualHost Konfiguration
├── migrations/            # Doctrine Datenbank-Migrationen
├── public/                # Web-Root (index.php, Assets)
├── src/                   # PHP-Quellcode
│   ├── Controller/       # Controller
│   ├── Entity/           # Doctrine Entities
│   ├── Enum/             # PHP Enums
│   ├── Repository/       # Doctrine Repositories
│   └── Kernel.php        # Symfony Kernel
├── templates/             # Twig-Templates
│   ├── base.html.twig   # Basis-Template
│   └── home/            # Homepage-Templates
├── var/                   # Cache, Logs
├── vendor/                # Composer Dependencies
├── .env                   # Umgebungsvariablen
├── .env.example          # Beispiel-Umgebungsvariablen
├── .gitignore            # Git Ignore-Datei
├── composer.json         # Composer-Konfiguration
├── docker-compose.yml    # Docker Compose-Konfiguration
├── Dockerfile            # Docker-Image für PHP/Apache
└── README.md             # Diese Datei

Umgebungsvariablen

Die Anwendung verwendet folgende Umgebungsvariablen (definiert in .env):

# Symfony
APP_ENV=dev
APP_SECRET=<generierter-secret-key>

# Datenbank
DATABASE_URL="mysql://immorechner_user:immorechner_pass@db:3306/immorechner?serverVersion=mariadb-11.7.1&charset=utf8mb4"

# CORS
CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$'

# Routing
DEFAULT_URI=http://localhost

Konfiguration

CORS anpassen

CORS-Einstellungen können in config/packages/nelmio_cors.yaml angepasst werden.

Datenbank-Verbindung ändern

Datenbank-Verbindung in .env anpassen:

DATABASE_URL="mysql://user:password@host:port/database?serverVersion=mariadb-11.7.1"

Apache-Konfiguration

Apache-VirtualHost-Konfiguration befindet sich in docker/apache/000-default.conf.

Fehlerbehebung

Swagger UI lädt ohne CSS/JS (Assets fehlen)

Wenn die Swagger UI unter http://localhost:8080/api/docs.html zwar lädt, aber keine Styles/Formatierung hat:

# Bundle-Assets installieren
docker-compose exec web php bin/console assets:install public --symlink --relative

# Cache leeren
docker-compose exec web php bin/console cache:clear

Danach sollten alle CSS-, JS- und Bilddateien unter /bundles/apiplatform/ verfügbar sein.

Container starten nicht

# Container-Logs prüfen
docker-compose logs

# Container-Status prüfen
docker ps -a

# Container neu bauen
docker-compose down
docker-compose up -d --build

"Class not found" Fehler

# Autoloader neu generieren
docker-compose exec web composer dump-autoload

# Cache leeren
docker-compose exec web php bin/console cache:clear

# Container neu starten
docker-compose restart web

Datenbank-Verbindungsfehler

# Prüfen ob DB-Container läuft
docker ps | grep db

# DB-Logs prüfen
docker-compose logs db

# In DB-Container einloggen und testen
docker-compose exec db mysql -u root -proot

Port bereits belegt

Wenn Port 8080, 8081 oder 3306 bereits belegt ist, können die Ports in docker-compose.yml angepasst werden:

services:
  web:
    ports:
      - "8090:80"  # Statt 8080:80

API-Dokumentation

Die Anwendung nutzt API Platform zur automatischen Generierung von OpenAPI/Swagger-Dokumentation. Die interaktive Dokumentation ermöglicht es, alle API-Endpunkte direkt im Browser zu testen.

Swagger UI (Interaktive Dokumentation)

Die Swagger UI bietet eine vollständige, interaktive Dokumentation aller API-Endpunkte:

URL: http://localhost:8080/api/docs.html

Features:

  • Übersicht aller verfügbaren Endpunkte
  • Interaktives Testen direkt im Browser
  • Detaillierte Request/Response-Schemas
  • Automatische Validierung von Parametern
  • Try-it-out Funktion für alle Operationen

OpenAPI Spezifikation

Die OpenAPI-Spezifikation (ehemals Swagger) kann in verschiedenen Formaten abgerufen werden:

OpenAPI JSON-Format

curl "http://localhost:8080/api/docs?format=json"

JSON-LD Format (Hydra)

curl http://localhost:8080/api/docs.jsonld

HTML Format (Swagger UI)

curl http://localhost:8080/api/docs.html
# oder im Browser öffnen: http://localhost:8080/api/docs.html

API-Formate

Die API unterstützt mehrere Content-Type-Formate:

Format Content-Type Beschreibung
JSON-LD application/ld+json Standard-Format mit Linked Data Kontext (Hydra)
JSON application/json Einfaches JSON-Format
HTML text/html HTML-Darstellung (Swagger UI)

Beispiel: JSON-Format verwenden

curl -H "Accept: application/json" http://localhost:8080/api/users

Beispiel: JSON-LD Format (Standard)

curl http://localhost:8080/api/users
# oder explizit:
curl -H "Accept: application/ld+json" http://localhost:8080/api/users

Verfügbare Ressourcen

Immobilien-Endpunkte

Methode Endpoint Beschreibung
GET /api/immobilies Alle Immobilien abrufen (mit Pagination)
GET /api/immobilies/{id} Einzelne Immobilie abrufen
POST /api/immobilies Neue Immobilie erstellen
PATCH /api/immobilies/{id} Immobilie teilweise aktualisieren
DELETE /api/immobilies/{id} Immobilie löschen

User-Endpunkte

Methode Endpoint Beschreibung
GET /api/users Alle User abrufen (mit Pagination)
GET /api/users/{id} Einzelnen User abrufen
POST /api/users Neuen User erstellen
PUT /api/users/{id} User vollständig ersetzen
DELETE /api/users/{id} User löschen

Bundesland-Endpunkte

Methode Endpoint Beschreibung
GET /api/bundeslands Alle Bundesländer abrufen (mit Pagination)
GET /api/bundeslands/{id} Einzelnes Bundesland abrufen
POST /api/bundeslands Neues Bundesland erstellen
PUT /api/bundeslands/{id} Bundesland vollständig ersetzen
DELETE /api/bundeslands/{id} Bundesland löschen

Heizungstyp-Endpunkte

Methode Endpoint Beschreibung
GET /api/heizungstyps Alle Heizungstypen abrufen (mit Pagination)
GET /api/heizungstyps/{id} Einzelnen Heizungstyp abrufen
POST /api/heizungstyps Neuen Heizungstyp erstellen
PUT /api/heizungstyps/{id} Heizungstyp vollständig ersetzen
DELETE /api/heizungstyps/{id} Heizungstyp löschen

Beispiele

Bundesland erstellen

curl -X POST http://localhost:8080/api/bundeslands \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Bayern",
    "grunderwerbsteuer": 3.5
  }'

Heizungstyp erstellen

curl -X POST http://localhost:8080/api/heizungstyps \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Wärmepumpe"
  }'

Immobilie erstellen

curl -X POST http://localhost:8080/api/immobilies \
  -H "Content-Type: application/json" \
  -d '{
    "verwalter": "/api/users/1",
    "adresse": "Hauptstraße 123, 12345 Musterstadt",
    "wohnflaeche": 85,
    "nutzflaeche": 15,
    "zimmer": 3,
    "typ": "wohnung",
    "garage": true,
    "baujahr": 2020,
    "heizungstyp": "/api/heizungstyps/1",
    "bundesland": "/api/bundeslands/1",
    "kaufpreis": 350000,
    "abschreibungszeit": 50,
    "etage": 3
  }'

User erstellen

curl -X POST http://localhost:8080/api/users \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Max Mustermann",
    "email": "max@example.com",
    "role": "user"
  }'

Immobilien mit Filter abrufen (Pagination)

# Erste Seite (Standard)
curl http://localhost:8080/api/immobilies

# Zweite Seite
curl http://localhost:8080/api/immobilies?page=2

Einzelne Immobilie aktualisieren (PATCH)

curl -X PATCH http://localhost:8080/api/immobilies/1 \
  -H "Content-Type: application/merge-patch+json" \
  -d '{
    "wohnflaeche": 90,
    "kaufpreis": 360000,
    "heizungstyp": "/api/heizungstyps/2"
  }'

Berechnete Felder

Die Immobilien-Entity bietet automatisch berechnete Felder:

  • gesamtflaeche: Berechnet die Gesamtfläche (Wohnfläche + Nutzfläche)
  • kaufnebenkosten: Berechnet die Kaufnebenkosten basierend auf Kaufpreis und Bundesland
    • Enthält: Notarkosten (1,5%), Grundbuchkosten (0,5%), Grunderwerbsteuer (abhängig vom Bundesland) und Gesamtsumme

Diese Felder sind schreibgeschützt (read-only) und werden automatisch bei jeder Abfrage berechnet.

Enums

Die API verwendet folgende Enums:

ImmobilienTyp:

  • wohnung - Wohnung
  • haus - Haus
  • grundstueck - Grundstück
  • gewerbe - Gewerbe
  • buero - Büro

UserRole:

  • user - Benutzer
  • admin - Administrator
  • moderator - Moderator

Relationen

Bundesland und Heizungstyp sind eigene Entities, die über Foreign Keys mit Immobilien verknüpft sind:

  • Bei der Erstellung einer Immobilie muss eine IRI verwendet werden (z.B. /api/bundeslands/1)
  • Diese Entities können über ihre eigenen Endpunkte verwaltet werden
  • Bundesländer enthalten die Grunderwerbsteuer-Sätze für die Kaufnebenkosten-Berechnung

Hydra-Unterstützung

Bei Verwendung des JSON-LD Formats (Standard) bietet die API Hydra-Unterstützung:

  • @context: Beschreibt die Linked Data Struktur
  • @id: IRI (Internationalized Resource Identifier) der Ressource
  • @type: Typ der Ressource
  • hydra:member: Array der Ressourcen in Collections
  • hydra:totalItems: Gesamtanzahl der Elemente
  • hydra:view: Pagination-Links (first, last, next, previous)

Sicherheitshinweise

Wichtig für Produktion:

  1. Ändern Sie alle Standardpasswörter in docker-compose.yml und .env
  2. Generieren Sie einen neuen APP_SECRET für .env
  3. Setzen Sie APP_ENV=prod in der Produktion
  4. Konfigurieren Sie CORS entsprechend Ihrer Domain
  5. Aktivieren Sie HTTPS
  6. Verwenden Sie sichere Datenbank-Credentials
  7. Entfernen Sie phpMyAdmin aus der Produktion

Lizenz

[Lizenz hier einfügen]

Kontakt

[Kontaktinformationen hier einfügen]