Commit Graph

7 Commits

Author SHA1 Message Date
LakG ac3e7061ac Rediseño visual UABC + Mulish + auditoría de BD (P0/P1)
Rediseño visual:
- Nueva identidad UABC/editorial (DESIGN.md), tipografía Mulish, tokens
  verde/dorado/negro sobre bone-white, patrón de puntos verde en canvas,
  radios 8/12/30/9999, sin sombras, hairline 1px, tarjetas con leve
  transparencia + blur suave + borde verde muy sutil.
- 45 archivos .astro/.tsx alineados al nuevo sistema (Track A/B/C/D/E).
- Limpieza post-critique: eliminado triple CTA en home alumno, .card
  anidados en admin, aria-live decorativo, 26 aliases legacy en global.css,
  border-l verde en nav (patrón AI-slop), classList.remove obsoletos.

Auditoría de llamadas a BD (para 20-50 usuarios concurrentes):
- P0-1: middleware con cache in-memory de profile (30s) + is_banned (30s)
  por uid; exclusión de assets estáticos (/_astro/*, /audio/*, favicon).
  Invalidación en signout, PATCH /profile, baneos.
- P0-2: eliminado count pendientes duplicado en AppLayout; badge se
  hidrata client-side (BadgeSolicitudes con fetch inicial).
- P0-3: migración 0008 REPLICA IDENTITY FULL en solicitudes + delta
  preciso en BadgeSolicitudes (con fallback a refetch).
- P1: admin/index dedupe (4 queries → 2 con recientes.filter), catalogo
  reusa profile del middleware (3 queries → 1), inventario paralelo,
  estadisticas con cache 60s en RAM (stats-cache.ts), migración 0009
  con 3 índices (fecha, vencidos parcial, audit compuesto).

Fixes P0 de UI post-critique:
- estadisticas.astro: ReferenceError DIAS restaurado.
- solicitudes (3 vistas): error rendering sanitizado (no expone mensaje
  Postgres crudo al admin).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014xaxs8cGcQe9NwbMqA1gvn
2026-09-21 09:42:12 -07:00
LakG dea268d975 v1.7: overlay carga, baneos, carrito persistente, fix upload
Lista negra:
- Migración 0007: tabla baneos con historial (soporta expires_at futuro)
- Helper is_banned() usado por middleware
- Middleware guard: user baneado → rewrite /banned (admin exento)
- Página /banned con razón/fecha/expires + botón signout
- Panel /admin/usuarios con banear/desbanear (razón obligatoria, self-ban bloqueado)
- Nav admin nueva entrada Usuarios + icono users

Fix upload de fotos (bug definitivo):
- Root cause: browserClient no autentica al Storage (cookies httpOnly no legibles desde JS)
- Nuevos endpoints proxy /api/upload/material-foto/[id] y /avatar
- Validan sesión con cookie httpOnly, suben con service_role (bypass RLS)
- Refactor MaterialForm y PerfilForm para usar fetch multipart
- Cookies httpOnly intactas (cero riesgo XSS)

Overlay de carga:
- Layout.astro con #page-loader (backdrop-filter blur + spinner mono)
- Script inline captura clicks en <a href> y submits de <form> mismo origen
- Filtros: modifier keys, target=_blank, anchor#, cross-origin, defaultPrevented
- Respeta prefers-reduced-motion; pageshow limpia por bfcache

Carrito persistente + vaciar:
- SolicitudCart: useEffect hidrata/persiste labre:cart:v1 en localStorage
- Guard cartHydrated evita pisar en montaje inicial
- Botón "Vaciar" en checkout con window.confirm (solo con perfilCompleto)

Filtro inventario sin auto-submit:
- Removido script debounced que hacía form.submit() en cada tecla
- Botón "Filtrar" existente sigue funcionando
2026-08-27 10:18:04 -07:00
LakG bcecdbb184 Fix: self-heal del profile en middleware + backfill de users existentes
El trigger prestamos_on_auth_user_created coexiste con otro trigger del
proyecto vecino en auth.users y no siempre dispara. Consecuencia:
usuarios que hacían login vía OAuth entraban con user pero sin profile,
y la app los trataba como "no logueado".

- Middleware: si hay user y no hay profile (email @uabc.edu.mx), upsert
  del profile con datos del OAuth (nombre desde user_metadata.full_name).
- Migración 0005: policy RLS profiles_insert_self con check
  (id=auth.uid() and rol='alumno') — impide escalación a admin desde el
  self-heal.
- Backfill manual ejecutado en prod para los 8 users @uabc.edu.mx que
  ya existían en auth.users pero no tenían profile.
2026-08-24 09:36:16 -07:00
LakG e159e8d297 Perfil + onboarding + home reformulado + fixes
Perfil de usuario:
- /perfil con avatar, matrícula, semestre, tutor, foto de perfil
- /onboarding opcional (skippeable) para primer login
- Avatar con prioridad: foto propia > Google OAuth > iniciales sobre color HSL
- Endpoint PATCH /api/profile con validación y guard self-only
- Middleware carga semestre, tutor_id, foto_path
- Sidebar footer con Avatar + link a perfil

CRUD admin de maestros:
- /admin/maestros con tabla desktop / cards mobile
- MaestroForm + EliminarMaestro (mismo patrón que categorias)
- Endpoints POST/PATCH/DELETE con guard admin + 23503 traducido
- Subnav de inventario ahora incluye tab Maestros

Home reformulado:
- Alumno: saludo por hora + CTA "¿Qué vas a pedir hoy?" + card de último préstamo activo
- Admin: saludo + 2 KPIs de alerta (Pendientes, Vencidos) + últimas 2 pendientes + actividad reciente (tabla desktop, cards mobile — fix del bug 6)
- Helper saludoHora() y fmtFechaRelativa() en date.ts con offset MX

Checkout con tutor auto:
- SolicitudCart: input maestro → textarea con placeholder = nombre del tutor
- Guard perfil incompleto: CTA "Completa tu perfil" si !matricula || !tutor_id
- RPC crear_solicitud: fallback automático al nombre del tutor si textarea vacío

Fixes:
- Bug upload imagen: Dockerfile ARG + docker-compose build.args pasan PUBLIC_* al bundle client de Vite
- Grid inventario mobile: acciones en grid 2-col con prop compact en botones
- UnidadesManager mobile: tabla reemplazada por cards, select estado con min-width 130px
- Chart donut: Legend horizontal debajo (sin labels internos cortadas)
- Chart barras: YAxis width fijo 100 + tickFormatter que trunca >14 chars
- Panel admin mobile: tabla ahora tiene versión cards mobile (parte del rediseño home)
2026-08-24 08:46:39 -07:00
LakG 57b07b9b82 Rediseño impeccable: brand mark, páginas 403/404, DESIGN.md + PRODUCT.md
Rediseño hecho en sesión aparte con el skill impeccable. Se registran
las especificaciones y ajustes visuales al sistema ya en producción.

Añade:
- BrandMark.astro con el escudo/logo del laboratorio.
- Favicon actualizado (svg + ico).
- Páginas propias 403 y 404 consistentes con el sistema visual.
- DESIGN.md y PRODUCT.md documentando decisiones.
- .impeccable/design.json con el design system tokenizado.

Ajusta componentes existentes (modales, autocomplete, layout, login,
solicitudes, mis-préstamos, middleware) para alinearse a los tokens
del design system.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-16 15:19:57 -07:00
LakG 5063a4b08d Fix: agregar /api/auth/signin a PUBLIC_ROUTES
Sin esto el middleware redirige a /login antes de entrar al handler,
haciendo que el botón "Continuar con Google" cicle contra el propio
login sin llegar nunca a Google.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-14 20:22:57 -07:00
LakG 1121ab7199 Sistema de préstamos LabRe UABC — implementación inicial
Sistema web para gestión de préstamos de material del Laboratorio de
Sistemas Computacionales de la UABC.

- Backend: Supabase self-hosted, schema aislado `prestamos` con RLS,
  triggers de stock y audit log (supabase/migrations/0001_init.sql).
- Auth: Google OAuth restringido a @uabc.edu.mx, verificado en
  middleware y como segunda línea en trigger de DB.
- Frontend: Astro 7 (SSR con adapter Node) + React islands + Tailwind
  v4 con paleta UABC (primary #00723F, secondary #DD971A) bajo regla
  60/30/10.
- Interfaz alumno mobile-first: catálogo con filtro por categorías,
  solicitud de préstamos, historial personal.
- Interfaz admin desktop-first: panel con KPIs, bandeja de solicitudes
  (aprobar/rechazar/devolver), CRUD de inventario y categorías,
  reportes filtrables con export CSV nativo.
- Modales con `<dialog>` nativo, cero librerías de UI adicionales.
- Deploy: Dockerfile multi-stage node:22-alpine + docker-compose para
  publicar bajo prestamos.buglabs.dev vía Cloudflare Tunnel.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-14 19:37:49 -07:00