refactor(license): extract cameleer-license-api module from server-core
Some checks failed
CI / cleanup-branch (push) Has been skipped
CI / build (push) Failing after 2m57s
CI / docker (push) Has been skipped
CI / deploy (push) Has been skipped
CI / deploy-feature (push) Has been skipped

Splits the pure license contract types (LicenseInfo, LicenseValidator,
LicenseState, LicenseStateMachine, LicenseLimits, DefaultTierLimits) into a
new cameleer-license-api module under package com.cameleer.license.

Why: cameleer-license-minter previously depended on cameleer-server-core for
these types, dragging cameleer-server-core + cameleer-common onto the
classpath of every minter consumer (notably cameleer-saas). The SaaS
management plane has no business carrying server-runtime types — it only
needs the license contract to mint and verify tokens.

After:
  cameleer-license-minter -> cameleer-license-api  (no server internals)
  cameleer-server-core    -> cameleer-license-api
  cameleer-saas           -> cameleer-license-minter -> cameleer-license-api

Verified: mvn -pl cameleer-license-minter dependency:tree shows the minter
no longer pulls cameleer-server-core or cameleer-common. Full reactor
verify (-DskipITs) green: 371 tests pass.

LicenseGate stays in server-core (server-runtime state holder, not contract).

Closes cameleer/cameleer-server#156

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-26 20:06:52 +02:00
parent 30db609aff
commit 858975f03f
43 changed files with 130 additions and 52 deletions

View File

@@ -58,7 +58,7 @@ Two JARs land in `cameleer-license-minter/target/`:
```java
import com.cameleer.license.minter.LicenseMinter;
import com.cameleer.server.core.license.LicenseInfo;
import com.cameleer.license.LicenseInfo;
LicenseInfo info = new LicenseInfo(
java.util.UUID.randomUUID(),
@@ -136,11 +136,11 @@ base64(canonicalJson) + "." + base64(ed25519Signature)
- The signature is computed with `Signature.getInstance("Ed25519")` over the canonical payload bytes (not over the base64-encoded form).
- Encoding is `Base64.getEncoder()` (RFC 4648 §4 — *not* base64url). The validator decodes with the matching `Base64.getDecoder()`.
`LicenseValidator.validate(...)` (`cameleer-server-core/src/main/java/com/cameleer/server/core/license/LicenseValidator.java:42`) splits on the first `.`, decodes both halves, verifies the signature, then deserializes the payload.
`LicenseValidator.validate(...)` (`cameleer-license-api/src/main/java/com/cameleer/license/LicenseValidator.java:42`) splits on the first `.`, decodes both halves, verifies the signature, then deserializes the payload.
## LicenseInfo schema
Source: `cameleer-server-core/src/main/java/com/cameleer/server/core/license/LicenseInfo.java`. Field-by-field:
Source: `cameleer-license-api/src/main/java/com/cameleer/license/LicenseInfo.java`. Field-by-field:
| Field | Type | Required | Semantics |
|---|---|---|---|
@@ -154,7 +154,7 @@ Source: `cameleer-server-core/src/main/java/com/cameleer/server/core/license/Lic
## Limits dictionary
Canonical key set: `cameleer-server-core/src/main/java/com/cameleer/server/core/license/DefaultTierLimits.java`. Any key not listed here is silently ignored by the server's `LicenseGate.getEffectiveLimits()`.
Canonical key set: `cameleer-license-api/src/main/java/com/cameleer/license/DefaultTierLimits.java`. Any key not listed here is silently ignored by the server's `LicenseGate.getEffectiveLimits()`.
| CLI flag | Key | Default | What the server enforces |
|---|---|---|---|
@@ -284,4 +284,4 @@ mvn -pl cameleer-server-app dependency:tree | grep license-minter
# expected: empty output (or, in development branches, a single line scoped 'test')
```
`cameleer-license-minter/pom.xml` depends on `cameleer-server-core` for `LicenseInfo` and the validator round-trip used by `--verify`. The server app intentionally does not depend on the minter — vendors mint outside the customer-deployed runtime, and a compromised customer cannot leverage server code to forge tokens.
`cameleer-license-minter/pom.xml` depends on `cameleer-license-api` for the pure license contract types (`LicenseInfo`, `LicenseValidator`) used by mint + `--verify`. It deliberately does **not** depend on `cameleer-server-core`, so consumers of the minter (e.g. `cameleer-saas`) do not inherit server-runtime types onto their classpath. The server app intentionally does not depend on the minter — vendors mint outside the customer-deployed runtime, and a compromised customer cannot leverage server code to forge tokens.