bmad-method-quarkus 1.0.0
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/.claude-plugin/marketplace.json +53 -0
- package/AGENTS.md +12 -0
- package/LICENSE +30 -0
- package/README.md +94 -0
- package/README_CN.md +108 -0
- package/README_VN.md +109 -0
- package/bmad-modules.yaml +133 -0
- package/package.json +123 -0
- package/removals.txt +87 -0
- package/src/bmm-skills/agents/bmad-agent-analyst/SKILL.md +76 -0
- package/src/bmm-skills/agents/bmad-agent-analyst/customize.toml +105 -0
- package/src/bmm-skills/agents/bmad-agent-architect/SKILL.md +76 -0
- package/src/bmm-skills/agents/bmad-agent-architect/customize.toml +65 -0
- package/src/bmm-skills/agents/bmad-agent-dev/SKILL.md +76 -0
- package/src/bmm-skills/agents/bmad-agent-dev/customize.toml +83 -0
- package/src/bmm-skills/agents/bmad-agent-pm/SKILL.md +76 -0
- package/src/bmm-skills/agents/bmad-agent-pm/customize.toml +75 -0
- package/src/bmm-skills/agents/bmad-agent-ux-designer/SKILL.md +76 -0
- package/src/bmm-skills/agents/bmad-agent-ux-designer/customize.toml +60 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/.memlog.md +12 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/.memlog.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/SKILL.md +86 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/SKILL.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/customize.toml +37 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/customize.toml:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/references/enrich-stories.md +19 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/references/enrich-stories.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/references/prompt-quality-canon.md +79 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/references/prompt-quality-canon.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/SKILL.md +80 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/SKILL.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/assets/module-help.csv +9 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/assets/module-help.csv:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/assets/module.yaml +16 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/assets/module.yaml:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/scripts/cleanup-legacy.py +287 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/scripts/cleanup-legacy.py:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/scripts/merge-config.py +441 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/scripts/merge-config.py:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/scripts/merge-help-csv.py +246 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/bqa-setup/scripts/merge-help-csv.py:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-error-handling-i18n/SKILL.md +181 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-error-handling-i18n/SKILL.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-grpc-services/SKILL.md +141 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-grpc-services/SKILL.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-hexagonal-core/SKILL.md +392 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-hexagonal-core/SKILL.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-kafka-messaging/SKILL.md +148 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-kafka-messaging/SKILL.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-observability-otel/SKILL.md +180 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-observability-otel/SKILL.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-openapi-tmforum/SKILL.md +128 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-openapi-tmforum/SKILL.md:Zone.Identifier +0 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-sql-jdbc-agroal/SKILL.md +245 -0
- package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-sql-jdbc-agroal/SKILL.md:Zone.Identifier +0 -0
- package/src/bmm-skills/module-help.csv +19 -0
- package/src/bmm-skills/module.yaml +92 -0
- package/src/bmm-skills/plan/bmad-architecture/SKILL.md +85 -0
- package/src/bmm-skills/plan/bmad-architecture/assets/spine-template.md +79 -0
- package/src/bmm-skills/plan/bmad-architecture/customize.toml +102 -0
- package/src/bmm-skills/plan/bmad-architecture/references/headless.md +26 -0
- package/src/bmm-skills/plan/bmad-architecture/references/reviewer-gate.md +13 -0
- package/src/bmm-skills/plan/bmad-architecture/scripts/lint_spine.py +257 -0
- package/src/bmm-skills/plan/bmad-architecture/scripts/tests/test_lint_spine.py +270 -0
- package/src/bmm-skills/plan/bmad-create-epics-and-stories/SKILL.md +93 -0
- package/src/bmm-skills/plan/bmad-create-epics-and-stories/customize.toml +41 -0
- package/src/bmm-skills/plan/bmad-create-epics-and-stories/steps/step-01-validate-prerequisites.md +263 -0
- package/src/bmm-skills/plan/bmad-create-epics-and-stories/steps/step-02-design-epics.md +242 -0
- package/src/bmm-skills/plan/bmad-create-epics-and-stories/steps/step-03-create-stories.md +255 -0
- package/src/bmm-skills/plan/bmad-create-epics-and-stories/steps/step-04-final-validation.md +143 -0
- package/src/bmm-skills/plan/bmad-create-epics-and-stories/templates/epics-template.md +61 -0
- package/src/bmm-skills/plan/bmad-generate-project-context/SKILL.md +10 -0
- package/src/bmm-skills/plan/bmad-prd/SKILL.md +94 -0
- package/src/bmm-skills/plan/bmad-prd/assets/headless-schemas.md +76 -0
- package/src/bmm-skills/plan/bmad-prd/assets/prd-template.md +165 -0
- package/src/bmm-skills/plan/bmad-prd/assets/prd-validation-checklist.md +135 -0
- package/src/bmm-skills/plan/bmad-prd/assets/validation-report-template.html +325 -0
- package/src/bmm-skills/plan/bmad-prd/customize.toml +149 -0
- package/src/bmm-skills/plan/bmad-prd/references/headless.md +39 -0
- package/src/bmm-skills/plan/bmad-prd/references/validate.md +97 -0
- package/src/bmm-skills/plan/bmad-prfaq/SKILL.md +135 -0
- package/src/bmm-skills/plan/bmad-prfaq/agents/artifact-analyzer.md +60 -0
- package/src/bmm-skills/plan/bmad-prfaq/agents/web-researcher.md +49 -0
- package/src/bmm-skills/plan/bmad-prfaq/assets/prfaq-template.md +62 -0
- package/src/bmm-skills/plan/bmad-prfaq/bmad-manifest.json +16 -0
- package/src/bmm-skills/plan/bmad-prfaq/customize.toml +41 -0
- package/src/bmm-skills/plan/bmad-prfaq/references/customer-faq.md +55 -0
- package/src/bmm-skills/plan/bmad-prfaq/references/internal-faq.md +51 -0
- package/src/bmm-skills/plan/bmad-prfaq/references/press-release.md +60 -0
- package/src/bmm-skills/plan/bmad-prfaq/references/verdict.md +83 -0
- package/src/bmm-skills/plan/bmad-product-brief/SKILL.md +91 -0
- package/src/bmm-skills/plan/bmad-product-brief/assets/brief-template.md +41 -0
- package/src/bmm-skills/plan/bmad-product-brief/customize.toml +101 -0
- package/src/bmm-skills/plan/bmad-project-context/SKILL.md +110 -0
- package/src/bmm-skills/plan/bmad-project-context/customize.toml +24 -0
- package/src/bmm-skills/plan/bmad-project-context/references/best-practices.md +65 -0
- package/src/bmm-skills/plan/bmad-project-context/references/template.md +55 -0
- package/src/bmm-skills/plan/bmad-spec/SKILL.md +160 -0
- package/src/bmm-skills/plan/bmad-spec/assets/headless-schemas.md +33 -0
- package/src/bmm-skills/plan/bmad-spec/assets/spec-template.md +49 -0
- package/src/bmm-skills/plan/bmad-spec/assets/stories-schema.md +44 -0
- package/src/bmm-skills/plan/bmad-spec/customize.toml +52 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/SKILL.md +62 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/customize.toml +41 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/references/fix-sprint-status.md +30 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/references/generate-tracking.md +25 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/references/readiness-gate.md +20 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/references/status-view.md +14 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/references/validate.md +10 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/scripts/__pycache__/sprint_plan.cpython-311.pyc +0 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/scripts/sprint_plan.py +697 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/scripts/tests/__pycache__/test_sprint_plan.cpython-311-pytest-9.1.1.pyc +0 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/scripts/tests/test_sprint_plan.py +524 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/sprint-status-template.yaml +71 -0
- package/src/bmm-skills/plan/bmad-ux/SKILL.md +90 -0
- package/src/bmm-skills/plan/bmad-ux/assets/color-themes.md +9 -0
- package/src/bmm-skills/plan/bmad-ux/assets/design-directions.md +9 -0
- package/src/bmm-skills/plan/bmad-ux/assets/design-example-editorial.md +158 -0
- package/src/bmm-skills/plan/bmad-ux/assets/design-example-mobile.md +93 -0
- package/src/bmm-skills/plan/bmad-ux/assets/design-example-shadcn.md +109 -0
- package/src/bmm-skills/plan/bmad-ux/assets/excalidraw-wireframe.md +19 -0
- package/src/bmm-skills/plan/bmad-ux/assets/experience-example-mobile.md +112 -0
- package/src/bmm-skills/plan/bmad-ux/assets/experience-example-shadcn.md +133 -0
- package/src/bmm-skills/plan/bmad-ux/assets/headless-schemas.md +84 -0
- package/src/bmm-skills/plan/bmad-ux/assets/key-screens.md +29 -0
- package/src/bmm-skills/plan/bmad-ux/assets/validation-report-template.html +319 -0
- package/src/bmm-skills/plan/bmad-ux/customize.toml +102 -0
- package/src/bmm-skills/plan/bmad-ux/references/creative-tools.md +19 -0
- package/src/bmm-skills/plan/bmad-ux/references/design-md-spec.md +50 -0
- package/src/bmm-skills/plan/bmad-ux/references/headless.md +37 -0
- package/src/bmm-skills/plan/bmad-ux/references/validate.md +115 -0
- package/src/bmm-skills/ship/bmad-build/SKILL.md +13 -0
- package/src/bmm-skills/ship/bmad-build/compile-epic-context.md +62 -0
- package/src/bmm-skills/ship/bmad-build/customize.toml +164 -0
- package/src/bmm-skills/ship/bmad-build/references/deletion-check.md +14 -0
- package/src/bmm-skills/ship/bmad-build/review-prompts/edge-case-hunter.md +88 -0
- package/src/bmm-skills/ship/bmad-build/review-prompts/verification-gap.md +113 -0
- package/src/bmm-skills/ship/bmad-build/spec-template.md +89 -0
- package/src/bmm-skills/ship/bmad-build/step-01-clarify-and-route.md +105 -0
- package/src/bmm-skills/ship/bmad-build/step-02-plan.md +47 -0
- package/src/bmm-skills/ship/bmad-build/step-03-implement.md +49 -0
- package/src/bmm-skills/ship/bmad-build/step-04-review.md +55 -0
- package/src/bmm-skills/ship/bmad-build/step-05-present.md +75 -0
- package/src/bmm-skills/ship/bmad-build/step-oneshot.md +77 -0
- package/src/bmm-skills/ship/bmad-build/sync-sprint-status.md +19 -0
- package/src/bmm-skills/ship/bmad-build/workflow.md +84 -0
- package/src/bmm-skills/ship/bmad-build-auto/SKILL.md +13 -0
- package/src/bmm-skills/ship/bmad-build-auto/compile-epic-context.md +62 -0
- package/src/bmm-skills/ship/bmad-build-auto/customize.toml +121 -0
- package/src/bmm-skills/ship/bmad-build-auto/references/deletion-check.md +14 -0
- package/src/bmm-skills/ship/bmad-build-auto/review-prompts/edge-case-hunter.md +88 -0
- package/src/bmm-skills/ship/bmad-build-auto/review-prompts/verification-gap.md +113 -0
- package/src/bmm-skills/ship/bmad-build-auto/spec-template.md +99 -0
- package/src/bmm-skills/ship/bmad-build-auto/step-01-clarify-and-route.md +83 -0
- package/src/bmm-skills/ship/bmad-build-auto/step-02-plan.md +27 -0
- package/src/bmm-skills/ship/bmad-build-auto/step-03-implement.md +44 -0
- package/src/bmm-skills/ship/bmad-build-auto/step-04-review.md +96 -0
- package/src/bmm-skills/ship/bmad-build-auto/workflow.md +104 -0
- package/src/bmm-skills/ship/bmad-checkpoint-preview/SKILL.md +68 -0
- package/src/bmm-skills/ship/bmad-checkpoint-preview/customize.toml +41 -0
- package/src/bmm-skills/ship/bmad-checkpoint-preview/generate-trail.md +38 -0
- package/src/bmm-skills/ship/bmad-checkpoint-preview/step-01-orientation.md +105 -0
- package/src/bmm-skills/ship/bmad-checkpoint-preview/step-02-walkthrough.md +89 -0
- package/src/bmm-skills/ship/bmad-checkpoint-preview/step-03-detail-pass.md +106 -0
- package/src/bmm-skills/ship/bmad-checkpoint-preview/step-04-testing.md +74 -0
- package/src/bmm-skills/ship/bmad-checkpoint-preview/step-05-wrapup.md +30 -0
- package/src/bmm-skills/ship/bmad-code-review/SKILL.md +90 -0
- package/src/bmm-skills/ship/bmad-code-review/customize.toml +113 -0
- package/src/bmm-skills/ship/bmad-code-review/references/deletion-check.md +14 -0
- package/src/bmm-skills/ship/bmad-code-review/review-prompts/edge-case-hunter.md +88 -0
- package/src/bmm-skills/ship/bmad-code-review/review-prompts/verification-gap.md +113 -0
- package/src/bmm-skills/ship/bmad-code-review/steps/step-01-gather-context.md +87 -0
- package/src/bmm-skills/ship/bmad-code-review/steps/step-02-review.md +32 -0
- package/src/bmm-skills/ship/bmad-code-review/steps/step-03-triage.md +50 -0
- package/src/bmm-skills/ship/bmad-code-review/steps/step-04-present.md +132 -0
- package/src/bmm-skills/ship/bmad-correct-course/SKILL.md +300 -0
- package/src/bmm-skills/ship/bmad-correct-course/checklist.md +288 -0
- package/src/bmm-skills/ship/bmad-correct-course/customize.toml +41 -0
- package/src/bmm-skills/ship/bmad-qa-generate-e2e-tests/SKILL.md +176 -0
- package/src/bmm-skills/ship/bmad-qa-generate-e2e-tests/checklist.md +33 -0
- package/src/bmm-skills/ship/bmad-qa-generate-e2e-tests/customize.toml +41 -0
- package/src/bmm-skills/ship/bmad-retrospective/SKILL.md +94 -0
- package/src/bmm-skills/ship/bmad-retrospective/customize.toml +41 -0
- package/src/bmm-skills/ship/bmad-retrospective/references/acceptance-verdict.md +55 -0
- package/src/bmm-skills/ship/bmad-retrospective/references/aggregate-views.md +17 -0
- package/src/bmm-skills/ship/bmad-retrospective/references/evidence-gathering.md +30 -0
- package/src/bmm-skills/ship/bmad-retrospective/references/retro-document.md +84 -0
- package/src/bmm-skills/ship/bmad-retrospective/references/team-discussion.md +22 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/__pycache__/sprint_status.cpython-311.pyc +0 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/git_evidence.py +304 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/sprint_status.py +746 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/__pycache__/test_git_evidence.cpython-311-pytest-9.1.1.pyc +0 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/__pycache__/test_sprint_status.cpython-311-pytest-9.1.1.pyc +0 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/fixtures/sprint-status-template.yaml +71 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/test_git_evidence.py +750 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/test_sprint_status.py +1579 -0
- package/src/bmm-skills/v6-shims/README.md +28 -0
- package/src/bmm-skills/v6-shims/bmad-create-architecture/SKILL.md +30 -0
- package/src/bmm-skills/v6-shims/bmad-create-architecture/customize.toml +41 -0
- package/src/bmm-skills/v6-shims/bmad-create-prd/SKILL.md +30 -0
- package/src/bmm-skills/v6-shims/bmad-create-prd/customize.toml +41 -0
- package/src/bmm-skills/v6-shims/bmad-create-story/SKILL.md +434 -0
- package/src/bmm-skills/v6-shims/bmad-create-story/checklist.md +357 -0
- package/src/bmm-skills/v6-shims/bmad-create-story/customize.toml +41 -0
- package/src/bmm-skills/v6-shims/bmad-create-story/discover-inputs.md +88 -0
- package/src/bmm-skills/v6-shims/bmad-create-story/template.md +49 -0
- package/src/bmm-skills/v6-shims/bmad-dev-auto/SKILL.md +19 -0
- package/src/bmm-skills/v6-shims/bmad-dev-story/SKILL.md +502 -0
- package/src/bmm-skills/v6-shims/bmad-dev-story/checklist.md +80 -0
- package/src/bmm-skills/v6-shims/bmad-dev-story/customize.toml +44 -0
- package/src/bmm-skills/v6-shims/bmad-document-project/SKILL.md +14 -0
- package/src/bmm-skills/v6-shims/bmad-domain-research/SKILL.md +14 -0
- package/src/bmm-skills/v6-shims/bmad-edit-prd/SKILL.md +30 -0
- package/src/bmm-skills/v6-shims/bmad-edit-prd/customize.toml +42 -0
- package/src/bmm-skills/v6-shims/bmad-market-research/SKILL.md +14 -0
- package/src/bmm-skills/v6-shims/bmad-quick-dev/SKILL.md +19 -0
- package/src/bmm-skills/v6-shims/bmad-sprint-status/SKILL.md +26 -0
- package/src/bmm-skills/v6-shims/bmad-sprint-status/customize.toml +41 -0
- package/src/bmm-skills/v6-shims/bmad-technical-research/SKILL.md +14 -0
- package/src/bmm-skills/v6-shims/bmad-validate-prd/SKILL.md +30 -0
- package/src/bmm-skills/v6-shims/bmad-validate-prd/customize.toml +42 -0
- package/src/core-skills/bmad-advanced-elicitation/SKILL.md +65 -0
- package/src/core-skills/bmad-advanced-elicitation/assets/methods.csv +72 -0
- package/src/core-skills/bmad-advanced-elicitation/customize.toml +54 -0
- package/src/core-skills/bmad-advanced-elicitation/scripts/pick_methods.py +233 -0
- package/src/core-skills/bmad-advanced-elicitation/scripts/tests/test_pick_methods.py +228 -0
- package/src/core-skills/bmad-brainstorming/SKILL.md +80 -0
- package/src/core-skills/bmad-brainstorming/assets/brain-icons.json +166 -0
- package/src/core-skills/bmad-brainstorming/assets/brain-methods.csv +109 -0
- package/src/core-skills/bmad-brainstorming/assets/brain-selector.html +328 -0
- package/src/core-skills/bmad-brainstorming/customize.toml +84 -0
- package/src/core-skills/bmad-brainstorming/references/converge.md +24 -0
- package/src/core-skills/bmad-brainstorming/references/finalize.md +26 -0
- package/src/core-skills/bmad-brainstorming/references/headless.md +54 -0
- package/src/core-skills/bmad-brainstorming/references/in-chat-techniques.md +18 -0
- package/src/core-skills/bmad-brainstorming/references/mode-autonomous.md +10 -0
- package/src/core-skills/bmad-brainstorming/references/mode-facilitator.md +11 -0
- package/src/core-skills/bmad-brainstorming/references/mode-partner.md +16 -0
- package/src/core-skills/bmad-brainstorming/references/resume.md +5 -0
- package/src/core-skills/bmad-brainstorming/scripts/brain.py +770 -0
- package/src/core-skills/bmad-brainstorming/scripts/tests/test_brain.py +239 -0
- package/src/core-skills/bmad-customize/SKILL.md +111 -0
- package/src/core-skills/bmad-customize/scripts/list_customizable_skills.py +231 -0
- package/src/core-skills/bmad-customize/scripts/tests/test_list_customizable_skills.py +249 -0
- package/src/core-skills/bmad-deep-recon/SKILL.md +82 -0
- package/src/core-skills/bmad-deep-recon/assets/research.template.md +18 -0
- package/src/core-skills/bmad-deep-recon/customize.toml +212 -0
- package/src/core-skills/bmad-deep-recon/references/draft.md +8 -0
- package/src/core-skills/bmad-deep-recon/references/finalize.md +11 -0
- package/src/core-skills/bmad-deep-recon/references/html-briefing.md +16 -0
- package/src/core-skills/bmad-deep-recon/references/lifecycle.md +11 -0
- package/src/core-skills/bmad-deep-recon/references/process.md +10 -0
- package/src/core-skills/bmad-deep-recon/references/run.md +73 -0
- package/src/core-skills/bmad-deep-recon/references/selection.md +13 -0
- package/src/core-skills/bmad-deep-recon/references/synthesis.md +16 -0
- package/src/core-skills/bmad-deep-recon/references/verification.md +29 -0
- package/src/core-skills/bmad-deep-recon/scripts/recon_kit.py +322 -0
- package/src/core-skills/bmad-deep-recon/scripts/tests/test_recon_kit.py +144 -0
- package/src/core-skills/bmad-deep-recon/types/academic-lit.md +19 -0
- package/src/core-skills/bmad-deep-recon/types/competitive.md +19 -0
- package/src/core-skills/bmad-deep-recon/types/domain.md +19 -0
- package/src/core-skills/bmad-deep-recon/types/market.md +19 -0
- package/src/core-skills/bmad-deep-recon/types/technical.md +19 -0
- package/src/core-skills/bmad-deep-recon/types/user-voice.md +19 -0
- package/src/core-skills/bmad-forge-idea/SKILL.md +107 -0
- package/src/core-skills/bmad-forge-idea/customize.toml +42 -0
- package/src/core-skills/bmad-forge-idea/scripts/resolve_personas.py +275 -0
- package/src/core-skills/bmad-forge-idea/scripts/tests/test_resolve_personas.py +138 -0
- package/src/core-skills/bmad-help/SKILL.md +75 -0
- package/src/core-skills/bmad-party-mode/SKILL.md +60 -0
- package/src/core-skills/bmad-party-mode/customize.toml +211 -0
- package/src/core-skills/bmad-party-mode/references/create-party.md +70 -0
- package/src/core-skills/bmad-party-mode/references/mode-agent-team.md +13 -0
- package/src/core-skills/bmad-party-mode/references/mode-auto.md +13 -0
- package/src/core-skills/bmad-party-mode/references/mode-subagent.md +31 -0
- package/src/core-skills/bmad-party-mode/references/party-memory.md +51 -0
- package/src/core-skills/bmad-party-mode/scripts/resolve_party.py +282 -0
- package/src/core-skills/bmad-party-mode/scripts/tests/test_resolve_party.py +146 -0
- package/src/core-skills/bmad-review/SKILL.md +49 -0
- package/src/core-skills/bmad-review/customize.toml +141 -0
- package/src/core-skills/bmad-review/references/editorial-common.md +56 -0
- package/src/core-skills/bmad-review/references/lens-adversarial.md +19 -0
- package/src/core-skills/bmad-review/references/lens-edge-case-hunter.md +54 -0
- package/src/core-skills/bmad-review/references/lens-prose.md +7 -0
- package/src/core-skills/bmad-review/references/lens-structure.md +9 -0
- package/src/core-skills/bmad-review/references/lens-verification-gap.md +92 -0
- package/src/core-skills/bmad-review/references/structure-models.md +44 -0
- package/src/core-skills/bmad-review/scripts/tests/test_word_metrics.py +62 -0
- package/src/core-skills/bmad-review/scripts/word_metrics.py +102 -0
- package/src/core-skills/module-help.csv +10 -0
- package/src/core-skills/module.yaml +38 -0
- package/src/core-skills/v6-shims/README.md +25 -0
- package/src/core-skills/v6-shims/bmad-editorial-review/SKILL.md +6 -0
- package/src/core-skills/v6-shims/bmad-editorial-review/customize.toml +31 -0
- package/src/core-skills/v6-shims/bmad-editorial-review-prose/SKILL.md +6 -0
- package/src/core-skills/v6-shims/bmad-editorial-review-structure/SKILL.md +6 -0
- package/src/core-skills/v6-shims/bmad-review-adversarial-general/SKILL.md +6 -0
- package/src/core-skills/v6-shims/bmad-review-edge-case-hunter/SKILL.md +6 -0
- package/src/core-skills/v6-shims/bmad-review-verification-gap/SKILL.md +6 -0
- package/src/scripts/__pycache__/config_utils.cpython-311.pyc +0 -0
- package/src/scripts/config_utils.py +119 -0
- package/src/scripts/memlog.py +224 -0
- package/src/scripts/render_skill.py +401 -0
- package/src/scripts/resolve_config.py +74 -0
- package/src/scripts/resolve_customization.py +99 -0
- package/src/scripts/tests/__pycache__/test_config_utils.cpython-311.pyc +0 -0
- package/src/scripts/tests/__pycache__/test_resolve_config.cpython-311.pyc +0 -0
- package/src/scripts/tests/__pycache__/test_resolve_customization.cpython-311.pyc +0 -0
- package/src/scripts/tests/test_config_utils.py +85 -0
- package/src/scripts/tests/test_memlog.py +306 -0
- package/src/scripts/tests/test_resolve_config.py +89 -0
- package/src/scripts/tests/test_resolve_customization.py +77 -0
- package/tools/bundle-web-bundles.js +117 -0
- package/tools/format-workflow-md.js +263 -0
- package/tools/installer/README.md +60 -0
- package/tools/installer/bmad-cli.js +105 -0
- package/tools/installer/cli-utils.js +57 -0
- package/tools/installer/commands/install.js +149 -0
- package/tools/installer/commands/status.js +65 -0
- package/tools/installer/commands/uninstall.js +167 -0
- package/tools/installer/core/config.js +73 -0
- package/tools/installer/core/existing-install.js +121 -0
- package/tools/installer/core/install-paths.js +132 -0
- package/tools/installer/core/installer.js +1767 -0
- package/tools/installer/core/legacy-warnings.js +151 -0
- package/tools/installer/core/manifest-generator.js +859 -0
- package/tools/installer/core/manifest.js +433 -0
- package/tools/installer/core/uv-check.js +195 -0
- package/tools/installer/core/wsl-node-check.js +109 -0
- package/tools/installer/file-ops.js +204 -0
- package/tools/installer/fs-native.js +116 -0
- package/tools/installer/ide/_config-driven.js +972 -0
- package/tools/installer/ide/manager.js +324 -0
- package/tools/installer/ide/platform-codes.js +80 -0
- package/tools/installer/ide/platform-codes.yaml +343 -0
- package/tools/installer/ide/shared/installed-skills.js +50 -0
- package/tools/installer/ide/shared/path-utils.js +219 -0
- package/tools/installer/ide/shared/skill-manifest.js +57 -0
- package/tools/installer/install-messages.yaml +37 -0
- package/tools/installer/list-options.js +210 -0
- package/tools/installer/message-loader.js +83 -0
- package/tools/installer/modules/channel-plan.js +203 -0
- package/tools/installer/modules/channel-resolver.js +241 -0
- package/tools/installer/modules/custom-module-manager.js +924 -0
- package/tools/installer/modules/external-manager.js +671 -0
- package/tools/installer/modules/git-env.js +47 -0
- package/tools/installer/modules/module-help-schema.js +13 -0
- package/tools/installer/modules/official-modules.js +2257 -0
- package/tools/installer/modules/plugin-resolver.js +398 -0
- package/tools/installer/modules/version-resolver.js +336 -0
- package/tools/installer/project-root.js +224 -0
- package/tools/installer/prompts.js +791 -0
- package/tools/installer/set-overrides.js +330 -0
- package/tools/installer/ui.js +2167 -0
- package/tools/installer/yaml-format.js +245 -0
- package/tools/javascript-conventions.md +5 -0
- package/tools/migrate-custom-module-paths.js +124 -0
- package/tools/skill-validator.md +378 -0
- package/tools/validate-published-implementation-model.mjs +68 -0
- package/tools/validate-sidebar-order.js +388 -0
- package/tools/validate-skills.js +735 -0
- package/tools/validate-svg-changes.sh +356 -0
- package/web-bundles/README.md +46 -0
- package/web-bundles/brainstorming-coach/INSTRUCTIONS.md +86 -0
- package/web-bundles/brainstorming-coach/SKILL.md +83 -0
- package/web-bundles/brainstorming-coach/brain-methods.csv +62 -0
- package/web-bundles/bundles.json +139 -0
- package/web-bundles/market-and-industry-research/INSTRUCTIONS.md +88 -0
- package/web-bundles/market-and-industry-research/SKILL.md +59 -0
- package/web-bundles/prd-coach/INSTRUCTIONS.md +86 -0
- package/web-bundles/prd-coach/SKILL.md +101 -0
- package/web-bundles/prd-coach/prd-template.md +165 -0
- package/web-bundles/prd-coach/prd-validation-checklist.md +135 -0
- package/web-bundles/prfaq-coach/INSTRUCTIONS.md +86 -0
- package/web-bundles/prfaq-coach/SKILL.md +139 -0
- package/web-bundles/product-brief-coach/INSTRUCTIONS.md +86 -0
- package/web-bundles/product-brief-coach/SKILL.md +113 -0
- package/web-bundles/ux-coach/INSTRUCTIONS.md +92 -0
- package/web-bundles/ux-coach/SKILL.md +187 -0
- package/web-bundles/ux-coach/ux-validation.md +100 -0
package/src/bmm-skills/agents/bmad-quarkus-architect/skills/quarkus-observability-otel/SKILL.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: quarkus-observability-otel
|
|
3
|
+
description: Observability standard for Quarkus native services using OpenTelemetry — distributed tracing with W3C Trace Context (traceparent), trace_id/span_id in every log line (JSON logs + MDC), OTLP export, metrics with Micrometer, custom spans, and trace propagation across REST, gRPC, and Kafka. Use this skill whenever the user mentions OpenTelemetry, OTel, tracing, trace_id, span_id, traceparent, distributed tracing, logging standard, log correlation, metrics, Grafana/Tempo/Jaeger/Prometheus, or debugging requests across services. Includes span, metric, logger and audit-adapter naming conventions.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# OpenTelemetry Observability Standard (Quarkus)
|
|
7
|
+
|
|
8
|
+
Every request must be traceable end-to-end: REST → use case → JDBC → outbox → Kafka → consumer → gRPC. `trace_id`/`span_id` appear in every log line and propagate across every transport via W3C Trace Context. Applies to any Quarkus backend project; project directives (CLAUDE.md, ADRs, explicit instructions) override these defaults.
|
|
9
|
+
|
|
10
|
+
Extensions: `quarkus-opentelemetry` (+ `quarkus-micrometer-registry-prometheus` or Micrometer→OTLP for metrics, `quarkus-logging-json` for structured logs). All native-compatible.
|
|
11
|
+
|
|
12
|
+
## Baseline configuration
|
|
13
|
+
|
|
14
|
+
```properties
|
|
15
|
+
quarkus.application.name=bc05-users # becomes service.name
|
|
16
|
+
quarkus.otel.exporter.otlp.endpoint=http://otel-collector:4317
|
|
17
|
+
quarkus.otel.resource.attributes=deployment.environment=${ENV:dev},service.namespace=alva
|
|
18
|
+
|
|
19
|
+
# W3C Trace Context + Baggage are the DEFAULT propagators — do not override with B3 unless mandated
|
|
20
|
+
# quarkus.otel.propagators=tracecontext,baggage
|
|
21
|
+
|
|
22
|
+
# Sampling: head-based ratio in prod, always_on elsewhere
|
|
23
|
+
%prod.quarkus.otel.traces.sampler=parentbased_traceidratio
|
|
24
|
+
%prod.quarkus.otel.traces.sampler.arg=0.10
|
|
25
|
+
|
|
26
|
+
# Don't trace health/metrics noise
|
|
27
|
+
quarkus.otel.traces.suppress-non-application-uris=true
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Export to an **OTel Collector** (agent/sidecar/gateway), never directly to the vendor backend — keeps services vendor-neutral.
|
|
31
|
+
|
|
32
|
+
## Logs: trace_id and span_id in every line
|
|
33
|
+
|
|
34
|
+
Quarkus OTel injects `traceId`, `spanId`, `sampled` into the MDC automatically.
|
|
35
|
+
|
|
36
|
+
Console (dev, human-readable):
|
|
37
|
+
|
|
38
|
+
```properties
|
|
39
|
+
%dev.quarkus.log.console.format=%d{HH:mm:ss} %-5p traceId=%X{traceId} spanId=%X{spanId} [%c{2.}] %s%e%n
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Prod: JSON logs (parseable, ship to the log pipeline):
|
|
43
|
+
|
|
44
|
+
```properties
|
|
45
|
+
%prod.quarkus.log.console.json=true
|
|
46
|
+
%prod.quarkus.log.console.json.additional-field."service.name".value=${quarkus.application.name}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`quarkus-logging-json` includes MDC (traceId/spanId) as fields — logs↔traces correlation in Grafana/Tempo/Loki works with zero code. Rule: NEVER log a business operation without going through JBoss Logging/`Log` — `System.out` breaks correlation.
|
|
50
|
+
|
|
51
|
+
Also return the trace id to API callers for support tickets: a tiny response filter adds header `X-Trace-Id: ${Span.current().getSpanContext().getTraceId()}` on every response (especially errors — pairs with the unified exception handler).
|
|
52
|
+
|
|
53
|
+
## Automatic instrumentation (free)
|
|
54
|
+
|
|
55
|
+
With the extension present, these produce/propagate spans with no code:
|
|
56
|
+
- HTTP server (Quarkus REST) and REST Client
|
|
57
|
+
- gRPC server & client (metadata `traceparent`)
|
|
58
|
+
- Kafka via SmallRye Reactive Messaging (header `traceparent`)
|
|
59
|
+
- Agroal/JDBC: add `quarkus-opentelemetry-jdbc` wrapper (`quarkus.datasource.jdbc.telemetry=true`) for SQL spans
|
|
60
|
+
|
|
61
|
+
## Mandatory: trace context extraction via the OTel SDK only
|
|
62
|
+
|
|
63
|
+
It is **strictly prohibited** to build or parse trace strings by hand (no manual `00-...-...-01` concatenation, no UUID-based fake trace ids). The ONLY sanctioned way to obtain the active trace is the SDK injected by `quarkus-opentelemetry`:
|
|
64
|
+
|
|
65
|
+
```java
|
|
66
|
+
String traceId = Span.current().getSpanContext().getTraceId();
|
|
67
|
+
String spanId = Span.current().getSpanContext().getSpanId();
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
If `Span.current()` is invalid (no active trace — e.g., a batch job without instrumentation), fix the instrumentation of the entry point; do not fabricate ids.
|
|
71
|
+
|
|
72
|
+
## Audit standard: `context` jsonb column in `audit_event`
|
|
73
|
+
|
|
74
|
+
Every service with a local `audit_event` table persists the active trace in a `context` column of type `jsonb`:
|
|
75
|
+
|
|
76
|
+
```sql
|
|
77
|
+
ALTER TABLE audit_event ADD COLUMN IF NOT EXISTS context jsonb;
|
|
78
|
+
CREATE INDEX IF NOT EXISTS idx_audit_event_trace_id
|
|
79
|
+
ON audit_event ((context->>'trace_id'));
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Stored value (snake_case keys, exactly these):
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{ "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736", "span_id": "00f067aa0ba902b7" }
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Reference implementation. The application layer depends on an outbound port `AuditRecorder` (`application/port/out`); capturing the active span is an infrastructure concern, so it happens in the adapter:
|
|
89
|
+
|
|
90
|
+
```java
|
|
91
|
+
// application/port/out — capability noun, no technology in the name
|
|
92
|
+
public interface AuditRecorder {
|
|
93
|
+
void record(String action, String entity, String entityId);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// infrastructure/persistence — Jdbc<Port>
|
|
97
|
+
@ApplicationScoped
|
|
98
|
+
public class JdbcAuditRecorder implements AuditRecorder {
|
|
99
|
+
|
|
100
|
+
private final AuditEventRepository repository;
|
|
101
|
+
|
|
102
|
+
public JdbcAuditRecorder(AuditEventRepository repository) { this.repository = repository; }
|
|
103
|
+
|
|
104
|
+
@Override
|
|
105
|
+
public void record(String action, String entity, String entityId) {
|
|
106
|
+
String traceId = Span.current().getSpanContext().getTraceId();
|
|
107
|
+
String spanId = Span.current().getSpanContext().getSpanId();
|
|
108
|
+
JsonObject context = new JsonObject()
|
|
109
|
+
.put("trace_id", traceId)
|
|
110
|
+
.put("span_id", spanId);
|
|
111
|
+
repository.save(action, entity, entityId, context.encode());
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Identifiers are English (`record`, `action`, `entity`), even when the business vocabulary and the UI are Spanish — Spanish belongs in the i18n bundles, not in class and method names. `*Service` is not used here: this is an outbound adapter, not a use case.
|
|
117
|
+
|
|
118
|
+
Any code path that writes `audit_event` without populating `context` is non-compliant — flag it in review.
|
|
119
|
+
|
|
120
|
+
## Trace context through the outbox (async gap)
|
|
121
|
+
|
|
122
|
+
The automatic Kafka instrumentation covers direct emits. The outbox breaks the chain — the standard requires the trace in TWO places (see quarkus-kafka-messaging skill):
|
|
123
|
+
|
|
124
|
+
1. **Kafka header** `traceparent` (W3C format `00-<trace_id>-<span_id>-01`) for technical propagation — captured at outbox insert, forwarded by the relay (Debezium SMT or poller). Consumer side: SmallRye extracts it automatically → consumer spans join the original trace.
|
|
125
|
+
2. **Inside the outbox `payload` jsonb**, a `traceContext` block for audit/immutability:
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
"traceContext": { "trace_id": "...", "span_id": "..." }
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Both values come from `Span.current()` at insert time — never from manual strings.
|
|
132
|
+
|
|
133
|
+
## Custom spans and attributes
|
|
134
|
+
|
|
135
|
+
Annotate use cases that matter for diagnosis (not every method):
|
|
136
|
+
|
|
137
|
+
```java
|
|
138
|
+
// application/usecase — RegisterUserService implements RegisterUserUseCase
|
|
139
|
+
@WithSpan("usecase.registerUser")
|
|
140
|
+
public UserId register(@SpanAttribute("user.email.domain") String emailDomain, RegisterUserCommand cmd) { ... }
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
- Span names: `usecase.<verb><Entity>` (lowerCamelCase, matching the use-case method), `outbox.publish`, `job.<name>`.
|
|
144
|
+
- Attributes: business-relevant, LOW-cardinality, NEVER PII (no emails, MSISDNs, tokens — use derived/hashed values).
|
|
145
|
+
- Manual spans (`Tracer.spanBuilder`) only for background work not covered by annotations; always `try/finally` end the span and restore scope.
|
|
146
|
+
|
|
147
|
+
### Naming for telemetry artifacts
|
|
148
|
+
|
|
149
|
+
Canonical class-naming rules live in the quarkus-hexagonal-core skill; these are the observability-specific ones:
|
|
150
|
+
|
|
151
|
+
| Artifact | Convention | Example |
|
|
152
|
+
|---|---|---|
|
|
153
|
+
| Audit port / adapter | `AuditRecorder` / `Jdbc<Port>` | `AuditRecorder`, `JdbcAuditRecorder` |
|
|
154
|
+
| Trace-id response filter | `<Purpose>Filter` | `TraceIdResponseFilter` |
|
|
155
|
+
| Span name | `usecase.<verb><Entity>`, `outbox.publish`, `job.<name>` | `usecase.registerUser` |
|
|
156
|
+
| Span attribute | dotted lowercase, OTel semconv where one exists | `user.email.domain` |
|
|
157
|
+
| Metric | `<module>_<entity>_<action>_total` / `_seconds`, snake_case | `bc05_user_registrations_total` |
|
|
158
|
+
| Logger | one per class via `Log`/`Logger.getLogger(Xxx.class)` — never a shared `LogUtil` | |
|
|
159
|
+
| MDC / jsonb trace keys | `snake_case`, exactly `trace_id` / `span_id` | |
|
|
160
|
+
|
|
161
|
+
Span, metric and log-field names are a contract with the dashboards — renaming one silently breaks alerts. Treat a rename like an API change.
|
|
162
|
+
|
|
163
|
+
## Metrics (Micrometer)
|
|
164
|
+
|
|
165
|
+
- Rely on built-in HTTP/JVM-substrate/Kafka metrics first.
|
|
166
|
+
- Custom business metrics: counters/timers via `MeterRegistry`, names `bc05_user_registrations_total` style, low-cardinality tags only.
|
|
167
|
+
- Expose `/q/metrics` for Prometheus scrape or bridge Micrometer→OTLP if the platform standardizes on the collector for metrics too.
|
|
168
|
+
|
|
169
|
+
## Health
|
|
170
|
+
|
|
171
|
+
`quarkus-smallrye-health`: `/q/health/live`, `/q/health/ready`. Readiness includes DB and Kafka checks (provided by extensions). These endpoints are excluded from tracing (see suppress config).
|
|
172
|
+
|
|
173
|
+
## Checklist per service
|
|
174
|
+
|
|
175
|
+
1. `quarkus-opentelemetry` + JSON logging configured as above; OTLP → collector.
|
|
176
|
+
2. Log format includes traceId/spanId (both profiles); `X-Trace-Id` response filter registered.
|
|
177
|
+
3. JDBC telemetry enabled; `audit_event.context` jsonb populated with `trace_id`/`span_id` (+ index); outbox rows carry `traceparent` (header) AND `traceContext` in payload; the relay forwards the header.
|
|
178
|
+
3b. No manual trace-string construction anywhere — grep-check in review; only `Span.current()` via the OTel SDK.
|
|
179
|
+
4. Key use cases annotated `@WithSpan`; attributes reviewed for PII/cardinality.
|
|
180
|
+
5. Verify end-to-end in dev: one request produces a single trace spanning REST → DB → Kafka → consumer (Dev UI or Jaeger/Tempo).
|
|
Binary file
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: quarkus-openapi-tmforum
|
|
3
|
+
description: API design and documentation standard for Quarkus REST services — OpenAPI 3.1 via SmallRye, Swagger UI restricted to dev/test, and full alignment with TM Forum Open API specifications (TMF630 design guidelines, TMF resource patterns, Error schema, pagination, filtering, JSON Merge Patch). Use this skill whenever the user mentions Swagger, OpenAPI, API documentation, REST API design, TMF/TM Forum APIs, endpoints/resources naming, pagination, PATCH semantics, or creates/reviews ANY REST resource class. Includes resource, DTO, mapper and operationId naming conventions.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# OpenAPI + TM Forum API Standard (Quarkus)
|
|
7
|
+
|
|
8
|
+
North-bound/external REST APIs follow TM Forum Open API conventions (TMF630 REST Design Guidelines). Internal service-to-service calls use gRPC (see quarkus-grpc-services skill) — do not build internal REST clients. Applies to any Quarkus backend project (TMF specs matter most in telco-facing APIs; the TMF630 conventions are good REST defaults everywhere); project directives override where they conflict.
|
|
9
|
+
|
|
10
|
+
Extension: `quarkus-smallrye-openapi`.
|
|
11
|
+
|
|
12
|
+
## Design-first with TMF specs
|
|
13
|
+
|
|
14
|
+
1. If a TM Forum spec covers the capability (e.g., TMF632 Party, TMF672 User Roles & Permissions, TMF720 Digital Identity, TMF691 Federated ID, TMF696), START from the official TMF OpenAPI file: commit it to the monorepo `contracts/` folder (e.g. `contracts/tmf678-customer-bill.yaml` — the same folder the app's `service.yaml` references under `apis.provided[].contract`), trim to the operations actually implemented, and implement resources to match it. Do not invent alternative shapes for concepts TMF already models.
|
|
15
|
+
2. Only for non-TMF internal concepts, design your own — still following TMF630 conventions below.
|
|
16
|
+
3. The OpenAPI document is the contract: generate/verify in CI that the served `/q/openapi` matches the committed spec (store snapshot, diff on build).
|
|
17
|
+
|
|
18
|
+
## Swagger UI: dev/test only (hard rule)
|
|
19
|
+
|
|
20
|
+
```properties
|
|
21
|
+
# default is already dev-only; NEVER set always-include=true in a prod profile
|
|
22
|
+
quarkus.swagger-ui.always-include=false
|
|
23
|
+
%test.quarkus.swagger-ui.always-include=true
|
|
24
|
+
quarkus.smallrye-openapi.info-title=${quarkus.application.name}
|
|
25
|
+
quarkus.smallrye-openapi.info-version=${quarkus.application.version}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The raw OpenAPI document at `/q/openapi` may stay enabled in prod behind the gateway if the platform team requires it; Swagger UI itself never ships in the native prod binary.
|
|
29
|
+
|
|
30
|
+
## TMF630 conventions to enforce on every resource
|
|
31
|
+
|
|
32
|
+
### URLs & versioning
|
|
33
|
+
- Plural kebab-free camelCase resource names as in TMF specs: `/user`, `/partyAccount` — follow the TMF spec exactly when implementing one; plural nouns for custom resources.
|
|
34
|
+
- Base path: `/{context}/{apiName}/v{major}` e.g. `/tmf-api/digitalIdentityManagement/v4`. Major version in path only.
|
|
35
|
+
|
|
36
|
+
### Standard operations
|
|
37
|
+
| Operation | Verb | Response |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| List | `GET /resource` | 200 + array |
|
|
40
|
+
| Retrieve | `GET /resource/{id}` | 200 |
|
|
41
|
+
| Create | `POST /resource` | **201 + Location header + created body** |
|
|
42
|
+
| Partial update | `PATCH /resource/{id}` (JSON Merge Patch, `application/merge-patch+json`) | 200 + updated body |
|
|
43
|
+
| Delete | `DELETE /resource/{id}` | 204 |
|
|
44
|
+
|
|
45
|
+
No PUT unless the TMF spec defines it. No RPC-ish URLs (`/user/activate`) — state changes go through PATCH of a state field or a TMF Task resource (`POST /resource/{id}/taskName` only when the spec defines the task pattern).
|
|
46
|
+
|
|
47
|
+
### Query patterns (list operations)
|
|
48
|
+
- **Attribute selection**: `?fields=id,name,status` — always support; huge payloads otherwise.
|
|
49
|
+
- **Pagination**: `?offset=0&limit=20`; respond with headers `X-Total-Count`, `X-Result-Count`. Enforce a max limit.
|
|
50
|
+
- **Filtering**: simple equality `?status=active&role=admin`; document supported filters per resource.
|
|
51
|
+
|
|
52
|
+
### Resource body conventions
|
|
53
|
+
- Every resource has `id` and `href`.
|
|
54
|
+
- Polymorphism/extensibility fields where TMF-defined: `@type`, `@baseType`, `@schemaLocation`.
|
|
55
|
+
- Dates ISO-8601 UTC (`OffsetDateTime` serialized as `2026-08-17T15:04:05Z`).
|
|
56
|
+
- Errors: TMF Error schema from the unified handler (see quarkus-error-handling-i18n skill) — document it as the response for 4xx/5xx on every operation.
|
|
57
|
+
|
|
58
|
+
## Annotating resources (SmallRye OpenAPI)
|
|
59
|
+
|
|
60
|
+
DTOs live in `infrastructure/rest/dto` — never annotate domain classes.
|
|
61
|
+
|
|
62
|
+
### Naming
|
|
63
|
+
|
|
64
|
+
Canonical rules in the quarkus-hexagonal-core skill; REST/TMF specifics:
|
|
65
|
+
|
|
66
|
+
| Artifact | Convention | Example |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| Resource class | `<Resource>Resource` — matches the TMF resource name | `DigitalIdentityResource` |
|
|
69
|
+
| Response DTO | `<Resource>Dto` | `DigitalIdentityDto` |
|
|
70
|
+
| Create / update DTO | `<Resource>CreateDto` / `<Resource>UpdateDto` (TMF `X_Create` / `X_Update`) | `DigitalIdentityCreateDto` |
|
|
71
|
+
| Error DTO | `ErrorDto` (see quarkus-error-handling-i18n skill) | |
|
|
72
|
+
| DTO ↔ domain mapper | `<Resource>RestMapper` | `DigitalIdentityRestMapper` |
|
|
73
|
+
| `operationId` | `list/retrieve/create/patch/delete` + `<Resource>` | `listDigitalIdentity` |
|
|
74
|
+
| Path segment | camelCase, exactly as the TMF spec spells it | `/partyAccount` |
|
|
75
|
+
| JSON field | camelCase; TMF meta-fields keep their `@` | `@type`, `@baseType` |
|
|
76
|
+
|
|
77
|
+
When implementing a TMF spec the wire names are **not negotiable** — DTO field names must match the spec even where our own convention would differ. The Java class name adds the `Dto` suffix; the serialized schema name stays the TMF one (`@Schema(name = "DigitalIdentity")`).
|
|
78
|
+
|
|
79
|
+
```java
|
|
80
|
+
@Path("/tmf-api/digitalIdentityManagement/v4/digitalIdentity")
|
|
81
|
+
@Tag(name = "DigitalIdentity")
|
|
82
|
+
public class DigitalIdentityResource {
|
|
83
|
+
|
|
84
|
+
private final CreateDigitalIdentityUseCase createIdentity; // inbound port
|
|
85
|
+
private final DigitalIdentityRestMapper mapper;
|
|
86
|
+
|
|
87
|
+
public DigitalIdentityResource(CreateDigitalIdentityUseCase createIdentity,
|
|
88
|
+
DigitalIdentityRestMapper mapper) {
|
|
89
|
+
this.createIdentity = createIdentity;
|
|
90
|
+
this.mapper = mapper;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@GET
|
|
94
|
+
@Operation(operationId = "listDigitalIdentity", summary = "List or find DigitalIdentity objects")
|
|
95
|
+
@APIResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = DigitalIdentityDto[].class)))
|
|
96
|
+
@APIResponse(responseCode = "400", ref = "#/components/responses/BadRequest")
|
|
97
|
+
public RestResponse<List<DigitalIdentityDto>> list(
|
|
98
|
+
@QueryParam("fields") String fields,
|
|
99
|
+
@QueryParam("offset") @DefaultValue("0") int offset,
|
|
100
|
+
@QueryParam("limit") @DefaultValue("20") int limit) { ... }
|
|
101
|
+
|
|
102
|
+
@POST
|
|
103
|
+
@Operation(operationId = "createDigitalIdentity")
|
|
104
|
+
@APIResponse(responseCode = "201", headers = @Header(name = "Location"))
|
|
105
|
+
public RestResponse<DigitalIdentityDto> create(@Valid DigitalIdentityCreateDto dto, @Context UriInfo uri) {
|
|
106
|
+
var created = createIdentity.create(mapper.toCommand(dto));
|
|
107
|
+
return RestResponse.created(uri.getAbsolutePathBuilder().path(created.id()).build());
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Rules:
|
|
113
|
+
- `operationId` on every operation (client generation depends on it); match TMF naming (`listX`, `retrieveX`, `createX`, `patchX`, `deleteX`).
|
|
114
|
+
- Reusable components: define common responses (400/401/404/409/500 with TMF Error schema) once via an `@OpenAPIDefinition`/filter class, `ref` them everywhere.
|
|
115
|
+
- `*CreateDto` (no id/href) vs full DTO — TMF pattern (`X_Create`, `X_Update`).
|
|
116
|
+
- Bean Validation on DTOs (`@NotNull`, `@Size`) so constraints appear in the schema.
|
|
117
|
+
|
|
118
|
+
## PATCH implementation (JSON Merge Patch)
|
|
119
|
+
|
|
120
|
+
Consume `application/merge-patch+json`. Apply merge onto the current DTO representation, validate the result, map to an update command. Reject attempts to modify read-only fields (`id`, `href`, audit fields) with 400/409 per spec.
|
|
121
|
+
|
|
122
|
+
## Checklist for a new endpoint
|
|
123
|
+
|
|
124
|
+
1. TMF spec exists? Copy & trim official OpenAPI, implement to match.
|
|
125
|
+
2. `<Resource>Resource` class with full annotations + operationIds; `<Resource>Dto` / `<Resource>CreateDto` with validation + `@RegisterForReflection`.
|
|
126
|
+
3. Error responses referenced to the shared TMF Error components.
|
|
127
|
+
4. fields/offset/limit on list operations; Location header on create.
|
|
128
|
+
5. Snapshot test: `/q/openapi` diff against committed contract.
|
|
Binary file
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: quarkus-sql-jdbc-agroal
|
|
3
|
+
description: Standard for executing SQL queries, updates, batches, and transactions in Quarkus WITHOUT Panache or any ORM — using the Agroal connection pool with plain JDBC (default) or the reactive Vert.x SQL client (justified cases only). Use this skill whenever the user writes or reviews ANY repository, DAO, SQL statement, SELECT/INSERT/UPDATE/DELETE, batch operation, transaction, pagination query, jsonb access, connection pool configuration, or mentions Agroal, JDBC, PreparedStatement, datasource, or "query the database" — all persistence code must follow these patterns, including repository/adapter/row-mapper naming.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SQL Execution Standard: Agroal + Plain JDBC (No ORM)
|
|
7
|
+
|
|
8
|
+
Applies to any Quarkus backend project; project directives (CLAUDE.md, ADRs, explicit instructions) override these defaults where they conflict.
|
|
9
|
+
|
|
10
|
+
Persistence is explicit SQL through the Agroal pool. No Panache, no Hibernate, no reflection-based row mappers. Repositories are adapters in `infrastructure/persistence` implementing outbound ports (see quarkus-hexagonal-core skill).
|
|
11
|
+
|
|
12
|
+
One clarification to keep teams from chasing ghosts: **Agroal is a JDBC (blocking) pool** — there is no "reactive Agroal". The reactive path in Quarkus is the Vert.x SQL client (`quarkus-reactive-pg-client`) with its own pool. Default choice here is **Agroal + JDBC** (simpler, dominant skill base, works perfectly in native); reactive client only for measured hot paths with extreme concurrency (see §7).
|
|
13
|
+
|
|
14
|
+
## 1. Datasource configuration (Agroal)
|
|
15
|
+
|
|
16
|
+
```properties
|
|
17
|
+
quarkus.datasource.db-kind=postgresql
|
|
18
|
+
quarkus.datasource.username=${DB_USER}
|
|
19
|
+
quarkus.datasource.password=${DB_PASSWORD}
|
|
20
|
+
quarkus.datasource.jdbc.url=jdbc:postgresql://${DB_HOST}:5432/${DB_NAME}
|
|
21
|
+
|
|
22
|
+
# Pool sizing: start small; size = concurrent transactions, NOT concurrent users
|
|
23
|
+
quarkus.datasource.jdbc.min-size=2
|
|
24
|
+
quarkus.datasource.jdbc.max-size=16
|
|
25
|
+
quarkus.datasource.jdbc.acquisition-timeout=5S
|
|
26
|
+
|
|
27
|
+
# Hygiene
|
|
28
|
+
quarkus.datasource.jdbc.validation-query-sql=SELECT 1
|
|
29
|
+
quarkus.datasource.jdbc.leak-detection-interval=60S
|
|
30
|
+
quarkus.datasource.jdbc.idle-removal-interval=5M
|
|
31
|
+
quarkus.datasource.jdbc.max-lifetime=30M
|
|
32
|
+
|
|
33
|
+
# Observability (pairs with quarkus-observability-otel skill)
|
|
34
|
+
quarkus.datasource.jdbc.telemetry=true
|
|
35
|
+
quarkus.datasource.metrics.enabled=true
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Rules:
|
|
39
|
+
- `max-size` per pod must respect the DB's `max_connections` budget across ALL replicas of ALL services. Coordinate with DBAs; 16 is a ceiling, not a target.
|
|
40
|
+
- Leak detection stays on in every environment — a logged leak is a bug, treat it as such.
|
|
41
|
+
- Multiple datasources: named (`quarkus.datasource."audit".jdbc.url=...`) and injected with `@DataSource("audit")`.
|
|
42
|
+
|
|
43
|
+
## 2. Injection and the golden resource pattern
|
|
44
|
+
|
|
45
|
+
Inject the pool, never raw drivers, never `DriverManager`:
|
|
46
|
+
|
|
47
|
+
```java
|
|
48
|
+
@ApplicationScoped
|
|
49
|
+
public class JdbcUserRepository implements UserRepository {
|
|
50
|
+
|
|
51
|
+
private final AgroalDataSource ds;
|
|
52
|
+
public JdbcUserRepository(AgroalDataSource ds) { this.ds = ds; }
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Every statement uses **try-with-resources on Connection, PreparedStatement AND ResultSet** — this is what returns connections to the pool. A missed close under load exhausts the pool and takes the native pod down:
|
|
57
|
+
|
|
58
|
+
```java
|
|
59
|
+
private static final String FIND_BY_ID = """
|
|
60
|
+
SELECT id, email, status, created_at
|
|
61
|
+
FROM app_user
|
|
62
|
+
WHERE id = ?
|
|
63
|
+
""";
|
|
64
|
+
|
|
65
|
+
@Override
|
|
66
|
+
public Optional<User> findById(UserId id) {
|
|
67
|
+
try (var con = ds.getConnection();
|
|
68
|
+
var ps = con.prepareStatement(FIND_BY_ID)) {
|
|
69
|
+
ps.setObject(1, id.value());
|
|
70
|
+
try (var rs = ps.executeQuery()) {
|
|
71
|
+
return rs.next() ? Optional.of(mapRow(rs)) : Optional.empty();
|
|
72
|
+
}
|
|
73
|
+
} catch (SQLException e) {
|
|
74
|
+
throw translate("user.find_by_id", e);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Absolute rules:
|
|
80
|
+
- SQL as `private static final String` text blocks. Never concatenate user input — `PreparedStatement` placeholders ALWAYS (SQL injection + plan cache).
|
|
81
|
+
- Dynamic WHERE clauses: build from a whitelist of column/operator constants, values still as placeholders.
|
|
82
|
+
- One private `mapRow(ResultSet) -> Entity` per repository (or a `RowMapper<T>` functional interface shared via a tiny helper — see §6). No reflection mappers: they break native and hide cost.
|
|
83
|
+
|
|
84
|
+
Naming (canonical rules in the quarkus-hexagonal-core skill):
|
|
85
|
+
|
|
86
|
+
| Artifact | Convention | Example |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| Outbound port | `<Entity>Repository`, in `application/port/out` | `UserRepository` |
|
|
89
|
+
| JDBC adapter | `Jdbc<Port>`, in `infrastructure/persistence` | `JdbcUserRepository` |
|
|
90
|
+
| Shared row mapper | `<Entity>RowMapper` (private `mapRow` when not shared) | `UserRowMapper` |
|
|
91
|
+
| SQL constant | `UPPER_SNAKE_CASE` verb-first `private static final String` | `FIND_BY_ID`, `INSERT_USER` |
|
|
92
|
+
| Table / column | `snake_case`, singular table name | `app_user`, `created_at` |
|
|
93
|
+
| Technical exception | `PersistenceException` + specific subtypes (§8) | `TransientPersistenceException` |
|
|
94
|
+
|
|
95
|
+
Never name a repository `*Dao`, `*Manager` or `*Service` — `*Service` is reserved for use-case implementations, and a repository that grows business logic is a use case in disguise.
|
|
96
|
+
|
|
97
|
+
## 3. Transactions: on the use case, not the repository
|
|
98
|
+
|
|
99
|
+
The unit of work is the business operation. Annotate the **application-layer use case**:
|
|
100
|
+
|
|
101
|
+
```java
|
|
102
|
+
@ApplicationScoped
|
|
103
|
+
public class RegisterUserService implements RegisterUserUseCase { // impl = *Service, port = *UseCase
|
|
104
|
+
|
|
105
|
+
@Transactional
|
|
106
|
+
public UserId register(RegisterUserCommand cmd) {
|
|
107
|
+
var user = User.register(cmd); // domain
|
|
108
|
+
userRepository.save(user); // same tx
|
|
109
|
+
eventPublisher.publish(new UserRegistered(user.id())); // same tx (outbox insert)
|
|
110
|
+
return user.id();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
With `@Transactional` active, Agroal enlists the connection in the JTA transaction automatically — repositories keep using `ds.getConnection()` and all writes inside the use case share one transaction, committed/rolled back together. This is exactly what the outbox pattern requires (see quarkus-kafka-messaging skill).
|
|
116
|
+
|
|
117
|
+
- Runtime exceptions roll back by default; domain exceptions extend `RuntimeException`, so throwing them rolls back — correct by construction.
|
|
118
|
+
- Programmatic control when annotations don't fit (loops with per-item commit, batch jobs):
|
|
119
|
+
|
|
120
|
+
```java
|
|
121
|
+
QuarkusTransaction.requiringNew().timeout(30).run(() -> { ...repos... });
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
- Never call `con.commit()`/`setAutoCommit()` manually inside JTA-managed code paths.
|
|
125
|
+
- Read-only single queries need no `@Transactional` (auto-commit read is fine); multi-read consistency or any write → transaction.
|
|
126
|
+
|
|
127
|
+
## 4. Updates, inserts, upserts, generated keys
|
|
128
|
+
|
|
129
|
+
```java
|
|
130
|
+
private static final String INSERT = """
|
|
131
|
+
INSERT INTO app_user (id, email, status, created_at)
|
|
132
|
+
VALUES (?, ?, ?, ?)
|
|
133
|
+
ON CONFLICT (email) DO NOTHING
|
|
134
|
+
""";
|
|
135
|
+
|
|
136
|
+
@Override
|
|
137
|
+
public void save(User u) {
|
|
138
|
+
try (var con = ds.getConnection(); var ps = con.prepareStatement(INSERT)) {
|
|
139
|
+
ps.setObject(1, u.id().value());
|
|
140
|
+
ps.setString(2, u.email().value());
|
|
141
|
+
ps.setString(3, u.status().name());
|
|
142
|
+
ps.setObject(4, u.createdAt());
|
|
143
|
+
if (ps.executeUpdate() == 0) throw new DuplicateEmailException(u.email());
|
|
144
|
+
} catch (SQLException e) {
|
|
145
|
+
throw translate("user.save", e);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
- Check `executeUpdate()` counts — 0 rows on an expected UPDATE is a bug or a concurrency signal, not a success.
|
|
151
|
+
- Prefer DB-generated values via `RETURNING` (Postgres) over `getGeneratedKeys()` when you need them: `INSERT ... RETURNING id` + `executeQuery()`.
|
|
152
|
+
- Optimistic locking: `version` column, `UPDATE ... WHERE id = ? AND version = ?`; 0 rows → `StaleVersionException` (domain) → 409 via the unified handler. Do NOT name it `ConcurrentModificationException` — it shadows `java.util.ConcurrentModificationException` and an accidental import turns the 409 mapping into a 500.
|
|
153
|
+
- Upserts: `ON CONFLICT ... DO UPDATE` explicitly; never SELECT-then-INSERT races.
|
|
154
|
+
|
|
155
|
+
## 5. Batches, pagination, jsonb
|
|
156
|
+
|
|
157
|
+
**Batch** (bulk inserts/updates — outbox relays, imports):
|
|
158
|
+
|
|
159
|
+
```java
|
|
160
|
+
try (var con = ds.getConnection(); var ps = con.prepareStatement(INSERT)) {
|
|
161
|
+
for (var item : items) {
|
|
162
|
+
bind(ps, item);
|
|
163
|
+
ps.addBatch();
|
|
164
|
+
}
|
|
165
|
+
ps.executeBatch(); // add ?reWriteBatchedInserts=true to the JDBC URL (Postgres)
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Chunk batches (500–1000) inside long jobs; combine with `QuarkusTransaction` per chunk.
|
|
170
|
+
|
|
171
|
+
**Pagination**: keyset over OFFSET for anything user-facing/deep:
|
|
172
|
+
|
|
173
|
+
```sql
|
|
174
|
+
SELECT ... FROM app_user WHERE (created_at, id) < (?, ?) ORDER BY created_at DESC, id DESC LIMIT ?
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
OFFSET/LIMIT acceptable for TMF `offset/limit` list operations with bounded depth; when aggregations are involved, paginate FIRST in a CTE, then join/aggregate over the page — never aggregate the full set and paginate last.
|
|
178
|
+
|
|
179
|
+
**jsonb** (audit `context`, outbox `payload` — see observability/kafka skills):
|
|
180
|
+
|
|
181
|
+
```java
|
|
182
|
+
var pgo = new org.postgresql.util.PGobject();
|
|
183
|
+
pgo.setType("jsonb");
|
|
184
|
+
pgo.setValue(json); // serialized with Jackson/JsonObject, never string-built
|
|
185
|
+
ps.setObject(5, pgo);
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Read side: `rs.getString("context")` then parse. Index jsonb lookups you actually query (`(context->>'trace_id')`).
|
|
189
|
+
|
|
190
|
+
## 6. A tiny helper is allowed; a framework is not
|
|
191
|
+
|
|
192
|
+
To kill boilerplate, ONE small internal helper class (~50 lines) per service or shared lib is the sanctioned maximum:
|
|
193
|
+
|
|
194
|
+
```java
|
|
195
|
+
public final class Jdbc {
|
|
196
|
+
@FunctionalInterface public interface RowMapper<T> { T map(ResultSet rs) throws SQLException; }
|
|
197
|
+
|
|
198
|
+
public static <T> Optional<T> queryOne(DataSource ds, String sql, RowMapper<T> m, Object... params) { ... }
|
|
199
|
+
public static <T> List<T> queryList(DataSource ds, String sql, RowMapper<T> m, Object... params) { ... }
|
|
200
|
+
public static int update(DataSource ds, String sql, Object... params) { ... }
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
- Pure delegation to the try-with-resources pattern above; no reflection, no annotations, no SQL generation. If someone proposes adding criteria builders or entity mapping to it, that's an ORM growing back — reject.
|
|
205
|
+
- The class is named `Jdbc` — a namespace, not `JdbcUtils`/`JdbcHelper`. The banned-suffix ArchUnit rule (see quarkus-hexagonal-core skill) exists precisely to stop this class from becoming a junk drawer.
|
|
206
|
+
- jOOQ (code-gen, type-safe SQL) MAY be evaluated as an alternative via formal ADR; MyBatis/Hibernate remain excluded.
|
|
207
|
+
|
|
208
|
+
## 7. Blocking model: worker threads or virtual threads (and when reactive)
|
|
209
|
+
|
|
210
|
+
JDBC blocks. Never run it on the event loop:
|
|
211
|
+
|
|
212
|
+
- Quarkus REST resources are blocking by default when returning plain types — fine as-is.
|
|
213
|
+
- Reactive signatures (`Uni`), Kafka consumers, gRPC: mark `@Blocking` or hop to a worker pool (see grpc/kafka skills).
|
|
214
|
+
- **Virtual threads**: `@RunOnVirtualThread` on JDBC-heavy endpoints is the modern default for high-concurrency blocking work (Java 25 baseline; synchronized-block pinning is fixed since JDK 24) — cheap threads, same simple code. Caveat: keep pool `max-size` as the real ceiling; virtual threads make it easy to pile up on `acquisition-timeout`.
|
|
215
|
+
- **Reactive SQL client** (`quarkus-reactive-pg-client`, Vert.x pool — NOT Agroal): only for measured hot paths (extreme fan-in, streaming thousands of rows). It's a different programming model and a second pool to size; adopting it in a service requires an ADR. Do not mix both models in the same repository class.
|
|
216
|
+
|
|
217
|
+
## 8. SQLException translation
|
|
218
|
+
|
|
219
|
+
One translator in `infrastructure/persistence`, mapping SQLState to domain/persistence exceptions so callers never see `SQLException`:
|
|
220
|
+
|
|
221
|
+
| SQLState | Meaning | Throw |
|
|
222
|
+
|---|---|---|
|
|
223
|
+
| `23505` | unique violation | domain conflict exception (→ 409) |
|
|
224
|
+
| `23503` | FK violation | domain integrity exception |
|
|
225
|
+
| `40001` / `40P01` | serialization failure / deadlock | retryable `TransientPersistenceException` |
|
|
226
|
+
| `57014` | statement timeout/cancel | `PersistenceTimeoutException` |
|
|
227
|
+
| other | infrastructure failure | `PersistenceException(code, e)` (→ 500) |
|
|
228
|
+
|
|
229
|
+
Set `statement_timeout` (session or per-datasource via `quarkus.datasource.jdbc.additional-jdbc-properties.options=-c statement_timeout=5000`) so runaway queries fail fast instead of holding pool connections.
|
|
230
|
+
|
|
231
|
+
## 9. Testing
|
|
232
|
+
|
|
233
|
+
- Repository tests: `@QuarkusTest` + Dev Services (Testcontainers Postgres starts automatically — no config). Real SQL against real Postgres; never H2 (dialect lies).
|
|
234
|
+
- Flyway migrations run at test start (`quarkus.flyway.migrate-at-start=true`) — tests validate DDL and queries together.
|
|
235
|
+
- Native verification: `@QuarkusIntegrationTest` re-runs the same tests against the binary.
|
|
236
|
+
|
|
237
|
+
## Checklist for a new repository method
|
|
238
|
+
|
|
239
|
+
0. Names follow the canonical table above (`Jdbc<Port>` adapter, `<Entity>Repository` port, `UPPER_SNAKE` SQL constants).
|
|
240
|
+
1. SQL text block constant, placeholders only; whitelist for any dynamic fragment.
|
|
241
|
+
2. try-with-resources on connection/statement/resultset (or the `Jdbc` helper).
|
|
242
|
+
3. Transaction boundary on the use case, not here.
|
|
243
|
+
4. `executeUpdate()` count checked; SQLState translated, never leaked.
|
|
244
|
+
5. jsonb via `PGobject`; batch + chunking for bulk; keyset pagination if deep.
|
|
245
|
+
6. `@Blocking`/virtual thread if called from a reactive context; Dev Services test written.
|
|
Binary file
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module,skill,display-name,menu-code,description,action,args,phase,preceded-by,followed-by,required,output-location,outputs
|
|
2
|
+
BMad Method,_meta,,,,,,,,,false,https://docs.bmad-method.org/llms.txt,
|
|
3
|
+
BMad Method,bmad-project-context,Project Context,PC,"Set up or refresh a repo's agent instructions so AI agents work well in it: verified commands, policy, conventions that differ from defaults, and known pitfalls. Setup, refresh, record, and audit — replaces document-project and generate-project-context.",,,anytime,,,false,repo root,AGENTS.md managed block
|
|
4
|
+
BMad Method,bmad-build,Build,BD,Official Phase 4 implementation loop: clarify intent plan implement review and present.,,,ship,bmad-sprint-planning,bmad-code-review,true,implementation_artifacts,spec and project implementation
|
|
5
|
+
BMad Method,bmad-spec,Spec,SPC,"Use to distill any intent input (brief, PRD, transcript, brain dump, design folder, mixed multi-source) into a succinct, no-fluff SPEC.md contract + companions that downstream work derives from. Locks the WHAT before the HOW. Works for software, game design, research, editorial, policy, business, anything intent-bearing. Validation mode also available.",,[path],anytime,,,false,{output_folder}/specs/spec-{slug},SPEC.md + companion files
|
|
6
|
+
BMad Method,bmad-correct-course,Correct Course,CC,Navigate significant changes. May recommend start over update PRD redo architecture sprint planning or correct epics and stories.,,,anytime,,,false,planning_artifacts,change proposal
|
|
7
|
+
BMad Method,bmad-brainstorming,Brainstorm Project,BP,Expert guided facilitation through a single or multiple techniques.,,,plan,,,false,{output_folder}/brainstorming,brainstorming session
|
|
8
|
+
BMad Method,bmad-product-brief,Create Brief,CB,An expert guided experience to nail down your product idea in a brief. a gentler approach than PRFAQ when you are already sure of your concept and nothing will sway you.,,-A,plan,,,false,planning_artifacts,product brief
|
|
9
|
+
BMad Method,bmad-prfaq,PRFAQ Challenge,WB,Working Backwards guided experience to forge and stress-test your product concept to ensure you have a great product that users will love and need through the PRFAQ gauntlet to determine feasibility and alignment with user needs. alternative to product brief.,,-H,plan,,,false,planning_artifacts,prfaq document
|
|
10
|
+
BMad Method,bmad-prd,Create Edit and Review PRD,PRD,"Facilitated PRD workflow — create a new PRD via coached discovery, update an existing one against a change signal, or validate a finished PRD against a checklist with an HTML findings report.",,,2-planning,bmad-product-brief,,true,planning_artifacts,prd
|
|
11
|
+
BMad Method,bmad-ux,Create UX,CU,"Guidance through realizing the plan for your UX, strongly recommended if a UI is a primary piece of the proposed project.",,,2-planning,bmad-prd,,false,planning_artifacts,ux design
|
|
12
|
+
BMad Method,bmad-architecture,Architecture,CA,Offer once requirements exist (a PRD or spec; plus UX if present) and the user is ready to move from what to how. Also offer any time independently-built parts risk diverging. Produces the architecture spine: the invariants that keep features epics and stories consistent. Comes before epics and stories and scales from a quick spine to a full architecture (brownfield: ratifies the existing codebase).,,,plan,,,true,planning_artifacts,architecture
|
|
13
|
+
BMad Method,bmad-create-epics-and-stories,Create Epics and Stories,CE,,,,plan,bmad-architecture,,true,planning_artifacts,epics and stories
|
|
14
|
+
BMad Method,bmad-sprint-planning,Sprint Planning,SP,Readiness gate then tracking: verifies the planning is implementable (PASS/CONCERNS/FAIL) and produces the sprint status the implementation agents follow for every story.,,,plan,,,true,implementation_artifacts,sprint status
|
|
15
|
+
BMad Method,bmad-sprint-planning,Sprint Status,SS,Anytime: summarize sprint status with risks open action items and the next recommended action; can also validate or repair the tracking file.,status,,anytime,,,false,,status summary
|
|
16
|
+
BMad Method,bmad-code-review,Code Review,CR,Ad hoc review of any code change. Optional extra layer after Build's built-in review.,,,ship,bmad-build,,false,,
|
|
17
|
+
BMad Method,bmad-checkpoint-preview,Checkpoint,CK,Guided walkthrough of a change from purpose and context into details. Use for human review of commits branches or PRs.,,,ship,,,false,,
|
|
18
|
+
BMad Method,bmad-qa-generate-e2e-tests,QA Automation Test,QA,Generate automated API and E2E tests for implemented code. NOT for code review or story validation — use CR for that.,,,ship,bmad-build,,false,implementation_artifacts,test suite
|
|
19
|
+
BMad Method,bmad-retrospective,Retrospective,ER,Optional at epic end: Review completed work lessons learned and next epic or if major issues consider CC.,,,ship,bmad-code-review,,false,implementation_artifacts,retrospective
|