Commit Graph

5 Commits

Author SHA1 Message Date
darroyo 995ed39dbc debug: enable SQL logging + auth category logging
CI / Build Native (push) Successful in 6m23s
Para diagnosticar por qué el login devuelve 401 con la password
correcta del bootstrap admin. Vamos a ver qué queries corre
Hibernate y qué pasa en el authenticate.
2026-08-15 01:46:22 -04:00
darroyo 89a224ee0c fix(bootstrap): use create-drop so tables exist on fresh H2
CI / Build Native (push) Successful in 6m16s
El schema-gen con database.generation=update NO corre en Quarkus native
(3.20.1) ni forzando quarkus.hibernate-orm.schema-management.run-on-startup=true.
El primer 'Table USERS not found' sigue saliendo en BootstrapAdmin.onStart.

Cambio a 'create-drop':
- En startup: crea las tablas que falten (no dropa las existentes).
- En shutdown limpio: drop -> POR CADA docker stop SE PIERDEN LOS USERS.

Para persistencia real a futuro: integrar Flyway con migrations y pasar
database.generation=validate. Para esta entrega, dejamos create-drop
que al menos arranca la app + bootstrap admin en un H2 fresco, y los
restarts sin SIGTERM (docker kill, caida de energia) preservan datos.

Saca tambien el run-on-startup=true que no estaba surtiendo efecto.
2026-08-15 00:15:24 -04:00
darroyo 07588979e4 fix(bootstrap): force EMF init + enable schema-gen on startup
CI / Build Native (push) Successful in 6m24s
El error 'Table USERS not found' en BootstrapAdmin.User.count() se daba
porque en Quarkus native-image, con database.generation=update, el
schema-gen NO corre en startup del container por defecto (corre solo en
dev mode). Resultado: en un H2 fresco, el primer SELECT COUNT(*) del
bootstrap pierde contra una DB sin tablas.

Dos cambios:
1. application.properties: agregar
   quarkus.hibernate-orm.schema-management.run-on-startup=true
   para forzar el schema-gen en startup en prod/native.
2. BootstrapAdmin:
   - @Transactional + EntityManager (em) inyectados
   - em.createNativeQuery('SELECT 1') al inicio de onStart() para
     asegurar que el EMF esté listo y la session esté abierta antes
     del count(). Belt-and-suspenders.
2026-08-15 00:04:17 -04:00
darroyo 1d6fc08a25 feat(auth): bootstrap admin on first boot + forced password change + admin reset
CI / Build Native (push) Has been cancelled
Backend changes (no frontend yet):

Schema (User entity)
- + mustChange_password (boolean NOT NULL, default false)
- + is_admin (boolean NOT NULL, default false)
Hibernate update mode adds both columns automatically.

BootstrapAdmin (new, ApplicationScoped, @Observes StartupEvent)
- runs only when User.count() == 0 and app.bootstrap.admin.enabled=true
- generates a 20-char random password (alphabet without 0/o/O/1/l/I)
- persists the user with isAdmin=true, mustChangePassword=true
- prints a banner to stdout AND to the JBoss logger so docker logs
  picks it up:
    BOOTSTRAP-ADMIN-USERNAME admin
    BOOTSTRAP-ADMIN-PASSWORD <random>
    BOOTSTRAP-ADMIN-CHANGE   This password MUST be changed on first login ...
- idempotent: skips if any user already exists

MustChangePasswordFilter (new, @Provider ContainerRequestFilter)
- runs after JWT auth (Priorities.AUTHENTICATION + 100)
- for authenticated requests with mustChangePassword=true, returns
  403 with {error, mustChangePassword:true} unless the path is
  /api/auth/change-password or /api/auth/logout

Change-password endpoint (POST /api/auth/change-password)
- @Authenticated, body {currentPassword, newPassword}
- verifies currentPassword via bcrypt, validates newPassword>=8 chars,
  updates hash and sets mustChangePassword=false
- returns updated AuthMeResponse and re-issues the auth cookie

Admin reset endpoint (POST /api/auth/admin/reset-password)
- @RolesAllowed("admin")
- body {username, newPassword}
- sets target's passwordHash and mustChangePassword=true (forces change
  on next login)
- security: only users in the JWT 'admin' group can hit it; isAdmin
  is stored on the user record so a stale token can't promote itself

JWT groups now include 'admin' for isAdmin users; previously everyone
was just 'user'.

Config (application.properties)
- app.bootstrap.admin.enabled=true
- app.bootstrap.admin.username=admin
2026-08-14 20:04:44 -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