StoryTeller/docs/development-workflow.md
Konrad Neitzel ee6e1c7cb1 Update project configuration and database setup
- Added H2 in-memory database support, replacing PostgreSQL for local development.
- Updated application properties to reflect new database configuration.
- Modified Vite build output directory to integrate with Quarkus static resources.
- Enhanced entity classes to use @Lob for character and story descriptions, allowing for larger text storage.
- Updated development workflow documentation to reflect changes in database setup and prerequisites.
2026-02-25 06:10:55 +01:00

4.5 KiB

StoryTeller Development Workflow

Stack and Layout

  • Backend: Quarkus 3.31.2 (Java 21, Maven).
  • Frontend: React 18 + TypeScript + Vite in src/main/web.
  • Database: H2 in-memory with Liquibase migrations (data resets on restart).
  • Auth: SmallRye JWT with RSA key signing; BCrypt password hashing.
  • API Contract: OpenAPI 3.0.3 at src/main/resources/openapi/story-teller-api.yaml.
  • Generated Code:
    • Java interfaces/models: target/generated-sources/openapi/java/src/gen/java/
    • TypeScript client: src/main/web/src/api/generated/

Local Setup

  1. Prerequisites: JDK 21, Maven 3.9+, Node.js 22 (managed by frontend-maven-plugin).
  2. Database: H2 in-memory — no external DB setup required. Liquibase creates the schema and seeds the admin user automatically on each startup.
  3. Build everything: mvn package (generates API code, compiles Java, builds frontend, runs tests).
  4. Run in dev mode: mvn quarkus:dev (hot reload, frontend proxy at http://localhost:5173).
  5. Frontend dev: cd src/main/web && npm run dev (standalone Vite dev server, proxies /api to Quarkus).

Default Admin Account

After first startup, Liquibase seeds an admin user:

  • Username: admin
  • Password: admin

Change this immediately in non-development environments.

OpenAPI-First Rules

  • The OpenAPI YAML is the single source of truth for backend and frontend API contracts.
  • Never edit generated files in target/generated-sources/ or src/main/web/src/api/generated/.
  • To change the API:
    1. Edit src/main/resources/openapi/story-teller-api.yaml.
    2. Run mvn generate-sources to regenerate Java and TypeScript.
    3. Update service/resource implementations to match new interfaces.

Common Commands

Command Description
mvn generate-sources Regenerate Java+TS from OpenAPI
mvn compile Compile Java backend
mvn test Run unit tests
mvn package Full build: Java + frontend + tests
mvn quarkus:dev Dev mode with hot reload
cd src/main/web && npm run dev Frontend dev server

Architecture Overview

de.neitzel.storyteller
├── business/         # Business logic services
├── common/
│   └── security/     # JWT, password hashing, auth context
├── data/
│   ├── entity/       # JPA entities
│   └── repository/   # Panache repositories
└── fascade/
    ├── api/          # Generated OpenAPI interfaces (DO NOT EDIT)
    ├── model/        # Generated OpenAPI models (DO NOT EDIT)
    └── rest/         # REST resource implementations

Authentication Flow

  1. Client sends POST /api/auth/login with username/password.
  2. Server verifies credentials, returns signed JWT with user claims.
  3. Client stores JWT in localStorage and sends it as Authorization: Bearer <token> on all subsequent requests.
  4. Quarkus SmallRye JWT validates the token on protected endpoints.
  5. AuthContext (request-scoped CDI bean) extracts user identity from the JWT.

Authorization

  • Public: /api/auth/*
  • Admin-only: /api/users/* (user management)
  • Authenticated users: /api/scenarios/*, /api/stories/* (with per-user ownership checks)

Story Generation & Compaction

The AI step generation flow includes automatic context compaction:

  1. Client sends a direction prompt.
  2. Server estimates context size (scene + characters + unmerged steps + direction).
  3. If it exceeds the limit (~12K chars), the oldest half of unmerged steps are compacted into the scene description.
  4. Steps are marked addedToScene = true after compaction.
  5. The AI generates the next step from the (possibly compacted) context.
  6. The response includes a compacted flag so the frontend can prompt the user to review the updated scene.

Note: The current AI adapter is a stub that generates placeholder text. Replace the generateAiContinuation and compactScene methods in StoryService with actual LLM integration.

Testing

  • Unit tests use JUnit 5 + Mockito in src/test/java/.
  • Tests cover auth, user service, scenario service, and story service.
  • Run with mvn test.

Troubleshooting

  • JWT errors: Ensure privateKey.pem and publicKey.pem exist in src/main/resources/.
  • Generated code issues: Run mvn clean generate-sources to rebuild from scratch.
  • TypeScript errors: Check that src/main/web/node_modules exists; run npm install in src/main/web.
  • DB issues: H2 in-memory resets on restart. If Liquibase fails, run mvn clean and restart.