# LBR Karriere – Inhalte

Dieses Repository enthält nur die **Inhalte** der Karriereseite unter <https://lbr.one/de/karriere>.
Aussehen und Aufbau der Seite liegen im Repository `lbr-landing`. Änderungen hier sind nach wenigen Minuten
live, ohne dass jemand die Website neu bauen muss.

## Dateien

| Datei | Inhalt |
| --- | --- |
| `page.json` | Texte der Karriereseite: Einstieg, Abschnitte, Überschriften der drei Bereiche |
| `jobs/jobs.json` | Offene Stellen |
| `internships/internships.json` | Praktika und Werkstudentenstellen |
| `research/research.json` | Abschlussarbeiten |
| `jobs/inactive_jobs.json` | Archiv – wird **nicht** veröffentlicht |
| `assets/` | Bilder, auf die `page.json` verweist |

Eine Stelle offline nehmen: im Eintrag `"active": false` setzen. Mit `"active": true` wird sie wieder veröffentlicht.
Alte Einträge können zusätzlich nach `jobs/inactive_jobs.json` verschoben werden, müssen es aber nicht.

## Aufbau einer Stelle

```json
{
  "active": true,
  "slug": "junior-sales-manager",
  "type": "full_time",
  "datePosted": "2026-06-29",
  "start": "2026-09",
  "validThrough": null,
  "applyUrl": "mailto:careers@lbr.one",
  "title_de": "Junior Sales Manager (m/w/d)",
  "description_short_de": "Aufbau des Vertriebs für die LBR.one und LBR Parts.",
  "description_long_de": "Mit der Markteinführung unserer ersten Serienmaschinen …",
  "tasks_de": ["Akquisition neuer Kunden …", "…"],
  "requirements_de": ["Abgeschlossenes Studium …", "…"]
}
```

| Feld | Bedeutung |
| --- | --- |
| `active` | Optional, standardmäßig `true`. Mit `false` bleibt der Inhalt in der Datei, erscheint aber weder auf der Website noch in Sitemap oder Google Jobs. |
| `slug` | Teil der Adresse: `lbr.one/de/karriere/junior-sales-manager`. Nur `a–z`, `0–9` und Bindestriche, jeder Slug nur einmal. Nach dem Veröffentlichen nicht mehr ändern, sonst funktionieren geteilte Links nicht mehr. |
| `type` | `full_time`, `part_time`, `working_student`, `internship`, `thesis` oder `initiative`. Die Website zeigt daraus „Vollzeit“, „Werkstudium“ usw. |
| `datePosted` | Datum der Ausschreibung, z. B. `2026-09-01`. Die neueste Stelle steht oben. |
| `start` | Optional. Arbeitsbeginn als `2026-10` oder `2026-10-01`. `null` bedeutet „ab sofort“. Weglassen, wenn kein Start angezeigt werden soll. |
| `validThrough` | Optional. Bewerbungsfrist, z. B. `2026-12-31`. `null` bedeutet „offen“. Nach Ablauf verschwindet die Stelle automatisch von Website, Sitemap und Google Jobs; dann Frist verlängern oder `active` auf `false` setzen. |
| `applyUrl` | `mailto:…` oder `https://…`. Bei `mailto:` setzt die Website den Betreff „Bewerbung: Titel“ automatisch. |
| `title_de` … `requirements_de` | Die Texte. `tasks_de` und `requirements_de` sind Listen. |

**Formatierung:** `**fett**` wird fett dargestellt. Absätze in `description_long_de` durch eine Leerzeile trennen,
im JSON also `\n\n`.

## Englisch

Jedes Textfeld kann ein englisches Gegenstück mit `_en` bekommen (`title_en`, `tasks_en`, …). Deutsch (`_de`) ist
Pflicht, Englisch freiwillig. Die englische Karriereseite liegt unter <https://lbr.one/karriere> (Umschalter EN/DE
oben rechts). Fehlt ein `_en`-Text, zeigt sie dort den deutschen. Eine Stelle ohne `title_en` erscheint auf Englisch
nur mit deutschem Text, wird unter der englischen Adresse nicht von Suchmaschinen indexiert und nicht an Google Jobs
gemeldet; neue Stellen daher am besten gleich mit englischen Feldern anlegen.

## Prüfung

Bei jedem Push prüft Gitea die Dateien (`node scripts/validate.mjs`). Ein roter Haken bedeutet einen Tippfehler, eine
fehlende Angabe oder ein unbekanntes Feld; die Meldung nennt Datei und Eintrag. Der Produktionsserver prüft einen neuen
Commit ebenfalls vollständig und schaltet ihn erst danach atomar frei. Bei einem Fehler bleibt die zuletzt gültige
Version online.
