fix(dev): Vite-API-Proxy, Auth, Stripe-Mails und Backend-Erweiterungen

- Client: API-Basis-URL (joinApiUrl, /v1-Falle), Vite strictPort + Proxy 127.0.0.1, Nicht-JSON-Fehler

- Server: /api-404 ohne Wildcard-Bug, SPA-Fallback, Auth-Middleware, Cron, Mailer, Crypto

- Routen: OAuth-State, Email/Stripe/Analytics; client/.env.example

Made-with: Cursor
This commit is contained in:
2026-04-03 00:23:01 +02:00
parent 61008b63bb
commit ecae89a79d
33 changed files with 1663 additions and 550 deletions

View File

@@ -3,6 +3,8 @@
* Catches all errors and returns consistent JSON responses
*/
import { AppwriteException } from 'node-appwrite'
export class AppError extends Error {
constructor(message, statusCode = 500, code = 'INTERNAL_ERROR') {
super(message)
@@ -56,11 +58,28 @@ export function errorHandler(err, req, res, next) {
stack: process.env.NODE_ENV === 'development' ? err.stack : undefined,
})
// Default error values
let statusCode = err.statusCode || 500
let code = err.code || 'INTERNAL_ERROR'
// Default error values (AppwriteException uses numeric err.code — do not reuse as JSON "code" string)
let statusCode =
typeof err.statusCode === 'number' ? err.statusCode : undefined
let code = typeof err.code === 'string' && err.code ? err.code : 'INTERNAL_ERROR'
let message = err.message || 'Ein Fehler ist aufgetreten'
if (
err instanceof AppwriteException &&
typeof err.code === 'number' &&
err.code >= 400 &&
err.code < 600
) {
statusCode = err.code
code = err.type || 'APPWRITE_ERROR'
message = err.message || message
err.isOperational = true
}
if (statusCode === undefined) {
statusCode = 500
}
// Handle specific error types
if (err.name === 'ValidationError') {
statusCode = 400