Skip to content

Development

Die Entwicklungsprinzipien von Celestia definieren die technischen Standards und Best Practices für die Implementierung von Komponenten und Features. Sie gewährleisten Code-Qualität, Wartbarkeit und konsistente Entwicklungspraktiken.

Unsere Entwicklung basiert auf folgenden Grundsätzen:

Code sollte selbsterklärend sein und verständlich für andere Entwickler. Wir priorisieren Lesbarkeit und Wartbarkeit gegenüber cleveren Lösungen.

Prinzipien:

  • Klare, beschreibende Namen für Variablen, Funktionen und Klassen
  • Funktionen mit einem klaren Zweck (Single Responsibility)
  • Vermeidung von Duplikation (DRY – Don’t Repeat Yourself)
  • Kommentare nur wo der Code nicht selbsterklärend ist

Code muss langfristig wartbar sein und sich an neue Anforderungen anpassen lassen.

Prinzipien:

  • Lose Kopplung zwischen Komponenten
  • Klare Abhängigkeiten und Imports
  • Modulare Architektur
  • Umfassende Dokumentation

Performance ist ein Feature. Wir optimieren für schnelle Ladezeiten und flüssige Interaktionen.

Prinzipien:

  • Lazy Loading wo sinnvoll
  • Optimierung von Bundle-Grössen
  • Vermeidung unnötiger Re-Renders
  • Progressive Enhancement

Komponenten-Struktur:

---
// 1. Imports
import type { HTMLAttributes } from 'astro/types';
import { clsx } from 'clsx';
// 2. Props Interface
interface Props extends HTMLAttributes<'button'> {
variant?: 'primary' | 'secondary';
size?: 'sm' | 'md' | 'lg';
isLoading?: boolean;
}
// 3. Props Destructuring mit Defaults
const {
variant = 'primary',
size = 'md',
isLoading = false,
...rest
} = Astro.props;
// 4. Computed Values
const classes = clsx(
'button',
`${variant}`,
`${size}`,
{ loading: isLoading }
);
---
<!-- 5. Template -->
<button class={classes} {...rest}>
<slot />
</button>

Naming Conventions:

  • Komponenten: PascalCase (Button.astro, CardHeader.astro)
  • Utilities: camelCase (formatDate.ts, useFocus.ts)
  • Styles: Tailwind-Utilities oder Component-scoped (kein BEM)
  • Konstanten: UPPER_SNAKE_CASE

Typisierung:

  • Strikte TypeScript-Konfiguration (strict: true)
  • Explizite Rückgabetypen für Funktionen
  • Interfaces für Objekt-Strukturen
  • Type Aliases für komplexe Typen

Beispiel:

// Interface für Props
interface ButtonProps {
variant: ButtonVariant;
size: ButtonSize;
onClick?: (event: MouseEvent) => void;
}
// Type Aliases
type ButtonVariant = "primary" | "secondary" | "tertiary";
type ButtonSize = "sm" | "md" | "lg";
// Funktion mit explizitem Rückgabetyp
function calculateButtonWidth(size: ButtonSize): number {
const widths: Record<ButtonSize, number> = {
sm: 80,
md: 120,
lg: 160,
};
return widths[size];
}

Verboten:

  • any ohne triftigen Grund
  • @ts-ignore ohne Kommentar
  • Implizite any durch fehlende Typen

Tailwind CSS:

  • Utility-First Ansatz
  • Design Tokens über Tailwind-Konfiguration
  • Custom Utilities für Celestia-spezifische Werte
  • Keine Arbitrary Values ohne Dokumentation

Best Practices:

<!-- Gut: Design Tokens nutzen -->
<button class="bg-primary-500 text-white px-4 py-2 rounded-md">
<!-- Vermeiden: Arbitrary Values -->
<button class="bg-[#007BFF] text-[white] px-[16px] py-[8px] rounded-[4px]">

CSS-Organisation:

// Komponenten-spezifische Styles
.button {
// Base styles
&.primary {
// Variant styles
}
&.disabled {
// State styles
}
&.icon {
// Child element styles
}
}

Prinzipien:

  • Korrekte HTML-Elemente für ihre semantische Bedeutung
  • Heading-Hierarchie (h1 → h2 → h3)
  • Listen (<ul>, <ol>) für Aufzählungen
  • <button> für Aktionen, <a> für Navigation
  • Landmark-Elemente (<main>, <nav>, <aside>)

Beispiel:

<!-- Gut -->
<nav aria-label="Main">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
<!-- Schlecht -->
<div class="nav">
<div class="nav-item" onclick="goHome()">Home</div>
<div class="nav-item" onclick="goAbout()">About</div>
</div>

Wir folgen dem Atomic Design Prinzip:

Atoms:

  • Grundeinheiten (Button, Input, Label)
  • Keine Abhängigkeiten
  • Höchste Wiederverwendbarkeit

Molecules:

  • Kombination von Atoms (InputGroup, SearchBar)
  • Einfache Funktionalität
  • Klar definierter Zweck

Organisms:

  • Komplexe Komponenten (Header, Hero, ProductCard)
  • Kombination aus Molecules und Atoms
  • Domain-spezifisch

Templates:

  • Seiten-Layouts ohne konkreten Content
  • Wireframe-Struktur
  • Responsive-Grids

Pages:

  • Konkrete Seiten mit Content
  • Komposition aus Organisms
  • Finale Produkte

Komponenten sollten komponierbar sein:

<Card>
<CardHeader>
<CardTitle>Überschrift</CardTitle>
<CardAction>
<Button variant="ghost">Edit</Button>
</CardAction>
</CardHeader>
<CardContent>
<p>Inhalt hier...</p>
</CardContent>
<CardFooter>
<Button variant="secondary">Cancel</Button>
<Button>Save</Button>
</CardFooter>
</Card>

Struktur:

interface Props {
// Required
children: React.ReactNode;
// Optional mit Default
variant?: "primary" | "secondary";
size?: "sm" | "md" | "lg";
// Boolean-Flags
isDisabled?: boolean;
isLoading?: boolean;
// Events
onClick?: (event: MouseEvent) => void;
onChange?: (value: string) => void;
// Accessibility
ariaLabel?: string;
ariaDescribedBy?: string;
}

Framework: Vitest

Was testen:

  • Utility-Funktionen
  • Helper-Methoden
  • Business Logic

Beispiel:

import { describe, it, expect } from "vitest";
import { formatDate } from "./formatDate";
describe("formatDate", () => {
it("formats date correctly", () => {
const date = new Date("2024-01-15");
expect(formatDate(date)).toBe("15.01.2024");
});
it("handles invalid dates", () => {
expect(formatDate(null)).toBe("");
});
});

Coverage:

  • Mindestens 80% Code-Coverage
  • 100% für kritische Business-Logic
  • Exkludiert: Type-Definitionen, simple Re-exports

Framework: Playwright

Was testen:

  • User Flows
  • Komponenten-Interaktionen
  • Formular-Validierung
  • API-Integration

Beispiel:

import { test, expect } from "@playwright/test";
test("user can complete checkout flow", async ({ page }) => {
await page.goto("/checkout");
await page.fill('[name="email"]', "test@example.com");
await page.fill('[name="card"]', "4242424242424242");
await page.click('button[type="submit"]');
await expect(page.locator(".success-message")).toBeVisible();
});

Framework: Chromatic / Storybook

Was testen:

  • Visuelle Konsistenz
  • Komponenten in verschiedenen States
  • Responsive Darstellung
  • Theme-Variationen (Light/Dark)

Tools:

  • axe-core (automatisiert)
  • Manuelle Tests mit Screenreadern
  • Tastatur-Navigation

Integration:

// In Vitest-Config
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
setupFiles: ["./test/setup.ts"],
coverage: {
provider: "v8",
reporter: ["text", "html"],
exclude: ["node_modules/", "test/"],
},
},
});

Bilder:

  • WebP-Format bevorzugen
  • Responsive Images (srcset)
  • Lazy Loading für Below-the-fold
  • Bildoptimierung im Build-Prozess

Code:

  • Tree Shaking aktivieren
  • Dynamic Imports für Heavy Components
  • Code-Splitting nach Routes
  • Minifizierung und Komprimierung

Assets:

  • CDN für statische Assets
  • Caching-Strategien
  • Service Worker für Offline-Fähigkeit

Monitoring:

  • Bundle-Analyzer im Build-Prozess
  • Budgets für Chunk-Grössen
  • Warnung bei Überschreitung

Optimierung:

  • Externe Dependencies analysieren
  • Nur benötigte Features importieren
  • Tree-shaking-freundliche Libraries wählen

Astro:

  • Static Generation wo möglich
  • Server-Side Rendering für dynamische Inhalte
  • Client-Side Rendering nur bei Interaktivitäts-Bedarf

React/Komponenten:

  • memo für pure Komponenten
  • useMemo und useCallback gezielt einsetzen
  • Virtualisierung für lange Listen

Main Branches:

  • main – Produktions-Code
  • develop – Entwicklungs-Branch

Feature Branches:

feature/CARD-123-button-component
feature/CARD-124-responsive-layout
bugfix/CARD-125-fix-navigation

Format:

<type>(<scope>): <subject>
<body>
<footer>

Types:

  • feat – Neues Feature
  • fix – Bugfix
  • docs – Dokumentation
  • style – Formatierung (keine Code-Änderung)
  • refactor – Refactoring
  • test – Tests
  • chore – Wartung

Beispiele:

feat(components): add new Button component with variants
- Implement primary, secondary, and tertiary variants
- Add loading and disabled states
- Include comprehensive Storybook stories
Fixes #123

Vor dem PR:

  • Alle Tests laufen erfolgreich
  • Linting ohne Fehler
  • TypeScript kompiliert ohne Fehler
  • Code formatiert mit Prettier
  • Self-Review durchgeführt

Review-Kriterien:

  • Code folgt den Konventionen
  • Logik ist verständlich
  • Tests sind vorhanden und aussagekräftig
  • Keine Breaking Changes (oder dokumentiert)
  • Performance-Beeinträchtigungen berücksichtigt

Inhalt:

  • Zweck des Moduls/der Komponente
  • Installationsanleitung (falls nötig)
  • Verwendungsbeispiele
  • API-Dokumentation
  • Bekannte Einschränkungen
  • Alle User-Inputs validieren
  • Sanitization bei der Darstellung
  • Prepared Statements für Datenbank-Queries
  • Content Security Policy (CSP)
  • Kein innerHTML, set:text oder set_html
  • Astro escaped automatisch
  • Regelmässige Updates
  • bun audit im Build-Prozess
  • Minimaler Einsatz von Dependencies
  • Vertrauenswürdige Libraries bevorzugen

Diese Prinzipien sind das Fundament für technische Qualität in Celestia. Regelmässige Code-Reviews und kontinuierliches Lernen tragen zur Verbesserung bei.