@rashidee/co2 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +25449 -0
- package/drizzle/0000_remarkable_charles_xavier.sql +210 -0
- package/drizzle/0001_wise_wolf_cub.sql +13 -0
- package/drizzle/0002_secret_spyke.sql +16 -0
- package/drizzle/0003_workspace_config_singleton.sql +16 -0
- package/drizzle/0004_terminal_claim_v120.sql +11 -0
- package/drizzle/0005_brainstorm_v124.sql +10 -0
- package/drizzle/0006_project_v140.sql +6 -0
- package/drizzle/0007_prd_wizard_v124.sql +14 -0
- package/drizzle/0008_workflow_artifact_v126.sql +24 -0
- package/drizzle/0009_project_import_v150.sql +7 -0
- package/drizzle/0010_quality_v151.sql +3 -0
- package/drizzle/meta/0000_snapshot.json +1335 -0
- package/drizzle/meta/0001_snapshot.json +1416 -0
- package/drizzle/meta/0002_snapshot.json +1510 -0
- package/drizzle/meta/_journal.json +83 -0
- package/package.json +41 -0
- package/plugin/.claude-plugin/marketplace.json +36 -0
- package/plugin/.claude-plugin/plugin.json +22 -0
- package/plugin/README.md +625 -0
- package/plugin/SKILLS.md +350 -0
- package/plugin/co2.svg +5 -0
- package/plugin/commands/brainstorm-loop.md +129 -0
- package/plugin/skills/conductor-defect/SKILL.md +898 -0
- package/plugin/skills/conductor-feature-develop/SKILL.md +1383 -0
- package/plugin/skills/conductor-feature-develop/references/implementation-domain-template.md +131 -0
- package/plugin/skills/conductor-feature-develop/references/implementation-master-template.md +89 -0
- package/plugin/skills/conductor-feature-develop/references/playwright-setup.md +224 -0
- package/plugin/skills/conductor-feature-prepare/SKILL.md +604 -0
- package/plugin/skills/depgen-k8s/SKILL.md +468 -0
- package/plugin/skills/depgen-k8s/references/dockerfile-laravel.md +197 -0
- package/plugin/skills/depgen-k8s/references/dockerfile-nodejs.md +163 -0
- package/plugin/skills/depgen-k8s/references/dockerfile-spring-boot.md +174 -0
- package/plugin/skills/depgen-k8s/references/k8s-patterns.md +869 -0
- package/plugin/skills/mockgen-shadcn/SKILL.md +1067 -0
- package/plugin/skills/mockgen-shadcn/references/admin-layout-template.md +1467 -0
- package/plugin/skills/mockgen-shadcn/references/mockup-hub-template.md +498 -0
- package/plugin/skills/mockgen-shadcn/references/mockup-index-template.md +216 -0
- package/plugin/skills/mockgen-tailwind/SKILL.md +904 -0
- package/plugin/skills/mockgen-tailwind/references/admin-layout-template.md +720 -0
- package/plugin/skills/mockgen-tailwind/references/mockup-hub-template.md +498 -0
- package/plugin/skills/mockgen-tailwind/references/mockup-index-template.md +190 -0
- package/plugin/skills/modelgen-nosql/SKILL.md +617 -0
- package/plugin/skills/modelgen-nosql/references/model-extraction-methodology.md +497 -0
- package/plugin/skills/modelgen-nosql/references/nosql-design-guide.md +258 -0
- package/plugin/skills/modelgen-relational/SKILL.md +707 -0
- package/plugin/skills/modelgen-relational/references/model-extraction-methodology.md +499 -0
- package/plugin/skills/specgen-flutter-riverpod/SKILL.md +898 -0
- package/plugin/skills/specgen-flutter-riverpod/references/component-patterns.md +971 -0
- package/plugin/skills/specgen-flutter-riverpod/references/notification-patterns.md +457 -0
- package/plugin/skills/specgen-flutter-riverpod/references/routing-patterns.md +362 -0
- package/plugin/skills/specgen-flutter-riverpod/references/security-patterns.md +709 -0
- package/plugin/skills/specgen-flutter-riverpod/references/spec-template.md +1566 -0
- package/plugin/skills/specgen-flutter-riverpod/references/state-patterns.md +518 -0
- package/plugin/skills/specgen-flutter-riverpod/references/storage-patterns.md +370 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/SKILL.md +984 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/batch-patterns.md +359 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/messaging-patterns.md +468 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/modulith-patterns.md +461 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/reporting-patterns.md +803 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/security-patterns.md +501 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/spec-template.md +1268 -0
- package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/web-patterns.md +301 -0
- package/plugin/skills/specgen-node-cli-web/SKILL.md +561 -0
- package/plugin/skills/specgen-node-cli-web/references/auth-patterns.md +293 -0
- package/plugin/skills/specgen-node-cli-web/references/cli-packaging-patterns.md +250 -0
- package/plugin/skills/specgen-node-cli-web/references/server-patterns.md +247 -0
- package/plugin/skills/specgen-node-cli-web/references/spec-template.md +401 -0
- package/plugin/skills/specgen-node-cli-web/references/testing-patterns.md +174 -0
- package/plugin/skills/specgen-react-mui/SKILL.md +789 -0
- package/plugin/skills/specgen-react-mui/references/component-patterns.md +1077 -0
- package/plugin/skills/specgen-react-mui/references/reporting-patterns.md +1998 -0
- package/plugin/skills/specgen-react-mui/references/routing-patterns.md +461 -0
- package/plugin/skills/specgen-react-mui/references/security-patterns.md +599 -0
- package/plugin/skills/specgen-react-mui/references/spec-template.md +1030 -0
- package/plugin/skills/specgen-react-mui/references/state-patterns.md +327 -0
- package/plugin/skills/specgen-react-tailwind/SKILL.md +859 -0
- package/plugin/skills/specgen-react-tailwind/references/component-patterns.md +1212 -0
- package/plugin/skills/specgen-react-tailwind/references/reporting-patterns.md +1529 -0
- package/plugin/skills/specgen-react-tailwind/references/routing-patterns.md +669 -0
- package/plugin/skills/specgen-react-tailwind/references/security-patterns.md +656 -0
- package/plugin/skills/specgen-react-tailwind/references/spec-template.md +1237 -0
- package/plugin/skills/specgen-react-tailwind/references/state-patterns.md +327 -0
- package/plugin/skills/specgen-sdk-java/SKILL.md +933 -0
- package/plugin/skills/specgen-sdk-java/references/api-extraction-patterns.md +247 -0
- package/plugin/skills/specgen-sdk-java/references/http-client-patterns.md +495 -0
- package/plugin/skills/specgen-sdk-java/references/packaging-patterns.md +366 -0
- package/plugin/skills/specgen-sdk-java/references/spec-template.md +956 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/SKILL.md +1284 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/batch-patterns.md +1224 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/jasper-patterns.md +1638 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/messaging-patterns.md +512 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/modulith-patterns.md +354 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/security-patterns.md +551 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/spec-template.md +2502 -0
- package/plugin/skills/specgen-spring-jpa-jtehtmx/references/web-patterns.md +503 -0
- package/plugin/skills/specgen-spring-jpa-restapi/SKILL.md +990 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/batch-patterns.md +1224 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/messaging-patterns.md +512 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/modulith-patterns.md +279 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/reporting-patterns.md +1536 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/restapi-patterns.md +722 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/security-patterns.md +351 -0
- package/plugin/skills/specgen-spring-jpa-restapi/references/spec-template.md +553 -0
- package/plugin/skills/specgen-ts-cli/SKILL.md +861 -0
- package/plugin/skills/specgen-ts-cli/references/async-patterns.md +1101 -0
- package/plugin/skills/specgen-ts-cli/references/command-patterns.md +383 -0
- package/plugin/skills/specgen-ts-cli/references/config-patterns.md +430 -0
- package/plugin/skills/specgen-ts-cli/references/database-patterns.md +750 -0
- package/plugin/skills/specgen-ts-cli/references/packaging-patterns.md +426 -0
- package/plugin/skills/specgen-ts-cli/references/spec-template.md +1391 -0
- package/plugin/skills/specgen-ts-cli/references/testing-patterns.md +909 -0
- package/plugin/skills/testgen-functional/SKILL.md +1381 -0
- package/plugin/skills/tracegen-matrix/SKILL.md +243 -0
- package/plugin/skills/util-preparek8senv/SKILL.md +422 -0
- package/plugin/skills/util-projectinit/SKILL.md +307 -0
- package/plugin/skills/util-projectinit/reference/brainstorm-loop.md +129 -0
- package/plugin/skills/util-projectinit/reference/brainstorm-protocol.md +144 -0
- package/plugin/skills/util-projectinit/reference/brainstorm-setup-guide.md +153 -0
- package/plugin/skills/util-projectinit/reference/brainstorm-template-appdev.md +87 -0
- package/plugin/skills/util-projectinit/reference/co2-context-generation-guide.md +761 -0
- package/plugin/skills/util-projectsync/SKILL.md +501 -0
- package/plugin/skills/util-updprd/SKILL.md +324 -0
- package/plugin/skills/util-usanalyzer/SKILL.md +307 -0
- package/plugin/skills/util-ustagger/SKILL.md +154 -0
- package/static/assets/abnfDiagram-VRR7QNED-DvPuwyCV.js +1 -0
- package/static/assets/arc-DRKw7sjs.js +1 -0
- package/static/assets/architectureDiagram-ZJ3FMSHR-CaNcxUbC.js +36 -0
- package/static/assets/blockDiagram-677ZJIJ3-Demd4AOK.js +132 -0
- package/static/assets/c4Diagram-LMCZKHZV-PVKUfc2x.js +10 -0
- package/static/assets/channel-C2nVbuwv.js +1 -0
- package/static/assets/chunk-2Q5K7J3B-CExf8ww_.js +1 -0
- package/static/assets/chunk-32BRIVSS-CFPaoONF.js +1 -0
- package/static/assets/chunk-5VM5RSS4-DE2esM67.js +15 -0
- package/static/assets/chunk-EX3LRPZG-SON_YdDG.js +231 -0
- package/static/assets/chunk-JWPE2WC7-Qxah8LNr.js +1 -0
- package/static/assets/chunk-MOJQB5TN-BcWGQV3j.js +88 -0
- package/static/assets/chunk-RYQCIY6F-DkDj-OR5.js +1 -0
- package/static/assets/chunk-V7JOEXUC-BlI1Mrah.js +206 -0
- package/static/assets/chunk-VR4S4FIN-Agf__duj.js +1 -0
- package/static/assets/chunk-XXDRQBXY-B5CfAh85.js +1 -0
- package/static/assets/classDiagram-OUVF2IWQ-DXJIljsR.js +1 -0
- package/static/assets/classDiagram-v2-EOCWNBFH-DXJIljsR.js +1 -0
- package/static/assets/cose-bilkent-JH36ORCC-DO0cQkcy.js +1 -0
- package/static/assets/cynefin-VYW2F7L2-CfOnsnXc.js +178 -0
- package/static/assets/cynefinDiagram-TSTJHNR4-BJ8tULAv.js +62 -0
- package/static/assets/cytoscape.esm-DTSO7Bv0.js +331 -0
- package/static/assets/dagre-VKFMJZFB-DfjwzHqP.js +4 -0
- package/static/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/static/assets/diagram-FQU43EPY-CndSOIIM.js +3 -0
- package/static/assets/diagram-G47NLZAW-Czf5hN0Z.js +24 -0
- package/static/assets/diagram-NH7WQ7WH-COAyojGh.js +24 -0
- package/static/assets/diagram-OA4YK3LP-H8PoiN2m.js +30 -0
- package/static/assets/diagram-WEI45ONY-DzcaVzjp.js +41 -0
- package/static/assets/ebnfDiagram-CCIWWBDH-DPazGYLJ.js +1 -0
- package/static/assets/erDiagram-Q63AITRT-Bo-fubgF.js +85 -0
- package/static/assets/flowDiagram-23GEKE2U-CSvxUDwh.js +156 -0
- package/static/assets/ganttDiagram-NO4QXBWP-DnBveWX6.js +292 -0
- package/static/assets/gitGraphDiagram-IHSO6WYX-B3rVL8c-.js +106 -0
- package/static/assets/graph-C9eacEi8.js +1 -0
- package/static/assets/index-LZSQkLE2.css +41 -0
- package/static/assets/index-y7XDSgMG.js +495 -0
- package/static/assets/infoDiagram-FWYZ7A6U-CvWV9yy2.js +2 -0
- package/static/assets/init-Gi6I4Gst.js +1 -0
- package/static/assets/ishikawaDiagram-FXEZZL3T-DF28a1N6.js +70 -0
- package/static/assets/journeyDiagram-5HDEW3XC-CB6CugYk.js +139 -0
- package/static/assets/kanban-definition-HUTT4EX6-ResSLF6d.js +89 -0
- package/static/assets/katex-C5jXJg4s.js +257 -0
- package/static/assets/layout-DEXfKzaS.js +1 -0
- package/static/assets/linear-CLO--ryk.js +1 -0
- package/static/assets/map-Czzmt4hB.js +1 -0
- package/static/assets/mindmap-definition-LN4V7U3C-BvW3EbxX.js +96 -0
- package/static/assets/ordinal-Cboi1Yqb.js +1 -0
- package/static/assets/pegDiagram-2B236MQR-BHCgqrrM.js +1 -0
- package/static/assets/pieDiagram-ENE6RG2P-DVmCQ5FA.js +39 -0
- package/static/assets/quadrantDiagram-ABIIQ3AL-B3e5KR52.js +7 -0
- package/static/assets/railroadDiagram-RFXS5EU6-Csv5ysLc.js +1 -0
- package/static/assets/requirementDiagram-TGXJPOKE-DOMVzvnB.js +84 -0
- package/static/assets/sankeyDiagram-HTMAVEWB-B1dcTOvy.js +40 -0
- package/static/assets/sequenceDiagram-DBY2YBRQ-BY414yeO.js +162 -0
- package/static/assets/sizeCapture-X5ZJPWSS-CuJfrfBN.js +1 -0
- package/static/assets/stateDiagram-2N3HPSRC-FX4rJkzV.js +1 -0
- package/static/assets/stateDiagram-v2-6OUMAXLB-BVufbO_H.js +1 -0
- package/static/assets/swimlanes-5IMT3BWC-Sfy58mmv.js +2 -0
- package/static/assets/swimlanesDiagram-G3AALYLV-wDCDw08H.js +8 -0
- package/static/assets/timeline-definition-FHXFAJF6-CmV7by8p.js +120 -0
- package/static/assets/vennDiagram-L72KCM5P-FqIyFZFt.js +34 -0
- package/static/assets/wardleyDiagram-EHGQE667-BZ06O45i.js +78 -0
- package/static/assets/xychartDiagram-FW5EYKEG-BOkffR06.js +7 -0
- package/static/index.html +24 -0
|
@@ -0,0 +1,933 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: specgen-sdk-java
|
|
3
|
+
model: claude-opus-4-8
|
|
4
|
+
effort: high
|
|
5
|
+
description: >
|
|
6
|
+
Generate a detailed specification document for building a distributable Java SDK
|
|
7
|
+
library packaged as a Multi-Release fat JAR via Maven. Targets JDK 8 baseline with
|
|
8
|
+
JDK 11+ overlay classes (Multi-Release JAR) so a single artifact runs on every
|
|
9
|
+
long-term JDK in production. The SDK is a thin client wrapping a remote REST API
|
|
10
|
+
(and any additional protocols extracted from the PRD's Architecture Principle
|
|
11
|
+
section). REST communication is implemented with OkHttp; everything else
|
|
12
|
+
(JSON parsing, models, builders, retry, logging) is implemented with the JDK and
|
|
13
|
+
in-house code — third-party dependencies are kept to the absolute minimum.
|
|
14
|
+
Standardized input: application name (mandatory), version (mandatory), module (optional).
|
|
15
|
+
Use this skill whenever the user asks to create a spec, specification, blueprint, or
|
|
16
|
+
technical design document for a new Java SDK, Java client library, or REST API
|
|
17
|
+
client wrapper. Also trigger when the user says things like "spec out a new Java SDK",
|
|
18
|
+
"design a Java client library for my API", "write a technical spec for an SDK that
|
|
19
|
+
wraps Swagger/OpenAPI", "scaffold spec for a fat-jar Java SDK", or any request
|
|
20
|
+
describing a Java library that wraps a REST/HTTP API for downstream consumers.
|
|
21
|
+
Even if the user only mentions a subset (e.g., "Java wrapper around my API",
|
|
22
|
+
"client library for our microservice", "SDK that supports JDK 8 and 11"), this
|
|
23
|
+
skill likely applies — ask and confirm.
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
# Java SDK (Multi-Release Fat JAR) Specification Generator
|
|
27
|
+
|
|
28
|
+
This skill generates a comprehensive specification document (Markdown) that serves as a
|
|
29
|
+
blueprint for building a distributable Java **SDK library**. The library is published as
|
|
30
|
+
a **Multi-Release fat JAR** built with Maven, supports JDK 8 as a baseline and uses
|
|
31
|
+
JDK 11+ overlays where modern APIs are beneficial, and wraps a remote REST API
|
|
32
|
+
(plus any additional protocols defined in the PRD's Architecture Principle section).
|
|
33
|
+
|
|
34
|
+
The specification does NOT generate code. It produces a detailed, opinionated technical
|
|
35
|
+
document describing every layer of the library — from the `pom.xml` Multi-Release
|
|
36
|
+
configuration, to the OkHttp transport, to the model classes and high-level service
|
|
37
|
+
facade — so that implementation becomes a mechanical exercise.
|
|
38
|
+
|
|
39
|
+
## Library-First Mindset
|
|
40
|
+
|
|
41
|
+
This is **NOT** an application. There is no `main()` (only an optional minimal one for
|
|
42
|
+
diagnostics), no Spring, no application server, no scheduler. The output is a JAR that
|
|
43
|
+
downstream Java applications add to their classpath and call as a normal API.
|
|
44
|
+
|
|
45
|
+
Every design decision below is biased toward:
|
|
46
|
+
|
|
47
|
+
1. **Minimum third-party footprint.** Each transitive dependency the SDK pulls in becomes
|
|
48
|
+
a problem for every downstream consumer. The skill MUST resist adding libraries unless
|
|
49
|
+
the JDK and OkHttp cannot reasonably cover the use case.
|
|
50
|
+
2. **Long-lived JDK compatibility.** Consumers may run JDK 8, 11, 17, or 21. The
|
|
51
|
+
Multi-Release JAR layout lets the SDK ship one artifact that runs on all of them.
|
|
52
|
+
3. **A fat (uber) JAR as the primary artifact.** Consumers either drop the fat JAR onto
|
|
53
|
+
the classpath or depend on it via Maven; either way they get one self-contained file.
|
|
54
|
+
|
|
55
|
+
## Technology Stack
|
|
56
|
+
|
|
57
|
+
### Core Stack (Always Included)
|
|
58
|
+
|
|
59
|
+
These versions are fixed unless the user explicitly overrides them.
|
|
60
|
+
|
|
61
|
+
| Component | Version | Notes |
|
|
62
|
+
|--------------------------|----------|-----------------------------------------------|
|
|
63
|
+
| Java baseline (`release`)| 8 | All sources under `src/main/java` target JDK 8|
|
|
64
|
+
| Java overlay (`release`) | 11 | Sources under `src/main/java11` target JDK 11 |
|
|
65
|
+
| Maven | 3.9.x | Build tool |
|
|
66
|
+
| OkHttp | 4.12.0 | The ONLY runtime third-party dependency |
|
|
67
|
+
| Okio | 3.9.x | Transitive of OkHttp — not declared directly |
|
|
68
|
+
| Kotlin stdlib (OkHttp) | 1.9.x | Transitive of OkHttp — not declared directly |
|
|
69
|
+
|
|
70
|
+
> **Note on OkHttp 4.x vs 5.x:** OkHttp 4.x runs on JDK 8 and is the safe default for an
|
|
71
|
+
> SDK that must support legacy consumers. Move to 5.x only if the user explicitly
|
|
72
|
+
> requires JDK 11 as the baseline AND no longer needs JDK 8 support.
|
|
73
|
+
|
|
74
|
+
### Test-Only Dependencies (always included, scope = `test`)
|
|
75
|
+
|
|
76
|
+
| Component | Version | Purpose |
|
|
77
|
+
|--------------------------|----------|------------------------------------------------|
|
|
78
|
+
| JUnit Jupiter | 5.10.x | Unit + integration tests |
|
|
79
|
+
| OkHttp MockWebServer | 4.12.0 | Stub the remote API in tests |
|
|
80
|
+
| AssertJ | 3.26.x | Fluent assertions |
|
|
81
|
+
|
|
82
|
+
These are scoped to `test` and never bundled into the fat JAR.
|
|
83
|
+
|
|
84
|
+
### Optional Runtime Dependencies (rare — only if PRD strictly requires)
|
|
85
|
+
|
|
86
|
+
The skill MUST default to **NO additional dependencies**. Add a row below ONLY when the
|
|
87
|
+
PRD explicitly requires the protocol/format and the JDK has no reasonable equivalent.
|
|
88
|
+
|
|
89
|
+
| Component | When Selected |
|
|
90
|
+
|--------------------------|------------------------------------------------------------|
|
|
91
|
+
| `org.java-websocket` | WebSocket support AND PRD bans JDK 11 `HttpClient` WS API |
|
|
92
|
+
| `com.rabbitmq:amqp-client` | AMQP/RabbitMQ protocol explicitly listed in Architecture Principle |
|
|
93
|
+
| `org.eclipse.paho:paho-mqtt-client` | MQTT protocol explicitly listed in Architecture Principle |
|
|
94
|
+
|
|
95
|
+
> **JSON is handled in-house.** Do NOT add Jackson, Gson, Moshi, or org.json. The spec
|
|
96
|
+
> describes a tiny hand-written JSON serializer/deserializer (or, if the OpenAPI spec is
|
|
97
|
+
> trivial, simple `Map<String, Object>` round-tripping) that operates on the SDK's own
|
|
98
|
+
> immutable model classes. This is intentional — JSON is one of the largest sources of
|
|
99
|
+
> SDK dependency bloat and downstream version conflicts.
|
|
100
|
+
|
|
101
|
+
## When the Skill Triggers
|
|
102
|
+
|
|
103
|
+
Generate the spec when the user provides an **application name** and **version** that
|
|
104
|
+
corresponds to one of the SDK libraries defined in `CLAUDE.md`. The skill reads all
|
|
105
|
+
required inputs from the project's context files — no interactive Q&A is needed for the
|
|
106
|
+
core inputs.
|
|
107
|
+
|
|
108
|
+
The user invokes this skill by specifying the target application and version, for example:
|
|
109
|
+
|
|
110
|
+
- `/specgen-sdk-java my_sdk v1.0.0`
|
|
111
|
+
- `/specgen-sdk-java my_sdk v1.0.0 module:Auth`
|
|
112
|
+
- `/specgen-sdk-java "My SDK" v1.0.0`
|
|
113
|
+
|
|
114
|
+
The skill then locates the matching context folder and reads all input files automatically.
|
|
115
|
+
|
|
116
|
+
## Version Gate
|
|
117
|
+
|
|
118
|
+
Before starting any work, resolve the application folder first (see Input Resolution below), then check `CHANGELOG.md` in the application folder (`<app_folder>/CHANGELOG.md`):
|
|
119
|
+
|
|
120
|
+
1. If `<app_folder>/CHANGELOG.md` does not exist, skip this check (first-ever execution for this application).
|
|
121
|
+
2. If `<app_folder>/CHANGELOG.md` exists, scan all `## vX.Y.Z` headings and determine the **highest version** using semantic versioning comparison.
|
|
122
|
+
3. Compare the requested version against the highest version:
|
|
123
|
+
- If requested version **>=** highest version: proceed normally.
|
|
124
|
+
- If requested version **<** highest version: **STOP immediately**. Print: `"Version {requested} is lower than the current application version {highest} recorded in <app_folder>/CHANGELOG.md. Execution rejected."` Do NOT proceed with any work.
|
|
125
|
+
|
|
126
|
+
## Input Resolution
|
|
127
|
+
|
|
128
|
+
This skill uses standardized input resolution. Provide:
|
|
129
|
+
|
|
130
|
+
| Argument | Required | Example | Description |
|
|
131
|
+
|-----------------|----------|-----------------|------------------------------------------------|
|
|
132
|
+
| `<application>` | Yes | `my_sdk` | Application name to locate the context folder |
|
|
133
|
+
| `<version>` | Yes | `v1.0.0` | Version to scope processing |
|
|
134
|
+
| `module:<name>` | No | `module:Auth` | Limit generation to a single module |
|
|
135
|
+
|
|
136
|
+
### Application Folder Resolution
|
|
137
|
+
|
|
138
|
+
The application name is matched against root-level application folders:
|
|
139
|
+
|
|
140
|
+
1. Strip any leading `<number>_` prefix from folder names (e.g., `1_my_sdk` → `my_sdk`)
|
|
141
|
+
2. Match case-insensitively against the provided application name
|
|
142
|
+
3. Accept snake_case, kebab-case, or title-case input (all match the same folder)
|
|
143
|
+
4. If no match found, list available applications and stop
|
|
144
|
+
|
|
145
|
+
### Auto-Resolved Paths
|
|
146
|
+
|
|
147
|
+
| File | Resolved Path |
|
|
148
|
+
|----------------|----------------------------------------|
|
|
149
|
+
| PRD.md | `<app_folder>/context/PRD.md` |
|
|
150
|
+
| Module Models | `<app_folder>/context/model/` |
|
|
151
|
+
| Output | `<app_folder>/context/specification/` |
|
|
152
|
+
|
|
153
|
+
### Version Filtering
|
|
154
|
+
|
|
155
|
+
When a version is provided, only include user stories, NFRs, constraints, tests, and
|
|
156
|
+
references from versions <= the provided version. For example, if `v0.3.0` is specified:
|
|
157
|
+
|
|
158
|
+
- Include items tagged `[v0.1.0]`, `[v0.2.0]`, `[v0.3.0]`
|
|
159
|
+
- Exclude items tagged `[v0.4.0]` or later
|
|
160
|
+
- Version comparison uses semantic versioning order
|
|
161
|
+
|
|
162
|
+
### Module Filtering
|
|
163
|
+
|
|
164
|
+
When `module:<name>` is provided:
|
|
165
|
+
|
|
166
|
+
- Only generate the `SPEC.md` for that specific module
|
|
167
|
+
- Other existing module spec files remain untouched
|
|
168
|
+
- `SPECIFICATION.md` (root) gets a partial update — only that module's TOC entry is
|
|
169
|
+
added or updated; all other entries are preserved as-is
|
|
170
|
+
|
|
171
|
+
## Gathering Input
|
|
172
|
+
|
|
173
|
+
The specification is driven by **six input sources** that are read from the project's
|
|
174
|
+
context files. The skill does NOT ask the user for protocol, packaging, or model
|
|
175
|
+
choices — it **determines** these automatically from the context.
|
|
176
|
+
|
|
177
|
+
### Input 1: Application Name (from CLAUDE.md)
|
|
178
|
+
|
|
179
|
+
From CLAUDE.md (already loaded in context), locate the target SDK under the
|
|
180
|
+
**Custom Applications** section. Extract:
|
|
181
|
+
|
|
182
|
+
- **Application name**: The section heading (e.g., "My SDK", "Hub Client SDK")
|
|
183
|
+
- **Application description**: The description paragraph below the heading
|
|
184
|
+
- **Target consumers**: The "Used by" or "Consumers" list — informs API surface design
|
|
185
|
+
- **Dependencies**: The "Depends on" list — primary source for identifying the remote
|
|
186
|
+
API (its base URL, auth scheme, etc.)
|
|
187
|
+
|
|
188
|
+
The application name is used to derive:
|
|
189
|
+
|
|
190
|
+
- **Artifact ID**: kebab-case of the application name (e.g., `my-sdk`)
|
|
191
|
+
- **Group ID**: `com.bestinet.urp` (project-level constant unless CLAUDE.md overrides)
|
|
192
|
+
- **Base package**: `com.bestinet.urp.<artifactid_no_hyphens>` (e.g., `com.bestinet.urp.mysdk`)
|
|
193
|
+
- **Main facade class name**: PascalCase of the application name with `Client` suffix
|
|
194
|
+
(e.g., `MySdkClient`, `HubClient`)
|
|
195
|
+
|
|
196
|
+
### Input 2: User Stories (from PRD.md — "Library User Stories")
|
|
197
|
+
|
|
198
|
+
Read `<app_folder>/context/PRD.md`. For an SDK library, user stories describe what
|
|
199
|
+
**downstream Java applications** want to do with the SDK — NOT what an end user wants to
|
|
200
|
+
do with a UI. Phrasing examples:
|
|
201
|
+
|
|
202
|
+
- "As a consumer application, I want to fetch a paginated list of orders by status."
|
|
203
|
+
- "As a consumer application, I want to upload a file with progress callback."
|
|
204
|
+
|
|
205
|
+
Each story is tagged like `[USSDK00101]` and grouped by module. Extract:
|
|
206
|
+
|
|
207
|
+
- **Modules**: Each `## <ModuleName>` or `### <ModuleName>` section
|
|
208
|
+
- **User stories per module**: Tagged items defining the SDK's public methods
|
|
209
|
+
|
|
210
|
+
Items with strikethrough (`~~text~~`) are deprecated. List them in the "Removed /
|
|
211
|
+
Replaced" subsection of the traceability table. Carry version tags through to the
|
|
212
|
+
generated specification.
|
|
213
|
+
|
|
214
|
+
The user stories directly inform:
|
|
215
|
+
|
|
216
|
+
- The methods on each module's facade class (e.g., `OrdersService.list(...)`)
|
|
217
|
+
- Which request/response model classes are needed
|
|
218
|
+
- Which HTTP endpoints the SDK calls (mapping derived together with Input 6)
|
|
219
|
+
|
|
220
|
+
### Input 3: Non-Functional Requirements (from PRD.md)
|
|
221
|
+
|
|
222
|
+
Within the same `PRD.md`, each module has a `### Non Functional Requirement` section
|
|
223
|
+
with tagged items like `[NFRSDK0120]`. NFRs typical for an SDK:
|
|
224
|
+
|
|
225
|
+
- "All HTTP calls timeout after 30 seconds by default, configurable per call."
|
|
226
|
+
- "Connection pool reuses up to 10 keep-alive connections."
|
|
227
|
+
- "All retryable errors retry with exponential backoff up to 3 attempts."
|
|
228
|
+
- "Logging is opt-in via SLF4J — the SDK ships no SLF4J binding."
|
|
229
|
+
|
|
230
|
+
These NFRs map directly to the `OkHttpClient` builder configuration, the retry
|
|
231
|
+
interceptor design, and the logging strategy in the generated spec.
|
|
232
|
+
|
|
233
|
+
### Input 4: Constraints (from PRD.md)
|
|
234
|
+
|
|
235
|
+
Tagged items like `[CONSSDK042]`. For an SDK these usually constrain the public API
|
|
236
|
+
surface and dependency footprint, e.g.:
|
|
237
|
+
|
|
238
|
+
- "Public API must remain backwards compatible within a major version."
|
|
239
|
+
- "SDK must run on JDK 8 without modification."
|
|
240
|
+
- "SDK must add no more than 5 transitive dependencies."
|
|
241
|
+
|
|
242
|
+
Constraints are embedded directly into the relevant module blueprint and surface as
|
|
243
|
+
explicit rules in the spec's "Constraints" section.
|
|
244
|
+
|
|
245
|
+
### Input 5: Test Instructions and References (from PRD.md)
|
|
246
|
+
|
|
247
|
+
Each module's `### Test` and `### References` sections feed:
|
|
248
|
+
|
|
249
|
+
- **Test**: The test plan section of the module SPEC.md — what scenarios MockWebServer
|
|
250
|
+
must cover, what fixtures are needed.
|
|
251
|
+
- **References**: The "External Documentation" subsection of the module SPEC.md — links
|
|
252
|
+
back to the upstream API docs, RFCs, vendor SDK comparisons, etc. Carry version tags
|
|
253
|
+
through.
|
|
254
|
+
|
|
255
|
+
### Input 6: Module Model (from model/ folder, if present)
|
|
256
|
+
|
|
257
|
+
Read `<app_folder>/context/model/MODEL.md` first as the index, then read individual
|
|
258
|
+
module files in each module subfolder.
|
|
259
|
+
|
|
260
|
+
For an SDK, "models" are the request/response Java classes that mirror the remote API's
|
|
261
|
+
schema — NOT database entities. Per-module model files (e.g.,
|
|
262
|
+
`model/auth/model.md`) define:
|
|
263
|
+
|
|
264
|
+
- The fields, types, and JSON property names for each model class
|
|
265
|
+
- Whether a model is a request DTO, response DTO, or both
|
|
266
|
+
- Validation rules to enforce client-side before sending the HTTP call
|
|
267
|
+
- Enum values and how they map to JSON strings
|
|
268
|
+
|
|
269
|
+
The model directly maps to:
|
|
270
|
+
|
|
271
|
+
- Immutable Java model classes (records on JDK 16+; final classes with `Builder` on JDK 8)
|
|
272
|
+
- The hand-written JSON serializer field tables
|
|
273
|
+
- Argument types of public facade methods
|
|
274
|
+
|
|
275
|
+
If MODEL.md is absent, derive models entirely from the OpenAPI spec (Input 7) and the
|
|
276
|
+
user stories.
|
|
277
|
+
|
|
278
|
+
## PRD.md Extended Sections
|
|
279
|
+
|
|
280
|
+
Before determining optional components, check PRD.md for the following extended sections.
|
|
281
|
+
**These are critical for SDK generation** — they define the protocols the SDK must
|
|
282
|
+
support and the design patterns it must follow.
|
|
283
|
+
|
|
284
|
+
### Input 7: API Surface Source — Swagger UI URL or OpenAPI Spec (CRITICAL)
|
|
285
|
+
|
|
286
|
+
**This is the highest-priority input for the SDK spec.** Before any other determination,
|
|
287
|
+
scan the entire `PRD.md` for one of:
|
|
288
|
+
|
|
289
|
+
| Pattern | Action |
|
|
290
|
+
|------------------------------------------------------------------|-------------------------------------------------|
|
|
291
|
+
| A URL ending in `/swagger-ui.html`, `/swagger-ui/index.html`, `/swagger`, or `/api-docs` | Record as `swaggerUiUrl` |
|
|
292
|
+
| A URL ending in `/v3/api-docs`, `/openapi.json`, `/openapi.yaml`, or `/swagger.json` | Record as `openApiSpecUrl` |
|
|
293
|
+
| A relative path to an `openapi.yaml` / `openapi.json` / `swagger.yaml` / `swagger.json` file inside the application folder | Record as `openApiSpecPath` |
|
|
294
|
+
| A heading "## Swagger UI", "## OpenAPI Spec", "## API Reference" with a URL/path beneath it | Same as above based on the URL form |
|
|
295
|
+
|
|
296
|
+
Scanning order: Architecture Principle section first → "API Reference" / "External APIs"
|
|
297
|
+
sections next → fall back to a project-wide grep for `swagger` / `openapi` / `api-docs`.
|
|
298
|
+
|
|
299
|
+
**Resolution behaviour:**
|
|
300
|
+
|
|
301
|
+
1. **`openApiSpecUrl` or `openApiSpecPath` found:** This is the authoritative API
|
|
302
|
+
surface. The spec MUST instruct the implementer to read this OpenAPI document and
|
|
303
|
+
generate one model class per schema, one facade method per operation, and one URL
|
|
304
|
+
constant per path. The skill should attempt to fetch the spec at generation time (if
|
|
305
|
+
the URL is reachable) so that the generated SPEC.md can list real operation IDs,
|
|
306
|
+
paths, and schema names — NOT placeholders.
|
|
307
|
+
2. **Only `swaggerUiUrl` found:** Treat the underlying `/v3/api-docs` (or `/api-docs`)
|
|
308
|
+
as the spec endpoint. Note in the spec that the implementer must derive the spec URL
|
|
309
|
+
by inspecting the Swagger UI page.
|
|
310
|
+
3. **Neither found, but PRD lists explicit endpoint tables:** Use those tables as the
|
|
311
|
+
authoritative API surface; mark a `[TODO]` reminding the team to publish an OpenAPI
|
|
312
|
+
document.
|
|
313
|
+
4. **Nothing found:** Insert a `[TODO]` at the top of the generated SPECIFICATION.md
|
|
314
|
+
reading: `[TODO] No Swagger UI URL or OpenAPI spec found in PRD.md — the SDK API
|
|
315
|
+
surface is inferred from user stories only and may drift from the real API.` Then
|
|
316
|
+
proceed using user stories alone.
|
|
317
|
+
|
|
318
|
+
The chosen API surface source MUST be summarized in the **Project Overview** section of
|
|
319
|
+
SPECIFICATION.md so future readers know which document drove the SDK shape.
|
|
320
|
+
|
|
321
|
+
See `references/api-extraction-patterns.md` for the full procedure.
|
|
322
|
+
|
|
323
|
+
### Architecture Principle Extraction
|
|
324
|
+
|
|
325
|
+
If PRD.md contains an `# Architecture Principle` section, extract patterns that affect
|
|
326
|
+
SDK design. Treat this section as **authoritative for protocol selection and design
|
|
327
|
+
patterns**:
|
|
328
|
+
|
|
329
|
+
| Pattern in Architecture Principle | How It Influences the SDK Spec |
|
|
330
|
+
|------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|
|
|
331
|
+
| "REST" / "RESTful API" | Confirm OkHttp transport (default) |
|
|
332
|
+
| "WebSocket" / "real-time" | Add WebSocket subsection. Use OkHttp's built-in WebSocket on JDK 8; document JDK 11 `HttpClient` WebSocket option |
|
|
333
|
+
| "Server-Sent Events" / "SSE" | Add SSE subsection backed by OkHttp `EventSource` |
|
|
334
|
+
| "gRPC" | Add a `[TODO]` — OkHttp does not support gRPC natively. Confirm with user before adding `grpc-java` |
|
|
335
|
+
| "AMQP" / "RabbitMQ" / "message queue" | Add AMQP subsection backed by `com.rabbitmq:amqp-client` only if user confirms |
|
|
336
|
+
| "MQTT" | Add MQTT subsection backed by `paho-mqtt-client` only if user confirms |
|
|
337
|
+
| "Stateless" | Confirm no client-side session state; every call carries credentials in headers |
|
|
338
|
+
| "OAuth2 / Bearer token" | Add `AuthInterceptor` to inject `Authorization: Bearer ...` and refresh on 401 |
|
|
339
|
+
| "API key authentication" | Add `AuthInterceptor` to inject the configured API key header |
|
|
340
|
+
| "mTLS" | Add `OkHttpClient` SSL configuration section with custom `X509TrustManager` and `KeyManager` |
|
|
341
|
+
| "Idempotency-Key" header | Add idempotency key generation utility used by all mutating calls |
|
|
342
|
+
| "Builder pattern" | Confirm builder pattern on the client and every request DTO |
|
|
343
|
+
| "Fluent API" / "fluent interface" | Confirm method chaining on the facade (e.g., `client.orders().forCustomer(id).list()`) |
|
|
344
|
+
| "Strategy pattern" / "pluggable" | Add a strategy interface (e.g., `RetryStrategy`, `BackoffStrategy`, `CredentialProvider`) that consumers override |
|
|
345
|
+
| "Adapter pattern" | Confirm the SDK adapts the remote HTTP API to a typed Java API — already the default; document it explicitly |
|
|
346
|
+
| "Decorator pattern" | Add a decorator section showing how consumers wrap the facade (e.g., for caching, metrics) |
|
|
347
|
+
| "Observer pattern" / "event listener" | Add a listener interface (e.g., `RequestLifecycleListener`) consumers can register |
|
|
348
|
+
| "Reactive" / "non-blocking" | Add an async API surface using `CompletableFuture` (JDK 8+, no extra dep) |
|
|
349
|
+
| "Thread-safe" / "concurrent" | Confirm immutable models, single shared `OkHttpClient`, document thread-safety in javadoc |
|
|
350
|
+
|
|
351
|
+
Every pattern from Architecture Principle that applies MUST be reflected in:
|
|
352
|
+
|
|
353
|
+
1. The SPECIFICATION.md "Architecture Patterns" section, as a numbered list with the
|
|
354
|
+
class/interface name and a one-paragraph rationale.
|
|
355
|
+
2. The relevant module SPEC.md (e.g., the auth interceptor lives in the auth module).
|
|
356
|
+
|
|
357
|
+
If the section is absent, default to: REST + Builder pattern + Strategy pattern (for
|
|
358
|
+
retry) + Adapter pattern (the SDK itself).
|
|
359
|
+
|
|
360
|
+
### High Level Process Flow Extraction
|
|
361
|
+
|
|
362
|
+
If PRD.md contains a `# High Level Process Flow` section:
|
|
363
|
+
|
|
364
|
+
1. Each named flow informs the orchestration helpers the SDK exposes (e.g., a
|
|
365
|
+
"submit and poll until complete" helper combines `POST /jobs` + `GET /jobs/{id}` +
|
|
366
|
+
polling).
|
|
367
|
+
2. Multi-step flows become a `*Flow` class on the facade (e.g., `OrderSubmissionFlow`)
|
|
368
|
+
that returns a `CompletableFuture` and internally calls the relevant module services.
|
|
369
|
+
3. Error paths in the flow become specific exception types in the SDK's exception hierarchy.
|
|
370
|
+
|
|
371
|
+
If absent, derive the API surface from user stories + OpenAPI alone (no flow helpers).
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
## Determining Optional Components
|
|
376
|
+
|
|
377
|
+
After reading all inputs above, produce a determination summary BEFORE generating the
|
|
378
|
+
spec. The defaults are aggressively minimal — the skill must justify every "yes".
|
|
379
|
+
|
|
380
|
+
### Protocol Selection
|
|
381
|
+
|
|
382
|
+
| Signal | Selection |
|
|
383
|
+
|--------------------------------------------------------------|--------------------------|
|
|
384
|
+
| Default | REST (OkHttp) |
|
|
385
|
+
| Architecture Principle mentions WebSocket / SSE / AMQP / MQTT/ gRPC | Add the named protocol |
|
|
386
|
+
|
|
387
|
+
### Authentication Selection
|
|
388
|
+
|
|
389
|
+
| Signal | Auth Selection |
|
|
390
|
+
|--------------------------------------------------------------|--------------------------|
|
|
391
|
+
| OpenAPI `securitySchemes` includes `bearer` / `oauth2` | Bearer token |
|
|
392
|
+
| OpenAPI `securitySchemes` includes `apiKey` | API key (header or query)|
|
|
393
|
+
| Architecture Principle mentions mTLS | mTLS (additional, not exclusive) |
|
|
394
|
+
| OpenAPI `securitySchemes` includes `basic` | HTTP Basic |
|
|
395
|
+
| None of the above | None (caller injects own headers) |
|
|
396
|
+
|
|
397
|
+
### Async API Surface
|
|
398
|
+
|
|
399
|
+
| Signal | Async Selection |
|
|
400
|
+
|--------------------------------------------------------------|--------------------------|
|
|
401
|
+
| Architecture Principle mentions "reactive", "non-blocking", "async-first" | Yes — every method has both sync and `CompletableFuture` overloads |
|
|
402
|
+
| User stories mention long-running operations (`upload`, `export`, `report`) | Yes — long ops only |
|
|
403
|
+
| Default | No — synchronous only |
|
|
404
|
+
|
|
405
|
+
### Logging Strategy
|
|
406
|
+
|
|
407
|
+
The default is **SLF4J facade only, no binding**. Consumers add their own SLF4J binding.
|
|
408
|
+
Override only if the PRD explicitly forbids SLF4J — in which case fall back to JUL
|
|
409
|
+
(`java.util.logging`) which is in the JDK and adds zero dependencies.
|
|
410
|
+
|
|
411
|
+
### Model Style
|
|
412
|
+
|
|
413
|
+
| JDK Baseline | Model Style |
|
|
414
|
+
|----------------|--------------------------------------------------------------------|
|
|
415
|
+
| 8 (default) | Final classes with explicit Builder, immutable fields, `equals`/`hashCode`/`toString` |
|
|
416
|
+
| 16+ (override) | Records (with builder for fields > 6) |
|
|
417
|
+
|
|
418
|
+
The MR-JAR layout permits records via overlays, but for an SDK the public API must be
|
|
419
|
+
identical across JDK versions, so models stay as final classes regardless of overlay.
|
|
420
|
+
|
|
421
|
+
### Summary of Determination
|
|
422
|
+
|
|
423
|
+
Print before generating the spec:
|
|
424
|
+
|
|
425
|
+
```
|
|
426
|
+
Optional Component Determination:
|
|
427
|
+
- API Surface Source: {{swagger url|openapi url|openapi path|user stories only}}
|
|
428
|
+
- Protocols: REST{{ + WebSocket/SSE/AMQP/MQTT if any}}
|
|
429
|
+
- Authentication: {{Bearer | API Key | mTLS | Basic | None}}
|
|
430
|
+
- Async API: {{yes (all) | yes (long ops) | no}}
|
|
431
|
+
- Logging: {{SLF4J facade | JUL}}
|
|
432
|
+
- Model Style: Final classes with Builder (JDK 8 baseline)
|
|
433
|
+
- Multi-Release JAR: yes (JDK 8 base + JDK 11 overlay)
|
|
434
|
+
- Fat JAR: yes (Maven Shade Plugin)
|
|
435
|
+
- Optional protocol deps:
|
|
436
|
+
- org.java-websocket: {{yes/no}}
|
|
437
|
+
- amqp-client: {{yes/no}}
|
|
438
|
+
- paho-mqtt-client: {{yes/no}}
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
If the user disagrees with any determination, allow them to override before proceeding.
|
|
442
|
+
|
|
443
|
+
## Required Inputs
|
|
444
|
+
|
|
445
|
+
After determination, these values are needed. Most are derived automatically:
|
|
446
|
+
|
|
447
|
+
**Auto-derived from context files:**
|
|
448
|
+
|
|
449
|
+
- **Application name**: From CLAUDE.md
|
|
450
|
+
- **Artifact ID**: kebab-case of application name
|
|
451
|
+
- **Group ID**: `com.bestinet.urp`
|
|
452
|
+
- **Base package**: `com.bestinet.urp.<artifactid_no_hyphens>`
|
|
453
|
+
- **Application description**: From CLAUDE.md
|
|
454
|
+
- **Modules**: From PRD.md module headings + `model/MODEL.md`
|
|
455
|
+
- **API surface source**: Swagger UI URL or OpenAPI spec (Input 7) — MANDATORY summary
|
|
456
|
+
- **Default base URL**: From the OpenAPI `servers[0].url`, or from the `# Reference`
|
|
457
|
+
section of CLAUDE.md, or `https://api.example.com` placeholder if neither is present
|
|
458
|
+
(with a `[TODO]`)
|
|
459
|
+
- **Auth scheme**: Auto-determined (see above)
|
|
460
|
+
- **Optional protocols**: Auto-determined (see above)
|
|
461
|
+
|
|
462
|
+
**From ENVIRONMENT.md (if present, for the demo/diagnostics `main()`):**
|
|
463
|
+
|
|
464
|
+
- API host, port, default credential — used as default values for the diagnostic
|
|
465
|
+
smoke-test only. Never bundle into the JAR; load from environment at runtime.
|
|
466
|
+
|
|
467
|
+
## Generating the Specification
|
|
468
|
+
|
|
469
|
+
Once inputs are gathered and optional components are determined, generate the
|
|
470
|
+
specification as a **multi-file output split by module**. Read the spec template at
|
|
471
|
+
`references/spec-template.md` for the exact structure and content of each section. The
|
|
472
|
+
template is the authoritative guide — follow it closely.
|
|
473
|
+
|
|
474
|
+
The specification is split into two categories:
|
|
475
|
+
|
|
476
|
+
1. **Root `SPECIFICATION.md`** — Shared infrastructure: Maven config (with
|
|
477
|
+
Multi-Release + Shade plugins), source layout, `OkHttpClient` setup, transport
|
|
478
|
+
utilities, JSON support, error model, retry strategy, the top-level `Client` facade,
|
|
479
|
+
and packaging.
|
|
480
|
+
2. **Per-module `<module-name>/SPEC.md`** — Each module gets its own folder with a
|
|
481
|
+
self-contained specification covering its model classes, service facade,
|
|
482
|
+
request/response payloads, OpenAPI operation mapping, error mapping, and tests.
|
|
483
|
+
|
|
484
|
+
**Important:** The generated spec must use **real application data** from the context
|
|
485
|
+
files:
|
|
486
|
+
|
|
487
|
+
- **Modules** must use the actual module names from PRD.md / MODEL.md
|
|
488
|
+
- **Operation IDs and paths** must come from the OpenAPI spec when available
|
|
489
|
+
- **Model fields** must match the OpenAPI schemas (or MODEL.md) — never placeholders
|
|
490
|
+
- **Public methods** must map to real user stories
|
|
491
|
+
- **Version tags** on every user story ID, NFR ID, constraint ID
|
|
492
|
+
- **Removed / Replaced items** listed for deprecated items
|
|
493
|
+
|
|
494
|
+
### Output Structure
|
|
495
|
+
|
|
496
|
+
```
|
|
497
|
+
<app_folder>/context/specification/
|
|
498
|
+
├── SPECIFICATION.md ↠Shared infrastructure + TOC
|
|
499
|
+
├── auth/
|
|
500
|
+
│ └── SPEC.md ↠Module blueprint for 'auth'
|
|
501
|
+
├── orders/
|
|
502
|
+
│ └── SPEC.md ↠Module blueprint for 'orders'
|
|
503
|
+
└── ... ↠One folder per module from PRD.md
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
### What Goes in `SPECIFICATION.md` (Root)
|
|
507
|
+
|
|
508
|
+
#### 1. Project Overview
|
|
509
|
+
|
|
510
|
+
Application metadata, description, target consumers, **API Surface Source** (the
|
|
511
|
+
recorded Swagger UI URL or OpenAPI path), default base URL, supported JDK range
|
|
512
|
+
(8 baseline + 11 overlay), distribution strategy (Maven Central / internal Nexus /
|
|
513
|
+
GitHub release attachment), and the complete module list.
|
|
514
|
+
|
|
515
|
+
#### 2. Maven Configuration (`pom.xml`)
|
|
516
|
+
|
|
517
|
+
Complete `pom.xml` with:
|
|
518
|
+
|
|
519
|
+
- `<packaging>jar</packaging>`
|
|
520
|
+
- `<groupId>`, `<artifactId>`, `<version>` from inputs
|
|
521
|
+
- A single `okhttp` runtime dependency, plus the test-scoped dependencies
|
|
522
|
+
- `maven-compiler-plugin` configured TWICE via `<executions>`:
|
|
523
|
+
- **Default execution**: compiles `src/main/java` with `<release>8</release>`
|
|
524
|
+
- **Overlay execution**: compiles `src/main/java11` with `<release>11</release>`,
|
|
525
|
+
output redirected to `target/classes-java11`
|
|
526
|
+
- `maven-jar-plugin` configured with `<Multi-Release>true</Multi-Release>` in the manifest
|
|
527
|
+
and an `<archive>` block that copies the JDK 11 overlay into
|
|
528
|
+
`META-INF/versions/11/` of the resulting JAR
|
|
529
|
+
- `maven-shade-plugin` configured to build a fat JAR (`<shadedArtifactAttached>false</shadedArtifactAttached>`),
|
|
530
|
+
relocate any internal Kotlin/Okio packages under `<base-package>.shaded.*` to avoid
|
|
531
|
+
classpath collisions, exclude test-scoped artifacts, and **preserve the
|
|
532
|
+
Multi-Release manifest entry** so MR-JAR semantics survive shading
|
|
533
|
+
- `maven-source-plugin` and `maven-javadoc-plugin` for source/javadoc JARs
|
|
534
|
+
- `maven-surefire-plugin` running JUnit 5
|
|
535
|
+
- `<properties>` for versions
|
|
536
|
+
|
|
537
|
+
The complete sample `pom.xml` MUST appear in this section. No fragments.
|
|
538
|
+
See `references/packaging-patterns.md` for the canonical configuration.
|
|
539
|
+
|
|
540
|
+
#### 3. Source Layout
|
|
541
|
+
|
|
542
|
+
```
|
|
543
|
+
src/
|
|
544
|
+
├── main/
|
|
545
|
+
│ ├── java/ ↠JDK 8 baseline — ALL public API lives here
|
|
546
|
+
│ │ └── com/bestinet/urp/{{artifactid}}/
|
|
547
|
+
│ │ ├── {{ClientName}}.java ↠Top-level facade + Builder
|
|
548
|
+
│ │ ├── {{ClientName}}Config.java ↠Immutable config (timeouts, baseUrl, auth)
|
|
549
|
+
│ │ ├── auth/ ↠Auth interceptor + credential provider
|
|
550
|
+
│ │ ├── http/ ↠OkHttp wiring, interceptors, retry
|
|
551
|
+
│ │ ├── json/ ↠Hand-written minimal JSON utility
|
|
552
|
+
│ │ ├── error/ ↠Exception hierarchy
|
|
553
|
+
│ │ ├── util/ ↠Internal helpers (no public API)
|
|
554
|
+
│ │ └── {{module1}}/ ↠One package per module
|
|
555
|
+
│ │ ├── {{Module1}}Service.java ↠Module facade (public)
|
|
556
|
+
│ │ ├── model/ ↠Request/response models (public)
|
|
557
|
+
│ │ └── internal/ ↠Internals (package-private)
|
|
558
|
+
│ ├── java11/ ↠JDK 11 overlay — same package paths only
|
|
559
|
+
│ │ └── com/bestinet/urp/{{artifactid}}/
|
|
560
|
+
│ │ └── util/
|
|
561
|
+
│ │ └── HttpUtil.java ↠e.g., uses java.net.http.HttpClient
|
|
562
|
+
│ └── resources/
|
|
563
|
+
│ └── META-INF/
|
|
564
|
+
│ └── services/ ↠(only if SPI is exposed)
|
|
565
|
+
└── test/
|
|
566
|
+
└── java/
|
|
567
|
+
└── com/bestinet/urp/{{artifactid}}/
|
|
568
|
+
└── ... ↠MockWebServer-based tests
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
**Multi-Release JAR rules:**
|
|
572
|
+
|
|
573
|
+
- Every class under `src/main/java11` MUST also exist under `src/main/java` with an
|
|
574
|
+
identical public signature (the JDK 8 fallback). The JVM picks the JDK 11 version
|
|
575
|
+
automatically when running on JDK 11+.
|
|
576
|
+
- Overlay classes are reserved for performance/feature wins on newer JDKs (e.g.,
|
|
577
|
+
`java.net.http.HttpClient`-based fast-path, `String.formatted`, `List.of`). They are
|
|
578
|
+
NOT used to introduce new public API.
|
|
579
|
+
- The fat JAR built by Shade preserves `Multi-Release: true` in `META-INF/MANIFEST.MF`
|
|
580
|
+
and copies overlay classes into `META-INF/versions/11/`.
|
|
581
|
+
|
|
582
|
+
#### 4. OkHttpClient Setup
|
|
583
|
+
|
|
584
|
+
`http/HttpClientFactory.java` — builds a single shared `OkHttpClient` with:
|
|
585
|
+
|
|
586
|
+
- Connection pool: max idle = 10, keep-alive = 5 min (configurable via `Config`)
|
|
587
|
+
- Connect / read / write timeout (default 30 s, configurable)
|
|
588
|
+
- `AuthInterceptor` (only if Auth != none)
|
|
589
|
+
- `RetryInterceptor` (always, with `RetryStrategy` strategy)
|
|
590
|
+
- `CorrelationIdInterceptor` (adds `X-Correlation-Id` if not already set)
|
|
591
|
+
- `LoggingInterceptor` (only if SLF4J is on the classpath; otherwise no-op)
|
|
592
|
+
|
|
593
|
+
The factory is package-private; the `Client.Builder` is the only entry point.
|
|
594
|
+
Document thread-safety: a single `OkHttpClient` is safe to share across threads and
|
|
595
|
+
must be reused by consumers — never create one per request.
|
|
596
|
+
|
|
597
|
+
See `references/http-client-patterns.md` for the full configuration.
|
|
598
|
+
|
|
599
|
+
#### 5. JSON Support (Hand-written)
|
|
600
|
+
|
|
601
|
+
`json/Json.java` — a minimal, hand-written JSON parser/writer that handles only what
|
|
602
|
+
the SDK's models need: objects, arrays, strings, numbers, booleans, null. No reflection,
|
|
603
|
+
no annotations. Each model class implements `toJson(JsonWriter)` and provides a static
|
|
604
|
+
`fromJson(JsonReader)`.
|
|
605
|
+
|
|
606
|
+
This is intentional. JSON is the largest source of dependency conflicts in Java SDKs,
|
|
607
|
+
and hand-coded read/write methods make every wire-format change a deliberate, reviewable
|
|
608
|
+
edit. If the OpenAPI spec is large enough that hand-writing becomes onerous, document a
|
|
609
|
+
codegen step (e.g., a small `JsonModelGenerator` invoked at build time from the OpenAPI
|
|
610
|
+
spec) — but still emit hand-written-style code, not Jackson annotations.
|
|
611
|
+
|
|
612
|
+
See `references/spec-template.md` for the exact `Json` class shape and per-model
|
|
613
|
+
serializer pattern.
|
|
614
|
+
|
|
615
|
+
#### 6. Error Model
|
|
616
|
+
|
|
617
|
+
`error/SdkException.java` (base, unchecked) with subclasses:
|
|
618
|
+
|
|
619
|
+
- `SdkApiException` — non-2xx HTTP response. Carries `int statusCode`, `String body`,
|
|
620
|
+
optional parsed error model, and the original `Request` URL/method.
|
|
621
|
+
- `SdkAuthException extends SdkApiException` — 401/403.
|
|
622
|
+
- `SdkClientException extends SdkException` — local I/O, JSON, or validation failure.
|
|
623
|
+
- `SdkTimeoutException extends SdkClientException` — wraps OkHttp timeout exceptions.
|
|
624
|
+
- `SdkRetryExhaustedException extends SdkClientException` — retry budget consumed.
|
|
625
|
+
|
|
626
|
+
All exceptions are `RuntimeException` subclasses — checked exceptions in a public Java
|
|
627
|
+
SDK API are widely considered an anti-pattern.
|
|
628
|
+
|
|
629
|
+
#### 7. Retry Strategy
|
|
630
|
+
|
|
631
|
+
`http/RetryInterceptor.java` invokes `RetryStrategy` (interface) — default
|
|
632
|
+
implementation `ExponentialBackoffRetryStrategy` retries on connection failure, 502, 503,
|
|
633
|
+
504 with `min(maxBackoff, base * 2^attempt + jitter)` delays. The strategy is pluggable
|
|
634
|
+
via `Client.Builder#retryStrategy(...)` so consumers can supply their own.
|
|
635
|
+
|
|
636
|
+
#### 8. Authentication *(conditional)*
|
|
637
|
+
|
|
638
|
+
If Auth = Bearer token: `auth/BearerCredentialProvider.java` interface +
|
|
639
|
+
`StaticBearerCredentialProvider` default. `AuthInterceptor` reads from the provider on
|
|
640
|
+
every request; on 401, it calls `provider.refresh()` and replays once.
|
|
641
|
+
|
|
642
|
+
If Auth = API key: similar but with the configured header name (e.g., `X-API-Key`).
|
|
643
|
+
|
|
644
|
+
If Auth = mTLS: document `OkHttpClient.Builder#sslSocketFactory` configuration with a
|
|
645
|
+
custom `X509TrustManager` + `KeyManager`. Provide a helper that loads a PKCS12 keystore
|
|
646
|
+
from a path provided by the consumer.
|
|
647
|
+
|
|
648
|
+
If Auth = Basic: simple `Credentials.basic(user, pass)` injection.
|
|
649
|
+
|
|
650
|
+
#### 9. Top-Level Client Facade
|
|
651
|
+
|
|
652
|
+
`{{ClientName}}.java` — the main entry point consumers use:
|
|
653
|
+
|
|
654
|
+
```java
|
|
655
|
+
{{ClientName}} client = {{ClientName}}.builder()
|
|
656
|
+
.baseUrl("https://api.example.com")
|
|
657
|
+
.credentials(BearerCredentialProvider.of("..."))
|
|
658
|
+
.connectTimeout(Duration.ofSeconds(30))
|
|
659
|
+
.build();
|
|
660
|
+
|
|
661
|
+
OrderDto order = client.orders().getById("ORD-123");
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
The facade is immutable and thread-safe. Each module is exposed as a method
|
|
665
|
+
(`client.orders()`, `client.auth()`, `client.users()`) that returns a cached service
|
|
666
|
+
instance. The Builder validates required fields (`baseUrl`) before producing the client.
|
|
667
|
+
|
|
668
|
+
#### 10. Diagnostic Main *(optional, very small)*
|
|
669
|
+
|
|
670
|
+
If the user explicitly asks, include a `cli/Diagnose.java` with a `public static void
|
|
671
|
+
main(String[] args)` that performs a single smoke-test call against the configured base
|
|
672
|
+
URL and prints the result. This adds no dependencies (only the SDK itself) and is
|
|
673
|
+
useful for `java -jar my-sdk-1.0.0.jar`. The fat-JAR manifest's `Main-Class` points to
|
|
674
|
+
this class. Otherwise, omit `Main-Class` so the JAR is library-only.
|
|
675
|
+
|
|
676
|
+
#### 11. Logging Strategy
|
|
677
|
+
|
|
678
|
+
If Logging = SLF4J facade: declare `org.slf4j:slf4j-api` as `<scope>provided</scope>` in
|
|
679
|
+
Maven so it is NOT bundled into the fat JAR. The SDK uses `LoggerFactory.getLogger(...)`
|
|
680
|
+
internally. If no SLF4J binding is on the consumer's classpath, the no-op binding ships
|
|
681
|
+
silently — this is the standard SLF4J behaviour.
|
|
682
|
+
|
|
683
|
+
If Logging = JUL: zero dependencies; the SDK uses `java.util.logging.Logger` directly.
|
|
684
|
+
|
|
685
|
+
#### 12. Testing Strategy
|
|
686
|
+
|
|
687
|
+
JUnit 5 + AssertJ + OkHttp `MockWebServer`. Each module has a `*ServiceTest.java` that
|
|
688
|
+
spins up a `MockWebServer`, configures the SDK to point at it, enqueues canned
|
|
689
|
+
responses, and asserts the SDK behavior. Document one full sample in this section.
|
|
690
|
+
|
|
691
|
+
See `references/spec-template.md` for the canonical test pattern.
|
|
692
|
+
|
|
693
|
+
#### 13. Packaging & Distribution
|
|
694
|
+
|
|
695
|
+
Two artifacts are produced:
|
|
696
|
+
|
|
697
|
+
1. **Thin JAR** (`target/{{artifactId}}-{{version}}.jar`) — for Maven consumers. Has
|
|
698
|
+
declared dependencies in `pom.xml`.
|
|
699
|
+
2. **Fat JAR** (`target/{{artifactId}}-{{version}}-shaded.jar` — but Shade is
|
|
700
|
+
configured with `<finalName>` to overwrite the thin JAR's name when desired) — for
|
|
701
|
+
classpath drop-in. Contains all runtime dependencies relocated under
|
|
702
|
+
`com.bestinet.urp.{{artifactid}}.shaded.*` to avoid collisions.
|
|
703
|
+
|
|
704
|
+
Both artifacts are Multi-Release JARs (MR-JAR layout preserved through Shade).
|
|
705
|
+
|
|
706
|
+
`mvn package` produces both. The Shade plugin's `Multi-Release: true` manifest entry
|
|
707
|
+
is the easiest thing to lose during shading — the spec MUST include the explicit
|
|
708
|
+
`ManifestResourceTransformer` and `<resource>true</resource>` configuration that
|
|
709
|
+
preserves it.
|
|
710
|
+
|
|
711
|
+
Distribution targets:
|
|
712
|
+
|
|
713
|
+
- Maven Central: signed (gpg) deploy via `nexus-staging-maven-plugin`.
|
|
714
|
+
- Internal Nexus: standard `mvn deploy` to the configured repository.
|
|
715
|
+
- GitHub Releases: attach the fat JAR to the release.
|
|
716
|
+
|
|
717
|
+
See `references/packaging-patterns.md` for the full Maven snippets.
|
|
718
|
+
|
|
719
|
+
#### 14. Public API Surface & Compatibility
|
|
720
|
+
|
|
721
|
+
Every public type and method is annotated with `@since 1.0.0` (matching the introducing
|
|
722
|
+
version) in javadoc. Removed APIs are marked `@Deprecated` for at least one minor
|
|
723
|
+
version before deletion. The spec describes a `revapi` or `japicmp` Maven plugin
|
|
724
|
+
configuration to enforce binary compatibility on every release build (optional but
|
|
725
|
+
strongly recommended).
|
|
726
|
+
|
|
727
|
+
#### 15. Fat JAR Verification
|
|
728
|
+
|
|
729
|
+
After `mvn package`, the spec instructs implementers to run:
|
|
730
|
+
|
|
731
|
+
```
|
|
732
|
+
jar tf target/{{artifactId}}-{{version}}.jar | head -50
|
|
733
|
+
unzip -p target/{{artifactId}}-{{version}}.jar META-INF/MANIFEST.MF
|
|
734
|
+
jar tf target/{{artifactId}}-{{version}}.jar | grep META-INF/versions/11/
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
…and to verify:
|
|
738
|
+
|
|
739
|
+
- `META-INF/MANIFEST.MF` contains `Multi-Release: true`
|
|
740
|
+
- `META-INF/versions/11/` contains every overlay class
|
|
741
|
+
- All OkHttp/Okio/Kotlin classes are present under
|
|
742
|
+
`com/bestinet/urp/{{artifactid}}/shaded/...`
|
|
743
|
+
- No unrelocated `okhttp3.*` / `okio.*` / `kotlin.*` packages exist at the JAR root
|
|
744
|
+
- The diagnostic main (if present) runs on JDK 8, 11, 17, and 21
|
|
745
|
+
|
|
746
|
+
### What Goes in Each `<module-name>/SPEC.md` (Per-Module)
|
|
747
|
+
|
|
748
|
+
For EACH module from PRD.md, create a folder named after the module (kebab-case) and
|
|
749
|
+
generate a `SPEC.md` inside it. Each file is **self-contained** — a coding agent can
|
|
750
|
+
implement the module after the shared infrastructure is in place.
|
|
751
|
+
|
|
752
|
+
Each module SPEC.md must include:
|
|
753
|
+
|
|
754
|
+
- **Header** with module name and back-reference to root `SPECIFICATION.md`
|
|
755
|
+
- **Traceability**: user story IDs, NFR IDs, constraint IDs, test IDs, reference IDs,
|
|
756
|
+
with version tags
|
|
757
|
+
- **OpenAPI Operation Mapping** — table mapping each user story to the upstream
|
|
758
|
+
operation ID, HTTP method, path, and OpenAPI schemas (request body, response body)
|
|
759
|
+
- **Public API**:
|
|
760
|
+
- Module facade interface and class (`{{Module}}Service`)
|
|
761
|
+
- Request DTOs (final classes with Builder)
|
|
762
|
+
- Response DTOs (final classes with Builder)
|
|
763
|
+
- Module exception class (extends `SdkApiException`)
|
|
764
|
+
- **Internal Implementation**:
|
|
765
|
+
- Service implementation (`internal/{{Module}}ServiceImpl`)
|
|
766
|
+
- URL constants
|
|
767
|
+
- JSON serializer methods per model
|
|
768
|
+
- **Error Mapping** — table mapping HTTP status codes to specific exception subclasses
|
|
769
|
+
- **Test Plan** — derived from PRD `### Test` section, expressed as MockWebServer scenarios
|
|
770
|
+
- **External References** — derived from PRD `### References` section
|
|
771
|
+
- **Complete code samples** for every component
|
|
772
|
+
|
|
773
|
+
See `references/spec-template.md` for the canonical module SPEC.md structure and
|
|
774
|
+
`references/http-client-patterns.md` for the OkHttp call pattern every service method
|
|
775
|
+
must follow.
|
|
776
|
+
|
|
777
|
+
## Changelog Append
|
|
778
|
+
|
|
779
|
+
After all specification files are successfully generated, append an entry to
|
|
780
|
+
`CHANGELOG.md` in the application folder (`<app_folder>/CHANGELOG.md`):
|
|
781
|
+
|
|
782
|
+
1. Read `<app_folder>/CHANGELOG.md`. If it does not exist, create it with:
|
|
783
|
+
```markdown
|
|
784
|
+
# Changelog
|
|
785
|
+
|
|
786
|
+
- This file tracks all skill executions by version for this application.
|
|
787
|
+
- The highest version recorded here is the current application version.
|
|
788
|
+
- Skills MUST NOT execute for a version lower than the highest version in this file.
|
|
789
|
+
|
|
790
|
+
---
|
|
791
|
+
```
|
|
792
|
+
2. Search for a `## {version}` heading matching the current version.
|
|
793
|
+
3. If the section **exists**: append a new row to its table.
|
|
794
|
+
4. If the section **does not exist**: insert a new section after the `---` below the
|
|
795
|
+
context header and before any existing `## vX.Y.Z` section (newest-first ordering),
|
|
796
|
+
with a new table header and the first row.
|
|
797
|
+
5. Row format: `| {YYYY-MM-DD} | {application_name} | specgen-sdk-java | {module or "All"} | Generated Java SDK technical specification |`
|
|
798
|
+
6. **Never modify or delete existing rows.**
|
|
799
|
+
|
|
800
|
+
## Output Format
|
|
801
|
+
|
|
802
|
+
```
|
|
803
|
+
<app_folder>/context/specification/
|
|
804
|
+
├── SPECIFICATION.md ↠Root: TOC + shared infrastructure
|
|
805
|
+
├── <module-1>/
|
|
806
|
+
│ └── SPEC.md ↠Self-contained module blueprint
|
|
807
|
+
├── <module-2>/
|
|
808
|
+
│ └── SPEC.md
|
|
809
|
+
└── <module-N>/
|
|
810
|
+
└── SPEC.md
|
|
811
|
+
```
|
|
812
|
+
|
|
813
|
+
**Sample code is mandatory.** Every component described in any spec file must include a
|
|
814
|
+
complete, self-explanatory code sample. The code must be continuous (no `// ...` gaps)
|
|
815
|
+
and usable as a direct reference by a coding agent.
|
|
816
|
+
|
|
817
|
+
## Constraints
|
|
818
|
+
|
|
819
|
+
These constraints are non-negotiable. Every code sample in the generated spec must
|
|
820
|
+
follow them.
|
|
821
|
+
|
|
822
|
+
### Universal Constraints
|
|
823
|
+
|
|
824
|
+
**Library, not application.** No `main()` (except the optional diagnostic), no Spring,
|
|
825
|
+
no application server, no static singletons exposed publicly, no global mutable state.
|
|
826
|
+
|
|
827
|
+
**Minimum dependencies.** OkHttp is the ONLY runtime third-party dependency unless an
|
|
828
|
+
optional protocol is selected. JSON, retry, validation, logging facade, builders are
|
|
829
|
+
all hand-coded against the JDK. Every additional dependency the spec proposes must
|
|
830
|
+
include a one-paragraph justification explaining why the JDK + OkHttp cannot do the job.
|
|
831
|
+
|
|
832
|
+
**Multi-Release JAR.** Sources under `src/main/java` MUST compile with `--release 8`.
|
|
833
|
+
Sources under `src/main/java11` MUST compile with `--release 11` and MUST NOT introduce
|
|
834
|
+
new public API — they are performance/feature overlays only. The fat JAR's
|
|
835
|
+
`META-INF/MANIFEST.MF` MUST contain `Multi-Release: true` and `META-INF/versions/11/`
|
|
836
|
+
MUST contain the overlay classes.
|
|
837
|
+
|
|
838
|
+
**Fat JAR is the headline artifact.** The Shade configuration must produce a fat JAR
|
|
839
|
+
with relocated transitive dependencies. The thin JAR with declared dependencies is
|
|
840
|
+
also produced for Maven consumers.
|
|
841
|
+
|
|
842
|
+
**Constructor injection — no setters on services.** The facade and every service take
|
|
843
|
+
their collaborators (HTTP client, config, JSON utility) via the constructor and store
|
|
844
|
+
them in `private final` fields. Builders mutate state during construction but the
|
|
845
|
+
resulting object is immutable.
|
|
846
|
+
|
|
847
|
+
**Immutable models.** Model classes are `final`, all fields are `private final`, no
|
|
848
|
+
setters, only a Builder. `equals`, `hashCode`, and `toString` are explicit (or generated
|
|
849
|
+
via `Objects.hash` / `String.format`) — no Lombok.
|
|
850
|
+
|
|
851
|
+
**Thread-safe by design.** A single `{{ClientName}}` instance is safe to share across
|
|
852
|
+
threads. The shared `OkHttpClient` is the only HTTP transport instance. Services hold
|
|
853
|
+
references to the shared client; they do not create new ones.
|
|
854
|
+
|
|
855
|
+
**No checked exceptions in the public API.** Every public method declares only
|
|
856
|
+
`RuntimeException` subclasses (the SDK's own hierarchy). Internal `IOException` is
|
|
857
|
+
caught and rewrapped as `SdkClientException` or `SdkApiException`.
|
|
858
|
+
|
|
859
|
+
**Every public type and method is javadoc'd.** No exceptions. Tools (IDE,
|
|
860
|
+
Maven Javadoc plugin) drive consumer adoption.
|
|
861
|
+
|
|
862
|
+
**No reflection on consumer types.** Models are static; serialization is explicit.
|
|
863
|
+
|
|
864
|
+
**Deterministic JSON output.** Map iteration order is preserved (`LinkedHashMap`),
|
|
865
|
+
booleans serialize as `true`/`false`, numbers without unnecessary trailing zeros.
|
|
866
|
+
|
|
867
|
+
### Conditional Constraints
|
|
868
|
+
|
|
869
|
+
**If Auth = Bearer token:**
|
|
870
|
+
|
|
871
|
+
- Tokens are NEVER logged. The `LoggingInterceptor` MUST redact `Authorization`
|
|
872
|
+
header values to `Bearer ***`.
|
|
873
|
+
- Tokens are stored only in the `BearerCredentialProvider` — never in `Config` itself.
|
|
874
|
+
|
|
875
|
+
**If Auth = mTLS:**
|
|
876
|
+
|
|
877
|
+
- The keystore path and password are read from the `Config` and applied to a fresh
|
|
878
|
+
`SSLSocketFactory` at client-build time. The keystore file is never bundled.
|
|
879
|
+
|
|
880
|
+
**If Async = yes:**
|
|
881
|
+
|
|
882
|
+
- Every async method returns `CompletableFuture<T>` and never blocks the calling
|
|
883
|
+
thread. Internal blocking calls are dispatched to OkHttp's dispatcher (which already
|
|
884
|
+
uses its own executor) — the SDK never spins up its own thread pool unless the user
|
|
885
|
+
supplies one.
|
|
886
|
+
|
|
887
|
+
**If WebSocket protocol is selected:**
|
|
888
|
+
|
|
889
|
+
- Use `OkHttpClient.newWebSocket(...)` on JDK 8. JDK 11 overlay MAY use
|
|
890
|
+
`java.net.http.HttpClient.newWebSocketBuilder()` for performance, but the public API
|
|
891
|
+
surface (`Subscription` interface) MUST be identical across overlays.
|
|
892
|
+
|
|
893
|
+
**If AMQP / MQTT is selected:**
|
|
894
|
+
|
|
895
|
+
- The relevant client lib (`amqp-client` / `paho-mqtt-client`) is a runtime dependency
|
|
896
|
+
AND is shaded into the fat JAR with the same relocation rule as OkHttp.
|
|
897
|
+
|
|
898
|
+
**If a `main()` (diagnostic) is included:**
|
|
899
|
+
|
|
900
|
+
- It reads `BASE_URL`, `API_TOKEN`, etc. from environment variables only — never
|
|
901
|
+
hardcoded.
|
|
902
|
+
- The fat JAR's `Main-Class` manifest entry points to `cli.Diagnose`; otherwise omit
|
|
903
|
+
`Main-Class` entirely.
|
|
904
|
+
|
|
905
|
+
## Principles Embedded in the Spec
|
|
906
|
+
|
|
907
|
+
### Always-Applicable Principles
|
|
908
|
+
|
|
909
|
+
- Java 8 source baseline, Multi-Release JDK 11 overlay
|
|
910
|
+
- One runtime third-party dependency: OkHttp
|
|
911
|
+
- One artifact: a Multi-Release fat JAR; a thin JAR is a side effect of `mvn package`
|
|
912
|
+
- Hand-written JSON for every model — no reflection-based JSON libraries
|
|
913
|
+
- Builder pattern on the client and every request DTO
|
|
914
|
+
- Strategy pattern for retry / backoff / credential provider
|
|
915
|
+
- Adapter pattern: the SDK adapts the remote HTTP API to a typed Java API
|
|
916
|
+
- Constructor injection, immutable services, thread-safe shared transport
|
|
917
|
+
- Unchecked exceptions only in the public API
|
|
918
|
+
- All modules share one `OkHttpClient`
|
|
919
|
+
- Every request goes through the same interceptor chain (auth, retry, correlation, logging)
|
|
920
|
+
- OpenAPI is the source of truth for endpoint paths, schemas, and operation IDs
|
|
921
|
+
- MockWebServer drives every test — no live calls
|
|
922
|
+
- Javadoc on every public type and method
|
|
923
|
+
- Public API is binary-compatible within a major version (japicmp / revapi enforced)
|
|
924
|
+
|
|
925
|
+
### Conditional Principles
|
|
926
|
+
|
|
927
|
+
- **If Auth = Bearer:** 401 triggers a single transparent refresh-and-retry; never two.
|
|
928
|
+
- **If Async = yes:** sync methods are convenience wrappers around the async ones —
|
|
929
|
+
`Service.foo(...)` calls `Service.fooAsync(...).join()`, not the other way around.
|
|
930
|
+
- **If WebSocket:** the public WebSocket API exposes only `connect`, `send`, `close`,
|
|
931
|
+
and a listener interface. No raw `okhttp3.WebSocket` ever escapes the package.
|
|
932
|
+
- **If AMQP / MQTT:** these are exposed as separate top-level facades
|
|
933
|
+
(`client.amqp()`, `client.mqtt()`), not mixed into the REST modules.
|