dorfteich/packages/shared/i18n/de/errors.json
Claude Sonnet 5 a645763679
All checks were successful
CD / Build and push images (push) Successful in 2m5s
CI / Lint, typecheck, test (push) Successful in 1m45s
CI / Auth e2e pack (push) Successful in 1m50s
CI / Build container images (push) Has been skipped
CD / Deploy to Test (push) Successful in 8s
CD / Smoke tests against Test (push) Successful in 1m11s
CD / Promote to Int (push) Successful in 10s
Add page trash: soft delete, restore, and purge job (#31)
Backend: a generic maintenance-job scheduler (SchedulerService, `jobs`
table) that any later maintenance job registers with instead of
growing its own timer loop. Due-ness and the run-mutex both live in
the DB row (`lastRunAt` survives a restart; claiming a due job is one
atomic `UPDATE ... WHERE status != 'RUNNING'`), and an injectable
ClockService lets tests simulate retention elapsing without waiting or
faking the global clock.

Trash endpoints: GET /ponds/:id/trash (list), POST /pages/:id/restore,
DELETE /pages/:id/purge (manual, bypasses retention) — all sharing the
same purge logic as the scheduled daily job (default 30-day retention,
new trash.retentionDays instance setting). Purging deletes a page's
content cache, update log, and attachment files/quota; page_versions
is a placeholder until M3 exists. Direct navigation to a trashed page
now 404s with a distinguishable `page_trashed` code for editors (a
plain 404 for everyone else) instead of the generic not-found.

Attachment.pageId — added in #27 but never wired up — now gets set on
every page state save to whichever page's document currently embeds
the file, which is what lets purge find a page's files.

Frontend: a per-pond trash view (restore/purge), a "move to trash"
action with confirmation in the page menu, and a trash link in the
sidebar for pond owners. Also fixes react-query retrying 4xx responses
for several seconds by default, which was masking the trash-hint 404
in the UI (and would have affected any other not-found/permission
error the same way).

Closes #31
2026-07-08 12:48:17 +02:00

51 lines
2.6 KiB
JSON

{
"bad_request": "Die Anfrage ist ungültig.",
"unauthorized": "Bitte melde dich an, um fortzufahren.",
"forbidden": "Dir fehlt die Berechtigung für diese Aktion.",
"not_found": "Die angeforderte Ressource existiert nicht.",
"conflict": "Die Anfrage steht im Widerspruch zum aktuellen Zustand.",
"gone": "Diese Ressource ist nicht mehr verfügbar.",
"payload_too_large": "Die übermittelten Daten sind zu groß.",
"rate_limited": "Zu viele Anfragen — bitte versuche es später erneut.",
"internal_error": "Interner Serverfehler.",
"registration_closed": "Die Registrierung ist auf dieser Instanz derzeit geschlossen.",
"token_invalid": "Dieser Link ist ungültig oder abgelaufen.",
"login_failed": "Benutzername/E-Mail oder Passwort ist falsch.",
"login_backoff": "Zu viele Fehlversuche — bitte warte ein paar Minuten.",
"email_unverified": "Bitte bestätige zuerst deine E-Mail-Adresse.",
"account_disabled": "Dieses Konto wurde deaktiviert.",
"password_incorrect": "Das aktuelle Passwort ist falsch.",
"csrf_origin_mismatch": "Die Anfrage kam von einer unerwarteten Herkunft.",
"cannot_revoke_current_session": "Beende deine aktuelle Sitzung über die Abmeldung.",
"personal_pond_undeletable": "Der persönliche Teich kann nicht gelöscht werden.",
"quota_exceeded": "Das Kontingent ist erreicht (Limit: {{limit}}).",
"slug_taken": "Dieser Adressname ist in diesem Teich bereits vergeben.",
"page_document_too_large": "Die Seite ist zu groß (Limit: {{limitBytes}} Bytes).",
"invalid_page_state": "Der übermittelte Seiteninhalt ist ungültig.",
"page_trashed": "Diese Seite wurde in den Papierkorb verschoben.",
"unsupported_file_type": "Dieser Dateityp wird nicht unterstützt.",
"file_too_large": "Die Datei ist zu groß (Limit: {{limitBytes}} Bytes).",
"network": "Der Server war nicht erreichbar.",
"validation": {
"required": "Dieses Feld ist erforderlich.",
"taken": "Dieser Wert ist bereits vergeben.",
"username": {
"tooShort": "Der Benutzername braucht mindestens 3 Zeichen.",
"tooLong": "Der Benutzername darf höchstens 32 Zeichen haben.",
"charset": "Erlaubt sind nur Buchstaben, Ziffern und Bindestriche."
},
"password": {
"tooShort": "Das Passwort braucht mindestens 10 Zeichen.",
"tooLong": "Das Passwort darf höchstens 128 Zeichen haben.",
"tooCommon": "Dieses Passwort ist zu verbreitet."
},
"email": {
"invalid": "Bitte gib eine gültige E-Mail-Adresse ein."
},
"displayName": {
"required": "Bitte gib einen Anzeigenamen ein."
},
"tooLong": "Die Eingabe ist zu lang."
}
}