This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Build & Run
```bash
# Build WAR artifact
./mvnw clean package -DskipTests
# Run locally (port 8082)
./mvnw spring-boot:run
# Run a specific test
./mvnw test-Dtest=AppApplicationTests
```
The artifact name is `trismegisto-services.war`. It is deployed to WildFly/JBoss in production (see `src/main/WEB-INF/jboss-web.xml`).
## Architecture Overview
This is a Spring Boot 2.7.14 (Java 8) utility microservice that exposes several independent REST APIs. There is no persistent application database at startup — `DataSourceAutoConfiguration` is excluded. Database connections are established **per-request** via a special `Database` HTTP header.
### Request-scoped database connection
`JWTokenFilter` reads the `Database` header on every request. This header must contain a JWT token generated by `POST /token/database` that encodes `{db, url, user, password}`. The filter decodes it and stores a `JdbcTemplate` in `threadLocalSingleton` (a `ThreadLocal` wrapper). `RoutineSql` then picks up that `JdbcTemplate` to execute MySQL stored procedures or PostgreSQL functions via `POST /api/public/routine`.
### Security model
- Routes matching `*/public/*` are open.
- Routes matching `*/private/*` require `ADMIN` or `USER` authority.
- Auth is stateless JWT (Bearer) or HTTP Basic. Both are validated in `JWTokenFilter`.
- Users are **hardcoded in-memory** in `UserRepository` (only `admin/admin` exists by default). There is no user table.
- Two JWT secrets in `application.properties`: `app.jwtSecret` (standard tokens) and `app.jwtSecret2` (one-life tokens). One-life tokens are tracked in `tokenSingleton` (an in-memory `JSONArray`) and can be consumed once; expired/consumed tokens are purged hourly via `@Scheduled`.
`GoogleConfig` handles OAuth2 token refresh for Drive and Gmail. Credentials are loaded from classpath resources:
-`src/main/resources/tokens/oAuth2_planilla.json` — Drive + Gmail for `trismegisto.planilla@sacooliveros.edu.pe`
-`src/main/resources/tokens/oAuth2_logistica.json` — Gmail for `trismegisto.logistica@sacooliveros.edu.pe`
Each JSON file must contain `client_id`, `client_secret`, `gmail_refresh_token`, and `drive_refresh_token`.
### PDF generation
`PDFService.generatePdf(html, backgroundUrl)` uses iText 8 `HtmlConverter`. The background is injected as a CSS `@page` rule appended to the HTML. Fonts are loaded from `src/main/resources/fonts/` (Roboto-Regular, Arial). The endpoint accepts JSON body or `multipart/form-data`.
### Singletons
-`tokenSingleton` — in-memory one-life token store, Spring `@Component`, scheduled cleanup every hour.
-`threadLocalSingleton` — per-thread `JdbcTemplate` holder; set by `JWTokenFilter`, consumed by `RoutineSql`.