Aufträge: Konstanten und Fehlerklasse (L0)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1b5b5b7094
commit
16f08b5ac3
3 files changed
+143
No files matched your search
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Fehlerklasse der Aufträge-Module und einheitliche Fehlerantwort der Routen.
|
||||
* AuftragError nur für Fälle, die ein Nutzer verstehen soll (404, 409, 400 bei zu langem Text); Programmfehler
|
||||
* (ungültige Kennungen oder Typen) sind TypeError und enden als 500.
|
||||
*/
|
||||
import { InvoiceError } from '../finance/stripeFinance.js'
|
||||
|
||||
export class AuftragError extends Error {
|
||||
constructor(status, message) {
|
||||
if (!Number.isInteger(status) || status < 400 || status > 599) {
|
||||
throw new TypeError('AuftragError: Status muss eine ganze Zahl von 400 bis 599 sein.')
|
||||
}
|
||||
super(message)
|
||||
this.name = 'AuftragError'
|
||||
this.status = status
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Antwortet auf einen Fehler: AuftragError und InvoiceError mit Status und Meldung, alles andere (auch Fehler mit
|
||||
* Status von Appwrite oder Stripe) als 500 „Interner Fehler.“. Das Protokoll nennt nie die Meldung, nur die Art.
|
||||
* InvoiceError wird nur in der Funktion benutzt, nie beim Laden: stripeFinance.js importiert ab L2 selbst Module
|
||||
* dieses Verzeichnisses, so bleibt der Importzyklus harmlos.
|
||||
*/
|
||||
export function sendeFehler(res, was, err) {
|
||||
if (err instanceof AuftragError || err instanceof InvoiceError) {
|
||||
return res.status(err.status).json({ error: err.message })
|
||||
}
|
||||
console.error(`[auftraege] ${was} fehlgeschlagen:`, err?.type || err?.name || 'Error', err?.status ?? err?.statusCode ?? '', err?.code ?? '')
|
||||
return res.status(500).json({ error: 'Interner Fehler.' })
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Aufträge und Rechnungen: gemeinsame Konstanten (Übersicht V2).
|
||||
* Gemeinsame Datei: nur L0 ändert sie (Ausnahme: die eine Zeile AGB_FASSUNG, die L7 anpassen darf).
|
||||
*/
|
||||
export const RECHNUNGS_ARTEN = ['frei', 'festbetrag', 'aufwand', 'anzahlung', 'schluss']
|
||||
export const AB_RECHNUNGS_ARTEN = ['anzahlung', 'schluss'] // brauchen AB und Schalter
|
||||
export const AUFTRAG_ARTEN = ['festpreis', 'aufwand']
|
||||
export const AUFTRAG_STATUS = ['entwurf', 'versendet', 'bestaetigt', 'abgerechnet', 'storniert', 'ersetzt', 'widerrufen']
|
||||
export const VEREINBARTE_STATUS = ['versendet', 'bestaetigt', 'abgerechnet'] // zählen als „vereinbart“
|
||||
export const AUFTRAG_WEGE = { muendlich: 'mündlich', telefon: 'telefonisch', email: 'per E-Mail', vor_ort: 'vor Ort', chat: 'im Chat' }
|
||||
export const ZAHLUNGSPLAN_ARTEN = ['nach_abnahme', 'anzahlung', 'monatlich', 'frei']
|
||||
export const KUNDENARTEN = ['unternehmen', 'privat']
|
||||
export const STUNDENSATZ_STANDARD_CENTS = 10000
|
||||
export const VIERTELSTUNDE = 15
|
||||
export const TOKEN_GUELTIG_TAGE = 60
|
||||
export const AGB_FASSUNG = '2026-09-30' // L7 darf diese eine Zeile anpassen
|
||||
export const LIMITS = {
|
||||
maxPositionen: 20, maxBeschreibung: 200, maxMenge: 999, maxEinzelpreisCents: 10_000_000,
|
||||
maxSummeCents: 99_999_999, maxTitel: 200, maxZahlungsplanText: 500, maxZahlungszielTage: 60,
|
||||
standardZahlungszielTage: 14, standardAnzahlungProzent: 50, maxZeitquellen: 10,
|
||||
maxSchaetzungMinuten: 99_960, maxLeistungszeitraum: 140,
|
||||
}
|
||||
// withLocks sperrt jedes Listenelement einzeln: deshalb je Sperre GENAU EIN zusammengesetzter Schlüssel
|
||||
export const SPERRE_NUMMER = ['auftraege-nummer']
|
||||
export const sperreRechnung = (kundenId) => [`auftraege-rechnung:${kundenId}`] // Aufwand, Anzahlung, Schluss je Kunde
|
||||
export const sperreAuftrag = (id) => [`auftraege-ab:${id}`] // jede Statusänderung einer AB (L2, L3, L5)
|
||||
export const SCHALTER_AUS_MELDUNG = 'Auftragsbestätigungen sind für diesen Kunden noch nicht freigeschaltet.'
|
||||
Reference in new issue
Block a user