- Created .gitignore to exclude build artifacts and IDE files. - Added pom.xml for Maven project configuration, including dependencies for Quarkus, OpenAPI, and testing. - Introduced project documentation outlining development workflow, architecture, and coding standards. - Implemented core business logic with services for authentication, scenario management, story lifecycle, and user management. - Established security context for JWT-based authentication. - Generated API specifications and client code for frontend integration. - Set up initial database entities and repositories for user, scenario, and story management.
110 lines
4.6 KiB
Markdown
110 lines
4.6 KiB
Markdown
## StoryTeller Development Workflow
|
|
|
|
### Stack and Layout
|
|
|
|
- **Backend**: Quarkus 3.31.2 (Java 21, Maven).
|
|
- **Frontend**: React 18 + TypeScript + Vite in `src/main/web`.
|
|
- **Database**: PostgreSQL with Liquibase migrations.
|
|
- **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+, PostgreSQL, Node.js 22 (managed by frontend-maven-plugin).
|
|
2. **Database**: Create a PostgreSQL database:
|
|
```sql
|
|
CREATE DATABASE storyteller;
|
|
CREATE USER storyteller WITH PASSWORD 'storyteller';
|
|
GRANT ALL PRIVILEGES ON DATABASE storyteller TO storyteller;
|
|
```
|
|
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 connection**: Verify PostgreSQL is running and the `storyteller` database/user exist.
|