Skip to content

epistola-app/epistola-suite

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

624 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Epistola Suite

Build and Publish Coverage Security Scan License: AGPL-3.0

A document suite application built with Spring Boot 4.0.0 and Kotlin, featuring server-side rendered views with Thymeleaf and HTMX.

Project Structure

epistola-suite/
├── apps/
│   └── epistola/          # Main Spring Boot application (Thymeleaf + HTMX)
├── modules/
│   └── editor/            # Rich text editor component (Vite + TypeScript)
├── build.gradle.kts       # Root build configuration
└── settings.gradle.kts    # Module includes

Architecture

The frontend uses a server-side rendering approach:

  • Thymeleaf: Template engine for rendering HTML on the server
  • HTMX: For dynamic interactions without full page reloads
  • Client components: Embedded JavaScript modules (like the editor) for features requiring rich client-side interactivity

Getting Started

Prerequisites

  1. Install mise version manager

  2. Run the init script to set up your development environment:

./scripts/init.sh

This will:

  • Configure mise in your shell (bash/zsh) if not already done
  • Install the required tool versions (Java Temurin 25, Node.js 24)
  • Install Git hooks (commitlint for conventional commit validation)
  • Configure SSH commit signing (if using SSH remote)

Build and Run

# Build the entire project
gradle build

# Run the application (requires a profile — see Authentication below)
gradle :apps:epistola:bootRun --args='--spring.profiles.active=local'

Authentication

A Spring profile must be set to configure authentication. Without one, the app will fail to start.

Profile Auth Method Use Case
local Form login (in-memory users) Local development
demo Form login (in-memory users) K8s demo environments
keycloak OAuth2/OIDC (local Keycloak) Testing OAuth2 locally
prod OAuth2/OIDC (external Keycloak) Production
local,keycloak Both form + OAuth2 Testing both login methods

Local development — uses in-memory users, no external dependencies:

gradle :apps:epistola:bootRun --args='--spring.profiles.active=local'
# Login: admin@local / admin  or  user@local / user

With local services — start PostgreSQL and Keycloak via the unified Docker Compose:

# Start PostgreSQL + Keycloak (admin console at http://localhost:8080, admin/admin)
docker compose -f apps/epistola/docker/docker-compose.yaml up -d

# Or start only PostgreSQL (sufficient for local profile)
docker compose -f apps/epistola/docker/docker-compose.yaml up -d postgres

# Run with OAuth2 only
gradle :apps:epistola:bootRun --args='--spring.profiles.active=keycloak'

# Or run with both form login and OAuth2
gradle :apps:epistola:bootRun --args='--spring.profiles.active=local,keycloak'

Production — requires environment variables for your Keycloak (or any OIDC provider):

export KEYCLOAK_CLIENT_ID=epistola-suite
export KEYCLOAK_CLIENT_SECRET=<your-secret>
export KEYCLOAK_ISSUER_URI=https://keycloak.example.com/realms/epistola

See docs/auth.md for full details on Keycloak setup, auto-provisioning, and safety guards.

Docker

Build a Docker image:

gradle :apps:epistola:bootBuildImage

Run the container:

docker run --rm -p 8080:8080 epistola:0.0.1-SNAPSHOT

Helm Chart

The application can be deployed to Kubernetes using the Helm chart published to the OCI registry.

Install from the OCI registry:

helm install epistola oci://ghcr.io/epistola-app/charts/epistola --version <version>

Upgrade an existing release:

helm upgrade epistola oci://ghcr.io/epistola-app/charts/epistola --version <version>

Customize the deployment with values:

helm install epistola oci://ghcr.io/epistola-app/charts/epistola \
  --version <version> \
  --set image.tag=1.0.0 \
  --set ingress.enabled=true \
  --set ingress.hosts[0].host=epistola.example.com

See charts/epistola/values.yaml for all available configuration options.

Modules

apps/epistola

The main Spring Boot application that serves the document suite. Uses Thymeleaf for server-side HTML rendering and HTMX for dynamic interactions.

modules/editor

A Vite-based TypeScript editor component that builds as a library and is embedded in the main application for rich text editing functionality. The built assets are served from /editor/.

To develop the editor standalone:

cd modules/editor
npm install
npm run dev

Development

Code Style

This project uses ktlint for Kotlin code style. Run the linter:

# Check code style
gradle ktlintCheck

# Auto-format code
gradle ktlintFormat

Testing

gradle test

Tests use Testcontainers which requires Docker to be running.

GitHub MCP (AI-Assisted Development)

This project includes a GitHub MCP server for AI-assisted issue and project management. It enables AI assistants (like Claude Code) to interact with GitHub Issues and Projects.

Setup:

pnpm run setup:github-mcp

This will:

  1. Open GitHub to create a fine-grained Personal Access Token with minimal permissions
  2. Validate the token
  3. Store it securely in your OS credential manager (macOS Keychain or Windows Credential Vault)

Features:

  • Create and manage GitHub Issues
  • Work with Pull Requests
  • Track backlog in GitHub Projects

The configuration is in .mcp.json (safe to commit - no secrets stored).

CI/CD

The project uses GitHub Actions for CI/CD:

  • Build and test runs on all PRs and main branch pushes
  • Docker images are published to ghcr.io:
    • On main: tagged with semantic version (based on conventional commits), SHA, and latest
    • On PRs with publish label: tagged with {version}-pr-{number}-{run}
  • Helm charts are published to ghcr.io OCI registry:
    • Triggered when changes are detected in the charts/ directory
    • Tagged with chart-X.Y.Z (separate versioning from the app)
    • Published to oci://ghcr.io/epistola-app/charts

Conventional Commits

Version bumps are determined automatically from commit messages:

  • feat: - minor version bump
  • fix: - patch version bump
  • feat!: or fix!: with BREAKING CHANGE - major version bump

Both the app and Helm chart follow this convention. The Helm chart version is only bumped when changes are made to the charts/ directory.

License

See LICENSE for details.

About

Epistola is an open-source product for document creation and automation.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors