feat: implement structured logging for server and client

Server:
- Add pino and pino-http for structured logging
- Create @Logged class decorator using Proxy pattern for automatic method logging
- Add pino redact config for sensitive data (password, token, etc.)
- Move AuthMiddleware to controllers folder (per architecture diagram)
- Add LoggingMiddleware for HTTP request logging
- Replace console.log/error with structured logger in controllers and app.ts
- Decorate all repositories and GPTAdapter with @Logged

Client:
- Add react-native-logs with namespaced loggers (apiLogger, storeLogger)
- Add request/response logging to ApiClient with duration tracking
This commit is contained in:
2026-01-10 16:59:40 +01:00
parent 675785ec93
commit 71f84d1cc7
24 changed files with 576 additions and 37 deletions

View File

@@ -1,6 +1,9 @@
import { Response } from "express";
import { EventService } from "../services";
import { AuthenticatedRequest } from "../middleware";
import { createLogger } from "../logging";
import { AuthenticatedRequest } from "./AuthMiddleware";
const log = createLogger("EventController");
export class EventController {
constructor(private eventService: EventService) {}
@@ -10,7 +13,7 @@ export class EventController {
const event = await this.eventService.create(req.user!.userId, req.body);
res.status(201).json(event);
} catch (error) {
console.error("Error creating event:", error);
log.error({ error, userId: req.user?.userId }, "Error creating event");
res.status(500).json({ error: "Failed to create event" });
}
}
@@ -27,7 +30,7 @@ export class EventController {
}
res.json(event);
} catch (error) {
console.error("Error getting event:", error);
log.error({ error, eventId: req.params.id }, "Error getting event");
res.status(500).json({ error: "Failed to get event" });
}
}
@@ -37,7 +40,7 @@ export class EventController {
const events = await this.eventService.getAll(req.user!.userId);
res.json(events);
} catch (error) {
console.error("Error getting events:", error);
log.error({ error, userId: req.user?.userId }, "Error getting events");
res.status(500).json({ error: "Failed to get events" });
}
}
@@ -69,7 +72,7 @@ export class EventController {
);
res.json(events);
} catch (error) {
console.error("Error getting events by range:", error);
log.error({ error, start: req.query.start, end: req.query.end }, "Error getting events by range");
res.status(500).json({ error: "Failed to get events" });
}
}
@@ -87,7 +90,7 @@ export class EventController {
}
res.json(event);
} catch (error) {
console.error("Error updating event:", error);
log.error({ error, eventId: req.params.id }, "Error updating event");
res.status(500).json({ error: "Failed to update event" });
}
}
@@ -104,7 +107,7 @@ export class EventController {
}
res.status(204).send();
} catch (error) {
console.error("Error deleting event:", error);
log.error({ error, eventId: req.params.id }, "Error deleting event");
res.status(500).json({ error: "Failed to delete event" });
}
}