feat(fullstack): implement observability and redesign frontend UI
Build & Push Docker Images / test-backend (push) Failing after 36s
Build & Push Docker Images / test-frontend (push) Successful in 29s
Build & Push Docker Images / build-backend (push) Has been skipped
Build & Push Docker Images / build-frontend (push) Has been skipped
Build & Push Docker Images / deploy (push) Successful in 7s

This commit introduces comprehensive observability for both backend and frontend, alongside a major UI/UX overhaul to align with modern design standards (Material 3 inspired) and improve localization.

Backend changes:
- Integrated OpenTelemetry SDK for distributed tracing.
- Added Pino for structured JSON logging with OTel instrumentation for trace/span correlation.
- Configured OTLP exporters to route traces and logs to Grafana Alloy.
- Updated docker-compose to include necessary environment variables for observability.

Frontend changes:
- Integrated Grafana Faro for Real User Monitoring (RUM), capturing Web Vitals, JS errors, and user interactions.
- Redesigned the entire UI using a new color palette and Material 3 design principles.
- Refactored component architecture (App, Home, Search, Scanner, Profile, Alerts views) for better state management and navigation.
- Improved mobile UX with a redesigned Bottom Navigation bar and Top Bar.
- Localized the interface to Spanish (es).
- Updated assets, icons, and PWA configuration (manifest, icons).
- Refactored CSS to use a centralized design token system (CSS variables).

Observability enables better debugging and performance monitoring across the entire stack.
This commit is contained in:
Antoni Nuñez Romeu
2026-07-01 11:48:27 +02:00
parent 9316f6c54f
commit db0935eb16
46 changed files with 5633 additions and 1867 deletions
+13
View File
@@ -1,3 +1,6 @@
// OpenTelemetry SDK — must be imported first to instrument http, express, pg, etc.
import './src/tracing.js';
import express from 'express';
import cors from 'cors';
import sqlite3 from 'sqlite3';
@@ -11,6 +14,8 @@ import pg from 'pg';
import bcrypt from 'bcrypt';
import rateLimit from 'express-rate-limit';
import webpush from 'web-push';
import pino from 'pino';
import pinoHttp from 'pino-http';
import { searchMedicines, getMedicineDetails } from './cima-service.js';
import { runFarmaciaWebhookImport, DEFAULT_FARMACIAS_WEBHOOK, importPharmaciesFromRows } from './farmacias-webhook-import.js';
import { fetchPharmaciesExternal } from '../API/index.js';
@@ -21,6 +26,13 @@ const __dirname = path.dirname(__filename);
const app = express();
const PORT = process.env.PORT || 3001;
// Structured JSON logger. The Pino OTel instrumentation attaches trace_id /
// span_id to every log line so they can be correlated in Grafana.
const logger = pino({
level: process.env.LOG_LEVEL || 'info',
base: { service: process.env.OTEL_SERVICE_NAME || 'farmafinder-backend' },
});
// Trust the reverse proxy in front of us (Docker/Traefik/nginx/Cloudflare) so
// req.ip and X-Forwarded-For are honored. Configurable via TRUST_PROXY:
// - unset/"1" → trust exactly one hop (typical single reverse proxy)
@@ -39,6 +51,7 @@ app.use(cors({
credentials: true
}));
app.use(express.json());
app.use(pinoHttp({ logger }));
const PG_URL = process.env.PG_URL;
let pgPool = null;