API updadte

This commit is contained in:
2025-11-09 11:27:21 +01:00
parent 77206224a2
commit 4953d192c0
8 changed files with 2343 additions and 784 deletions

424
docs/technical.md Normal file
View File

@@ -0,0 +1,424 @@
# Technische Dokumentation
[← Zurück zur Hauptseite](../README.md)
## Technologie-Stack
- **Backend**: PHP 8.4
- **Framework**: Symfony 7.3
- **Datenbank**: MariaDB 11.7
- **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
- **Frontend**: jQuery 3.7.1, separates CSS/JS
## Architektur
### Schichtenmodell
```
┌─────────────────────────────────────┐
│ Presentation Layer │
│ (Twig Templates, CSS, JavaScript) │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ Controller Layer │
│ (HomeController, AuthController, │
│ ImmobilienSaveController) │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ Service Layer │
│ (Security, Validation, Business │
│ Logic) │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ Persistence Layer │
│ (Doctrine ORM, Repositories) │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ Database Layer │
│ (MariaDB) │
└─────────────────────────────────────┘
```
### Komponenten
#### Frontend
- **Templates:** `templates/` (Twig)
- **CSS:** `public/css/` (calculator.css, auth.css)
- **JavaScript:** `public/js/` (calculator.js mit jQuery)
#### Backend
- **Controller:** `src/Controller/` (Request Handling)
- **Entity:** `src/Entity/` (Datenmodelle)
- **Repository:** `src/Repository/` (Datenbank-Queries)
- **Security:** `src/Security/` (Authentifizierung)
- **Enum:** `src/Enum/` (PHP Enums)
## Datenbank-Schema
### Entity-Relationship-Diagram
```
┌──────────────┐ ┌────────────────┐
│ User │ 1 * │ Immobilie │
│──────────────│◄────────│────────────────│
│ id │ │ id │
│ name │ │ verwalter_id │
│ email │ │ adresse │
│ password │ │ wohnflaeche │
│ role │ │ nutzflaeche │
│ api_key │ │ zimmer │
│ created_at │ │ kaufpreis │
└──────────────┘ │ typ │
│ ... │
└────────────────┘
┌──────────────┴──────────────┐
│ │
▼ ▼
┌───────────────┐ ┌─────────────────┐
│ Bundesland │ │ Heizungstyp │
│───────────────│ │─────────────────│
│ id │ │ id │
│ name │ │ name │
│ grunderwerbst.│ └─────────────────┘
└───────────────┘
```
### Tabellen-Details
#### User-Tabelle
| Feld | Typ | Constraints | Beschreibung |
|------|-----|-------------|--------------|
| id | INT | PK, AUTO_INCREMENT | Eindeutige ID |
| name | VARCHAR(255) | NOT NULL | Benutzername |
| email | VARCHAR(255) | NOT NULL, UNIQUE | E-Mail-Adresse |
| password | VARCHAR(255) | NULL | Bcrypt-Hash des Passworts |
| role | VARCHAR(255) | NOT NULL | Benutzerrolle (Enum) |
| api_key | VARCHAR(64) | NOT NULL, UNIQUE | SHA256 API-Key |
| created_at | DATETIME | NOT NULL | Erstellungsdatum |
**Benutzerrollen (Enum):**
- `user` - Normaler Benutzer
- `admin` - Administrator
- `moderator` - Moderator
- `technical` - Technischer User
#### Bundesland-Tabelle
| Feld | Typ | Constraints | Beschreibung |
|------|-----|-------------|--------------|
| id | INT | PK, AUTO_INCREMENT | Eindeutige ID |
| name | VARCHAR(100) | NOT NULL, UNIQUE | Name des Bundeslandes |
| grunderwerbsteuer | DECIMAL(4,2) | NOT NULL | Steuersatz in % |
**Vorbefüllt mit 16 deutschen Bundesländern**
#### Heizungstyp-Tabelle
| Feld | Typ | Constraints | Beschreibung |
|------|-----|-------------|--------------|
| id | INT | PK, AUTO_INCREMENT | Eindeutige ID |
| name | VARCHAR(100) | NOT NULL, UNIQUE | Name des Heizungstyps |
**Vorbefüllt mit:** Ölheizung, Gasheizung, Wärmepumpe, Pelletheizung
#### Immobilien-Tabelle
| Feld | Typ | Constraints | Beschreibung |
|------|-----|-------------|--------------|
| id | INT | PK, AUTO_INCREMENT | Eindeutige ID |
| verwalter_id | INT | FK → users.id, NOT NULL | Besitzer der Immobilie |
| bundesland_id | INT | FK → bundeslaender.id, NULL | Bundesland |
| heizungstyp_id | INT | FK → heizungstypen.id, NULL | Heizungstyp |
| adresse | VARCHAR(255) | NOT NULL | Vollständige Adresse |
| wohnflaeche | INT | NOT NULL | Wohnfläche in m² |
| nutzflaeche | INT | NOT NULL | Nutzfläche in m² |
| garage | BOOLEAN | NOT NULL, DEFAULT false | Garage vorhanden? |
| zimmer | INT | NOT NULL | Anzahl Zimmer |
| baujahr | INT | NULL | Baujahr (1800-2100) |
| typ | VARCHAR(255) | NOT NULL | Immobilientyp (Enum) |
| beschreibung | TEXT | NULL | Freitextbeschreibung |
| etage | INT | NULL | Stockwerk (0-10) |
| kaufpreis | INT | NULL | Kaufpreis in Euro |
| abschreibungszeit | INT | NULL | Abschreibungszeit in Jahren |
| created_at | DATETIME | NOT NULL | Erstellungsdatum |
| updated_at | DATETIME | NOT NULL | Letzte Änderung |
**Immobilientyp (Enum):**
- `wohnung` - Wohnung
- `haus` - Haus
- `grundstueck` - Grundstück
- `gewerbe` - Gewerbe
- `buero` - Büro
### Indizes
```sql
-- User
CREATE UNIQUE INDEX UNIQ_1483A5E9E7927C74 ON users (email);
CREATE UNIQUE INDEX UNIQ_1483A5E9C912ED9D ON users (api_key);
-- Bundesland
CREATE UNIQUE INDEX UNIQ_DF7DFAB25E237E06 ON bundeslaender (name);
-- Heizungstyp
CREATE UNIQUE INDEX UNIQ_6161C2A65E237E06 ON heizungstypen (name);
-- Immobilie
CREATE INDEX IDX_2C789D3E5F66D3 ON immobilien (verwalter_id);
CREATE INDEX IDX_2C789DC1B4DB52 ON immobilien (heizungstyp_id);
CREATE INDEX IDX_2C789DB74FDBEB ON immobilien (bundesland_id);
```
## Konfiguration
### Umgebungsvariablen (.env)
```env
# Symfony
APP_ENV=dev # Umgebung: dev | prod | test
APP_SECRET=<32-zeichen-hex> # Symfony Secret für Verschlüsselung
# Datenbank
DATABASE_URL="mysql://immorechner_user:immorechner_pass@db:3306/immorechner?serverVersion=mariadb-11.7.1&charset=utf8mb4"
# Routing
DEFAULT_URI=http://localhost
# CORS (für API)
CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$'
```
### Services (config/services.yaml)
```yaml
services:
_defaults:
autowire: true
autoconfigure: true
App\:
resource: '../src/'
exclude:
- '../src/Entity/'
- '../src/Repository/'
- '../src/Kernel.php'
App\Controller\:
resource: '../src/Controller/'
tags: ['controller.service_arguments']
App\Repository\:
resource: '../src/Repository/'
```
### Security (config/packages/security.yaml)
```yaml
security:
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
providers:
app_user_provider:
entity:
class: App\Entity\User
property: email
firewalls:
# API mit API-Key
api:
pattern: ^/api
stateless: true
custom_authenticators:
- App\Security\ApiKeyAuthenticator
# Frontend mit Form-Login
main:
lazy: true
provider: app_user_provider
form_login:
login_path: app_login
check_path: app_login
default_target_path: app_home
logout:
path: app_logout
target: app_home
```
### API Platform (config/packages/api_platform.yaml)
```yaml
api_platform:
title: 'Immorechner API'
version: 1.0.0
mapping:
paths: ['%kernel.project_dir%/src/Entity']
defaults:
stateless: true
formats:
jsonld: ['application/ld+json']
json: ['application/json']
```
## Docker-Konfiguration
### docker-compose.yml
```yaml
services:
web:
build: .
container_name: immorechner_web
ports:
- "8080:80"
volumes:
- .:/var/www/html
depends_on:
- db
db:
image: mariadb:latest
container_name: immorechner_db
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: immorechner
MYSQL_USER: immorechner_user
MYSQL_PASSWORD: immorechner_pass
ports:
- "3306:3306"
volumes:
- db_data:/var/lib/mysql
phpmyadmin:
image: phpmyadmin:latest
container_name: immorechner_phpmyadmin
ports:
- "8081:80"
environment:
PMA_HOST: db
PMA_USER: root
PMA_PASSWORD: root
```
### Dockerfile
```dockerfile
FROM php:8.4-apache
# Install dependencies
RUN apt-get update && apt-get install -y \
libpng-dev libonig-dev libxml2-dev libicu-dev \
libzip-dev git curl unzip
# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif \
pcntl bcmath gd zip intl opcache
# Enable Apache modules
RUN a2enmod rewrite headers
# Copy Composer
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
# Set working directory
WORKDIR /var/www/html
# Copy application
COPY . /var/www/html
# Set permissions
RUN chown -R www-data:www-data /var/www/html
```
## Performance-Optimierungen
### Opcache (Produktion)
In Produktion ist Opcache aktiviert:
```ini
opcache.enable=1
opcache.memory_consumption=256
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0
```
### Doctrine Query Cache
Doctrine nutzt automatisch Query-Cache in Produktion.
### Asset Compilation
Assets werden bei Deployment kompiliert:
```bash
php bin/console assets:install public --symlink --relative
```
## Sicherheit
### CSRF-Schutz
Alle Forms verwenden CSRF-Tokens:
```twig
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
```
### Passwort-Hashing
Passwörter werden mit bcrypt gehasht:
```php
$hashedPassword = $passwordHasher->hashPassword($user, $password);
```
### API-Key-Generierung
API-Keys sind SHA256-Hashes:
```php
return hash('sha256', random_bytes(32).microtime(true));
```
### SQL-Injection-Schutz
Doctrine ORM verhindert SQL-Injection durch Prepared Statements.
### XSS-Schutz
Twig escaped automatisch alle Ausgaben.
## Migrations
Migrationen werden mit Doctrine Migrations verwaltet:
```bash
# Neue Migration erstellen
php bin/console doctrine:migrations:diff
# Migrationen ausführen
php bin/console doctrine:migrations:migrate
# Migration-Status anzeigen
php bin/console doctrine:migrations:status
```
---
**Siehe auch:**
- [Installation](installation.md) - Setup-Anleitung
- [Development](development.md) - Entwickler-Workflow
- [Docker](docker.md) - Container-Management
[← Zurück zur Hauptseite](../README.md)