Clockify marketplace add-on that reviews whether workspace users took required break time. Java 21 / Spring Boot 3.3 on the native Clockify addon-java-sdk, backed by PostgreSQL (durable tenant state) and Redis (webhook idempotency + per-workspace rate limiting). Designed for broad public-marketplace installation across many workspaces.
- Java 21 (Temurin recommended)
- Maven 3.9+
- Docker (for Testcontainers-driven integration tests)
The Clockify Java SDK is vendored under repo/com/cake/clockify/ and consumed via a file:// Maven repository declared in pom.xml, so no GitHub Packages credential is required.
- From this directory:
mvn verify - Run locally:
mvn spring-boot:run - Smoke test:
curl http://localhost:8080/healthz→{"status":"ok"}andcurl http://localhost:8080/manifest→ manifest JSON.
.
├── pom.xml
├── src/main/java/me/apet97/breakcompliance/
│ ├── addon/{auth,lifecycle,manifest,ui,webhook}/ SDK touchpoints + iframe shells
│ ├── api/ /api/* controllers (session, findings,
│ │ ingest, refresh-signals) + AddonTokenAuthFilter
│ ├── clockify/ REST client, rate limiter, report fetcher
│ ├── config/ Spring config + security headers + crypto guard
│ ├── domain/ Rule engine + preset registry
│ ├── persistence/{entities,repositories,crypto}/ JPA + AES-GCM-256 token codec
│ └── util/ Webhook path normalizer
├── src/main/resources/
│ ├── application.yaml Env-driven Spring config
│ ├── db/migration/V1__init.sql Flyway schema (V1–V9, additive only)
│ ├── logback-spring.xml Token-redacting log pattern
│ └── static/ sidebar.js, styles.css, icon.svg (64×64 designed mark)
├── docs/ Marketplace submission docs
├── repo/com/cake/clockify/ Vendored Clockify SDK (jar+pom)
│ — see `pom.xml`'s `vendored-clockify-sdk` repository
└── .github/workflows/ci.yml Maven verify on PR + main
- Spring Boot 3.3 + Spring MVC — all routes are
@RestControllerclasses; the SDK is used as a manifest builder (ClockifyManifest.v1_3Builder()) + JWT verifier (ClockifySignatureParser), not as a routing framework. - PostgreSQL + Spring Data JPA + Flyway — 12 workspace-scoped tables, composite primary keys with
workspace_idleading every tenant-scoped table for schema-enforced isolation. - Redis + Spring Data Redis (Lettuce) — webhook idempotency (24-hour SETNX TTL keyed by
sha256(eventType||body)) and per-workspace Clockify-API rate limiting (50 req/sec/workspace, fixed-window). - AES-GCM-256 token codec — every installation token and webhook auth token encrypted at rest; 12-byte IV per encrypt,
keyIdfor rotation, fail-closed on any tamper. - 3-check webhook auth — RS256 signature, event-type header match, stored per-webhook authToken comparison.
- Hosted on Railway with managed Postgres + Redis add-ons and a custom-domain manifest URL.
GitHub Actions runs mvn verify on every push to main and every PR. No repo secrets are needed for the build — the Clockify SDK comes from the vendored repo/ directory, Maven Central handles everything else.
| Variable | Required | Purpose |
|---|---|---|
ADDON_BASE_URL |
yes | Manifest's baseUrl. Must match the URL Clockify hits the addon at. |
DATABASE_URL |
yes | JDBC connection string for Postgres. Railway sets this automatically. |
DATABASE_USERNAME / DATABASE_PASSWORD |
yes | Postgres credentials. |
REDIS_HOST / REDIS_PORT |
yes | Redis connection details. Railway sets these automatically. |
INSTALLATION_TOKEN_KEY |
yes | 64 hex characters → 256-bit AES key for the token codec. Generate via openssl rand -hex 32. |
INSTALLATION_TOKEN_KEY_ID |
optional | Active key id (defaults to default); supports rotation. |
CLOCKIFY_PUBLIC_KEY_URL |
optional | Override for the Clockify RSA public-key endpoint. |
ENABLE_HSTS |
optional | Set true once a custom domain serves HTTPS end-to-end. |
EXTRA_FRAME_ANCESTORS |
optional | CSV of extra frame-ancestors for the CSP (e.g. https://developer.clockify.me during dev-portal testing). |