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,4 +1,5 @@
import { Platform } from "react-native";
import { apiLogger } from "../logging";
const API_BASE_URL =
process.env.EXPO_PUBLIC_API_URL ||
@@ -19,20 +20,33 @@ async function request<T>(
endpoint: string,
options?: RequestOptions,
): Promise<T> {
const response = await fetch(`${API_BASE_URL}${endpoint}`, {
method,
headers: {
"Content-Type": "application/json",
...options?.headers,
},
body: options?.body ? JSON.stringify(options.body) : undefined,
});
const start = performance.now();
apiLogger.debug(`${method} ${endpoint}`);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
try {
const response = await fetch(`${API_BASE_URL}${endpoint}`, {
method,
headers: {
"Content-Type": "application/json",
...options?.headers,
},
body: options?.body ? JSON.stringify(options.body) : undefined,
});
const duration = Math.round(performance.now() - start);
if (!response.ok) {
apiLogger.error(`${method} ${endpoint} - ${response.status} (${duration}ms)`);
throw new Error(`HTTP ${response.status}`);
}
apiLogger.debug(`${method} ${endpoint} - ${response.status} (${duration}ms)`);
return response.json();
} catch (error) {
const duration = Math.round(performance.now() - start);
apiLogger.error(`${method} ${endpoint} failed (${duration}ms): ${error}`);
throw error;
}
return response.json();
}
export const ApiClient = {