Commit Graph
5 Commits
Author SHA1 Message Date
darroyo 2ceb7ca7ea fix(frontend): reorder await api.me() before setUser in changePassword
CI / Build Native (push) Successful in 6m22s
En el fix anterior, await api.me() estaba DESPUES de setUser(u). Eso
significaba que React podria re-renderizar AuthenticatedApp entre el
setUser y el await, disparando el usePersistedState.load() que llama
api.getState() mientras la cookie todavia no estaba aplicada al
cookie store del browser. El await api.me() quedaba corriendo mientras
el 401 ya habia sido reportado.

Invertir el orden: await api.me() PRIMERO (confirma que la cookie
quedo realmente aplicada), despues setUser(u). Asi React re-renderiza
con la cookie ya activa para los fetches internos.
2026-08-15 11:24:36 -04:00
darroyo b161710952 fix(frontend): post-change-password cookie timing + defensive 401 fallback
CI / Build Native (push) Successful in 7m45s
Dos cambios para destrabar el flujo post-change-password:

1. AuthContext.changePassword: despues de setUser(u), hacer un round-trip
   a api.me() para confirmar que la nueva cookie ya es utilizable. Sin
   este paso, React monta AuthenticatedApp tan rapido que el primer
   fetch desde usePersistedState.load() corre antes de que el browser
   haya propagado el Set-Cookie (race condition reportado en Chrome).

2. usePersistedState.load: en 401, caer en makeDefaultAppState() en lugar
   de setStateInternal(null). Antes dejaba al usuario varado en un
   <LoadingScreen>Cargando tu estado...</LoadingScreen> para siempre. Ahora
   ve la app vacia con SaveIndicator, y al primer cambio real el
   auto-save sube el estado al server.
2026-08-15 03:27:31 -04:00
darroyo a171943f98 feat(auth): admin UI for user management + change-password frontend
CI / Build Native (push) Failing after 3m4s
Backend additions:
- User.lastLoginAt column (updated on each successful login)
- AdminUserSummary DTO (id, username, createdAt, lastLoginAt, isAdmin, mustChangePassword)
- GET /api/auth/admin/users (RolesAllowed("admin")) -> array of summaries
- AuthService.listUsersForAdmin() + AuthService.authenticate() now @Transactional and bumps lastLoginAt

Frontend (Phase 1):
- User type extended with mustChangePassword + isAdmin
- api.changePassword() / api.adminResetPassword() / api.adminListUsers()
- AuthContext exposes changePassword
- ChangePasswordPage.tsx (full-page, current + new + confirm, errors inline)
- App.tsx routes LoginPage -> ChangePasswordPage -> AuthenticatedApp

Frontend (Phase 2):
- TabBar supports optional 'usuarios' tab (shown only if user.isAdmin)
- UsersAdminPage.tsx: lista todos los usuarios con badges de rol y estado,
  botón "Resetear contraseña" con modal inline que llama adminResetPassword
- Header de AuthenticatedApp muestra un badge 'admin' al lado del username

Both mvn compile and npm tsc + vite build pass clean.
2026-08-14 20:07:12 -04:00
darroyo 7b89066ef3 fix(ci): gitignore was excluding src/frontend/src/data/defaults.ts
CI / Build Native (push) Failing after 3m18s
CI / Build & Push Native Image (push) Has been skipped
The .gitignore had 'data/' which matches any 'data' directory at
any depth. That excluded src/frontend/src/data/ from git, so the
file defaults.ts (with DEFAULT_INSUMOS, DEFAULT_FORMULAS, etc.)
was never committed. CI was failing with TS2307 because the file
was in the local working tree but not in the git checkout.

Tighten the rule to '/data/' so only the root runtime H2 database
folder is ignored, not the source data directory.
2026-08-12 17:57:23 -04:00
darroyo 9c9fb3a2ca feat: shot-crafter-calculator with H2 persistence and production history
Quarkus 3.20.1 monolith serving React 18 + TypeScript + Tailwind SPA.

Features:
- Three-tab calculator (Insumos, Fórmulas, Calculadora) for
  Soulshot, Spiritshot and Blessed Spiritshot crafting in Lineage 2
  Interlude/Clásico with all 15 grades and pre-loaded recipes
- Real-time profitability computation (cristales → ore →
  crafteos → shots → cost → sale → ganancia)
- Multi-user auth with JWT in httpOnly cookie (bcrypt + RSA 2048)
- H2 file-based persistence in ./data/shots.mv.db (file-based, H2)
- Auto-save on state changes (debounced 500ms)
- Production history with stats (total/avg/best/worst/last5avg)
  and per-run detail modal with snapshot of insumos+formulas

Stack:
- Backend: Quarkus REST + Hibernate ORM Panache + smallrye-jwt
- Frontend: React 18 + TypeScript + Vite + Tailwind 3
- Build: Maven runs frontend-maven-plugin (Node 22 + npm ci)
  then copies dist to META-INF/resources for Quarkus to serve

Verified:
- 5 backend endpoints + 5 history endpoints with curl
- 35/35 browser tests via Playwright + Chromium
- All TS strict, all builds green
2026-08-12 16:03:51 -04:00