AdminTemplate/docs/DEVELOPMENT.md

426 lines
8.3 KiB
Markdown

# Development Guide
## Entwicklungsumgebung einrichten
### Voraussetzungen
- Go 1.21 oder höher
- Node.js 18+ und npm
- Git
- Docker (optional, für Container-Entwicklung)
### Erste Schritte
```bash
# Repository klonen oder kopieren
cd AdminTemplate
# Backend initialisieren
cd backend
go mod download
cp .env.example .env
# Frontend initialisieren
cd ../frontend
npm install
# Beide starten (mit Makefile)
cd ..
make dev
```
## Projektstruktur verstehen
### Backend (Go)
```
backend/
├── cmd/server/ # Hauptanwendung (main.go)
├── internal/
│ ├── auth/ # JWT & Passwort-Hashing
│ ├── database/ # DB-Verbindung & Migration
│ ├── handlers/ # HTTP Request Handler
│ ├── middleware/ # Auth Middleware
│ └── models/ # Datenmodelle
└── pkg/config/ # Konfiguration
```
### Frontend (Vue 3)
```
frontend/
├── src/
│ ├── components/ # Wiederverwendbare Komponenten
│ ├── views/ # Seiten-Komponenten
│ ├── router/ # Vue Router Konfiguration
│ ├── stores/ # Pinia State Management
│ ├── services/ # API Service Layer
│ └── styles/ # CSS Styles
```
## Entwicklungsworkflow
### Neue Features entwickeln
#### 1. Backend API Endpoint hinzufügen
**Schritt 1: Model definieren**
```go
// backend/internal/models/product.go
package models
type Product struct {
ID int64 `json:"id" db:"id"`
Name string `json:"name" db:"name"`
Description string `json:"description" db:"description"`
Price float64 `json:"price" db:"price"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
}
```
**Schritt 2: Handler erstellen**
```go
// backend/internal/handlers/product_handler.go
package handlers
import (
"github.com/gin-gonic/gin"
"admintemplate/internal/database"
"admintemplate/internal/models"
)
type ProductHandler struct {
db *database.DB
}
func NewProductHandler(db *database.DB) *ProductHandler {
return &ProductHandler{db: db}
}
func (h *ProductHandler) List(c *gin.Context) {
// Implementation
}
func (h *ProductHandler) Create(c *gin.Context) {
// Implementation
}
```
**Schritt 3: Routen registrieren**
```go
// backend/cmd/server/main.go
productHandler := handlers.NewProductHandler(db)
api.GET("/products", productHandler.List)
api.POST("/products", productHandler.Create)
```
**Schritt 4: Datenbank-Migration**
```go
// backend/internal/database/database.go
func (db *DB) Migrate() error {
// Bestehende Migrationen...
createProductsTable := `
CREATE TABLE IF NOT EXISTS products (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
description TEXT,
price REAL NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);`
if _, err := db.Exec(createProductsTable); err != nil {
return err
}
return nil
}
```
#### 2. Frontend Features hinzufügen
**Schritt 1: Service erstellen**
```javascript
// frontend/src/services/products.js
import api from './api'
export const productService = {
async getAll() {
const response = await api.get('/products')
return response.data
},
async create(product) {
const response = await api.post('/products', product)
return response.data
}
}
```
**Schritt 2: Store erstellen (optional)**
```javascript
// frontend/src/stores/products.js
import { defineStore } from 'pinia'
import { productService } from '../services/products'
export const useProductStore = defineStore('products', {
state: () => ({
products: []
}),
actions: {
async fetchProducts() {
this.products = await productService.getAll()
}
}
})
```
**Schritt 3: View/Komponente erstellen**
```vue
<!-- frontend/src/views/Products.vue -->
<template>
<div>
<Navbar />
<div class="container">
<h1>Produkte</h1>
<!-- Liste der Produkte -->
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { productService } from '../services/products'
import Navbar from '../components/Navbar.vue'
const products = ref([])
onMounted(async () => {
products.value = await productService.getAll()
})
</script>
```
**Schritt 4: Route hinzufügen**
```javascript
// frontend/src/router/index.js
{
path: '/products',
name: 'Products',
component: () => import('../views/Products.vue'),
meta: { requiresAuth: true }
}
```
## Anpassung für Ihr Projekt
### 1. Projekt umbenennen
```bash
# Backend: go.mod bearbeiten
cd backend
# module admintemplate -> module IhrProjektname
# Alle Imports aktualisieren
find . -type f -name "*.go" -exec sed -i 's/admintemplate/IhrProjektname/g' {} +
# Frontend: package.json bearbeiten
cd ../frontend
# "name": "IhrProjektname-frontend"
```
### 2. Branding anpassen
```javascript
// frontend/src/components/Navbar.vue
<div class="navbar-brand">Ihr Projektname</div>
// frontend/index.html
<title>Ihr Projektname</title>
```
### 3. Standard-Benutzer ändern
```go
// backend/internal/handlers/auth_handler.go
func (h *AuthHandler) InitDefaultUsers() error {
defaultUsers := []struct {
username string
password string
email string
role string
}{
{"admin", "IhrAdminPasswort", "admin@example.com", "admin"},
{"user", "IhrUserPasswort", "user@example.com", "user"},
}
// ...
}
```
## Testing
### Backend Tests
```go
// backend/internal/handlers/auth_handler_test.go
package handlers
import (
"testing"
)
func TestLogin(t *testing.T) {
// Test implementation
}
```
```bash
# Tests ausführen
cd backend
go test ./...
```
### Frontend Tests
```javascript
// frontend/src/components/__tests__/Navbar.test.js
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import Navbar from '../Navbar.vue'
describe('Navbar', () => {
it('renders properly', () => {
const wrapper = mount(Navbar)
expect(wrapper.text()).toContain('Admin Template')
})
})
```
## Debugging
### Backend
```go
// Logging hinzufügen
import "log"
log.Printf("Debug: %+v", variable)
// Mit Debugger (delve)
go install github.com/go-delve/delve/cmd/dlv@latest
dlv debug cmd/server/main.go
```
### Frontend
```javascript
// Browser DevTools Console
console.log('Debug:', data)
// Vue DevTools Extension installieren
// Chrome/Firefox: Vue.js devtools
```
## Best Practices
### Backend
1. **Fehlerbehandlung**: Immer Fehler zurückgeben und loggen
2. **Prepared Statements**: Gegen SQL-Injection
3. **Middleware**: Wiederverwendbare Logik auslagern
4. **Strukturierung**: Trennung von Handler, Service, Repository
### Frontend
1. **Komponenten**: Klein und wiederverwendbar halten
2. **State Management**: Komplexen State in Pinia Stores
3. **API Calls**: Immer über Service Layer
4. **Error Handling**: Try-catch für alle API Calls
## Häufige Aufgaben
### Neue Tabelle hinzufügen
1. Model in `internal/models/` definieren
2. Migration in `database.Migrate()` hinzufügen
3. Handler erstellen
4. Routen registrieren
### Neue Benutzerrolle hinzufügen
1. Role in Datenbank-Schema erweitern
2. Middleware für neue Rolle erstellen
3. Frontend-Router Guards anpassen
### Custom Middleware hinzufügen
```go
// backend/internal/middleware/custom.go
func CustomMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// Vor Request
c.Next()
// Nach Request
}
}
// In main.go registrieren
r.Use(middleware.CustomMiddleware())
```
## Performance-Optimierung
### Backend
- Datenbankindizes hinzufügen
- Connection Pooling konfigurieren
- Caching implementieren (z.B. Redis)
### Frontend
- Lazy Loading für Routen
- Code Splitting
- Asset Optimization (Vite macht das automatisch)
## Git Workflow
```bash
# Feature Branch erstellen
git checkout -b feature/neue-funktion
# Änderungen committen
git add .
git commit -m "feat: Neue Funktion hinzugefügt"
# In Main mergen
git checkout main
git merge feature/neue-funktion
```
## Nützliche Befehle
```bash
# Backend Hot Reload (mit air)
go install github.com/cosmtrek/air@latest
cd backend && air
# Frontend mit spezifischem Port
cd frontend && npm run dev -- --port 3001
# Alle Container neu bauen
docker-compose up -d --build --force-recreate
# Logs verfolgen
docker-compose logs -f backend
```