fix: resolve token expiration clock skew and remove Keycloak docs

This commit is contained in:
Gabriel Menezes 2026-10-09 10:20:06 -04:00
parent b05ff9651a
commit 33b24b62d5
3 changed files with 7 additions and 10 deletions

View file

@ -4,7 +4,7 @@ Guidance for Claude Code when working in this repository. Keep edits aligned wit
## Project ## Project
**bee-task-v3 / TimeTrack** — task & time-tracking SaaS. Monorepo with React (Vite) frontend and Quarkus backend, PostgreSQL + Keycloak via Docker. Backlog and user stories live in `backlog.md`. **bee-task-v3 / TimeTrack** — task & time-tracking SaaS. Monorepo with React (Vite) frontend and Quarkus backend, PostgreSQL via Docker. Backlog and user stories live in `backlog.md`.
## Layout ## Layout
@ -12,7 +12,7 @@ Guidance for Claude Code when working in this repository. Keep edits aligned wit
backend/ Quarkus 3.34, Java 17, Hibernate ORM + Panache, Flyway, JWT (smallrye) backend/ Quarkus 3.34, Java 17, Hibernate ORM + Panache, Flyway, JWT (smallrye)
frontend/ Vite + React 19 + TypeScript + Tailwind v4 frontend/ Vite + React 19 + TypeScript + Tailwind v4
docker/ Postgres init scripts docker/ Postgres init scripts
docker-compose.yml Postgres + Keycloak docker-compose.yml Postgres
specification/ Domain specs specification/ Domain specs
backlog.md User stories (US-001…) backlog.md User stories (US-001…)
``` ```
@ -21,7 +21,7 @@ Java root package: `net.beetechgroup.beetask`.
## Commands ## Commands
Infra: `docker-compose up` (Postgres :5432, Keycloak :8081). Infra: `docker-compose up` (Postgres :5432).
Backend (`cd backend`): Backend (`cd backend`):
- Dev: `./mvnw quarkus:dev` (port 8080, uses H2 in dev profile, swagger at `/swagger`, OpenAPI at `/openapi`) - Dev: `./mvnw quarkus:dev` (port 8080, uses H2 in dev profile, swagger at `/swagger`, OpenAPI at `/openapi`)
@ -92,7 +92,6 @@ The authenticated email comes from `securityIdentity.getPrincipal().getName()` a
### Auth ### Auth
- JWT signed with `privateKey.pem`, verified with `publicKey.pem`. Issuer `https://beetech.net`. - JWT signed with `privateKey.pem`, verified with `publicKey.pem`. Issuer `https://beetech.net`.
- Keycloak is provisioned in docker-compose but **not yet integrated** into the app — JWTs are minted by `usecase/auth/login`.
## Frontend Conventions ## Frontend Conventions

View file

@ -5,17 +5,16 @@ Minimal vertical slice for task management using:
- React + TypeScript + Tailwind CSS - React + TypeScript + Tailwind CSS
- Java + Quarkus - Java + Quarkus
- PostgreSQL - PostgreSQL
- Keycloak prepared for future authentication
## Structure ## Structure
- `frontend/`: Vite React app with task list, task creation, and status updates - `frontend/`: Vite React app with task list, task creation, and status updates
- `backend/`: Quarkus API with a simple Clean Architecture split - `backend/`: Quarkus API with a simple Clean Architecture split
- `docker-compose.yml`: local PostgreSQL and Keycloak services - `docker-compose.yml`: local PostgreSQL service
## Run infrastructure ## Run infrastructure
Start PostgreSQL and Keycloak: Start PostgreSQL:
```bash ```bash
docker-compose up docker-compose up
@ -24,8 +23,6 @@ docker-compose up
Services: Services:
- PostgreSQL: `localhost:5432` - PostgreSQL: `localhost:5432`
- Keycloak: `http://localhost:8081`
- Keycloak admin: `admin` / `admin`
## Run the backend ## Run the backend
@ -88,7 +85,6 @@ Important pragmatic decisions:
- UUIDs are generated in the application layer to keep the slice simple. - UUIDs are generated in the application layer to keep the slice simple.
- Flyway owns schema creation with a single migration. - Flyway owns schema creation with a single migration.
- Keycloak is available locally now but not integrated into the app yet.
## Verification ## Verification

View file

@ -80,6 +80,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({
const renewToken = async (refreshToken: string) => { const renewToken = async (refreshToken: string) => {
try { try {
const response = await authService.refresh(refreshToken); const response = await authService.refresh(refreshToken);
response.issuedAt = new Date().toISOString();
localStorage.setItem(STORAGE_KEYS.USER, JSON.stringify(response)); localStorage.setItem(STORAGE_KEYS.USER, JSON.stringify(response));
setUser(response); setUser(response);
} catch (error) { } catch (error) {
@ -117,6 +118,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({
const login = async (email: string, password: string) => { const login = async (email: string, password: string) => {
const response = await authService.login(email, password); const response = await authService.login(email, password);
response.issuedAt = new Date().toISOString();
localStorage.setItem(STORAGE_KEYS.USER, JSON.stringify(response)); localStorage.setItem(STORAGE_KEYS.USER, JSON.stringify(response));
setUser(response); setUser(response);
setupActiveOrg(response.organizations); setupActiveOrg(response.organizations);