perl-testing
Perl testing patterns using Test2::V0, Test::More, prove runner, mocking, coverage with Devel::Cover, and TDD methodology.
- License 许可
- Apache-2.0
- 最近更新
- 2026-11-08
- Stars
- ★ 0
- Forks
- 0
01 前言 Front Matter
- name
- be-init
- description
- Initialize Backend WebFlux Plugin configuration for the current project.
- allowed-tools
- Read, Write, Glob, Bash
- argument-hint
- user-invocable
- true
03 SKILL.md 正文
Initialize Backend WebFlux Plugin
Set up the Backend WebFlux Plugin configuration for this project.
Instructions
Step 1: Check Existing Configuration
pluginRoot: the one line of${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plugins/data/backend-webflux-plugin/pluginRoot(plugin CLAUDE.md § Configuration) — everytemplates/…path in this document is{pluginRoot}/templates/…. Missing → do not stop: initialization needs no template (only Step 2 item 9's optional checkstyle offer does — skip that offer); record that it is missing for Step 7.- Check if
.claude/backend-webflux-plugin.jsonalready exists in the current project directory - If it exists, read the current configuration and show it to the user:
"Backend WebFlux Plugin is already configured:"
{ current config contents }"Do you want to reconfigure? This will overwrite the existing settings."
- If the user declines, stop here
Step 2: Auto-Detect Project Settings
Scan the project to detect settings automatically:
- Build tool: Look for
build.gradle.kts(gradle-kotlin) orbuild.gradle(gradle-groovy). Apom.xmlwith neither → stop, write no config: every gate row in this plugin is a Gradle task (classes,checkstyleMain,jacocoTestReport,--tests), so a Maven project would be configured "successfully" and fail every gate — say so and stop. - Java version: Parse whichever build file was detected in item 1:
build.gradle.kts(gradle-kotlin):java.toolchain.languageVersionorsourceCompatibilitybuild.gradle(gradle-groovy): same keys, Groovy syntax (sourceCompatibility = '21'orlanguageVersion = JavaLanguageVersion.of(21))- If the field can't be parsed from the detected build file, leave it undetected — do not guess a version from an unrelated file.
- Spring Boot version: Parse whichever build file was detected in item 1:
build.gradle.kts/build.gradle: theorg.springframework.bootentry in the plugins block- If the field can't be parsed from the detected build file, leave it undetected — do not guess a version from an unrelated file.
- Base package: Find the first directory level under
src/main/java/that contains.javafiles - Data profile: Check dependencies for
spring-boot-starter-data-r2dbc(→r2dbcpresent) andmybatis-spring-boot-starter(→mybatispresent; on Boot 4 it must be the4.xline — a3.0.xstarter is a Boot 3 artifact, so warn in Step 3 when the versions disagree). Both present →"both". Only one present → that profile. Neither present → default"both"(plugin default, seedocs/decisions.mdDecision 1) - Web layer: Check for
RouterFunctionbean definitions vs@RestControllerusage in existing source.- Project is empty (no source found yet) → default
"functional", no warning needed. - One style clearly dominates → that style wins, no warning needed.
- Both styles are present in meaningful numbers (mixed evenly) → do not silently default. Flag it in Step 3 as a warning: the existing source shows both
RouterFunctionand@RestControllerusage, and per this plugin's architecture rule a domain must never mix both styles (seeCLAUDE.md§ Web Layer) — ask the user which style to standardize on for new code rather than picking"functional"for them.
- Project is empty (no source found yet) → default
- Database: Check dependencies for
mysql-connector-j/io.asyncer:r2dbc-mysql(mysql, default) orh2(the sample's stand-in). Anio.asyncer:r2dbc-mysqlbelow1.4.2is a Boot-3 line — warn in Step 3 (the same way item 5 warns on a 3.0.x MyBatis starter);be-crudStep 3 stops on it. Any other vendor's driver (PostgreSQL, MariaDB, …) → stop, write no config:be-crudemits MySQL DDL and requires the MySQL drivers, so the project would be configured and then given SQL its database rejects - Migration: Check for a
src/main/resources/migration/directory (manual-sql, default) or a migration-runner dependency (only if the project has explicitly opted into one). A runner changes nothing about generation —be-crudalways writes plain SQL undersrc/main/resources/migration/and never registers it — so warn in Step 3: a Flyway project points its runner there (spring.flyway.locations=classpath:migration), a Liquibase project includes each file in its changelog itself - Checkstyle:
truewhen thecheckstyleplugin is applied in the build file. If it is applied butconfig/checkstyle/checkstyle.xmlis missing, offer to write the file fromtemplates/checkstyle-config.md(that is the only place it is scaffolded; without itcheckstyleMainfails on a missing config). A project that has its own file keeps it — the reviewer judges by the project's file - Coverage:
trueonly when thejacocoplugin is applied in the build file. Nothing in this plugin adds it, and withcoverage: trueon a project without itbe-verify's Coverage row fails (jacocoTestReportnot found) and so doesOverall— on every run. Absent →false, and tell the user in Step 3 how to enable it: the Gradle block intemplates/coverage-gate.md, then re-runbe-init - Lombok: Check if
lombokis in dependencies - Gradle command:
./gradlewwhen the wrapper exists, elsegradle— the invocation every task-level gate row (classes,checkstyleMain,jacocoTestReport,--tests) is built on. No build file at all (fresh repository):./gradlew— Spring Initializr ships the wrapper, and agradlebaked in now would run the system Gradle (absent, or a different version) against the project created next. Appending a task to the build command would run the fullbuildevery time and misattribute one failure to every row - Build command:
{gradleCommand} build - Test command:
{gradleCommand} test
Step 3: Confirm with User
Present detected values and ask the user to confirm or override:
"Detected project settings:"
Java Version: {detected or "21"} Spring Boot: {detected or "unknown"} Build Tool: {detected} Base Package: {detected or "com.example"} Data Profile: {detected or "both"} (r2dbc | mybatis | both — see docs/decisions.md) Web Layer: {detected or "functional"} (functional | annotated) Database: {detected or "mysql"} Migration: {detected or "manual-sql"} Checkstyle: {detected or false} Coverage: {detected or false} (report-only JaCoco gate — see docs/decisions.md Decision 6) Lombok: {detected or false} Architecture: cqrs (default) Work Doc Dir: work/features (default) Working Language: en (default)"Would you like to change any of these values?"
If the user wants changes, ask for specific values. Accept the following for architecture: cqrs (default).
For working language, accept: en (English), ko (Korean), vi (Vietnamese).
Worked example — clean detection
A project with build.gradle.kts, spring-boot-starter-data-r2dbc only, no
@RestController usage, and io.asyncer:r2dbc-mysql in dependencies produces:
"Detected project settings:"
Java Version: 21 Spring Boot: 4.0.2 Build Tool: gradle-kotlin Base Package: com.example.demo Data Profile: r2dbc (r2dbc | mybatis | both — see docs/decisions.md) Web Layer: functional (functional | annotated) Database: mysql Migration: manual-sql Checkstyle: true Coverage: true (report-only JaCoco gate — see docs/decisions.md Decision 6) Lombok: true Architecture: cqrs (default) Work Doc Dir: work/features (default) Working Language: en (default)"Would you like to change any of these values?"
The user replies "looks good" → proceed to Step 4 with these values as-is.
Worked example — edge cases
No build file present (fresh/empty repository): every build-file-derived field
(javaVersion, springBootVersion, buildTool, buildCommand, testCommand) has
no detected value. Present the plugin defaults explicitly instead of leaving fields
blank, and say so:
"No
build.gradle.ktsorbuild.gradlefound — this looks like a new project. Using plugin defaults below; correct any that don't match your plan. Note:be-crudscaffolds into an existing Spring Boot WebFlux project — it writes sources and a migration, not a build file, wrapper or application class. Create the project first (Spring Initializr: WebFlux + the starters for your data profile —spring-boot-starter-data-r2dbc+io.asyncer:r2dbc-mysql:1.4.3, and/ormybatis-spring-boot-starter:4.x+mysql-connector-j— pluscom.github.f4b6a3:uuid-creator, and the test starters the generated tests compile against:spring-boot-starter-test,spring-boot-starter-webflux-test,reactor-test, andspring-boot-starter-data-r2dbc-test/mybatis-spring-boot-starter-test), then runbe-crud:"Java Version: 21 (default, undetected) Spring Boot: 4.0.2 (default, undetected) Build Tool: gradle-kotlin (default, undetected) Gradle Command: ./gradlew (Initializr ships the wrapper) ...
Mixed web-layer usage (per Step 2 item 6): do not silently pick "functional".
Surface the conflict before presenting the confirmation table:
"Note: existing source under
src/main/java/shows bothRouterFunctionbeans and@RestControllerclasses in roughly equal numbers. This plugin's rule is that a domain must never mix both styles (seeCLAUDE.md§ Web Layer). Which style should new code use —functionalorannotated?"
Only after the user answers does webLayer get a value in the confirmation table;
do not default it in this case.
Step 4: Write Configuration
Write .claude/backend-webflux-plugin.json:
{
"javaVersion": "{value}",
"springBootVersion": "{value}",
"buildTool": "{value}",
"gradleCommand": "{value}",
"buildCommand": "{value}",
"testCommand": "{value}",
"basePackage": "{value}",
"sourceDir": "src/main/java",
"testDir": "src/test/java",
"architecture": "{value}",
"dataProfile": "{value}",
"webLayer": "{value}",
"database": "{value}",
"migration": "{value}",
"checkstyle": {value},
"coverage": {value},
"lombokEnabled": {value},
"workDocDir": "{value}",
"workingLanguage": "{value}"
}
(No pluginRoot key: the plugin's install directory is read by the gate skills from
${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plugins/data/backend-webflux-plugin/pluginRoot, which the
SessionStart hook rewrites at every session start — a copy here would go stale on upgrade. If that
file is missing now, say so in Step 7.)
After the Write tool call returns, read .claude/backend-webflux-plugin.json back and
confirm its contents match what was just written. This is the evidence Step 7's
success message relies on — do not skip it. If the write failed or the read-back
doesn't match, stop and report the error instead of proceeding to Step 5.
Step 5: Set Up Work Document Directory
- If
{workDocDir}does not exist, create it
Step 6: Add Gradle Permission
Check .claude/settings.json for Bash permissions. If {gradleCommand} * is not in the allow list, inform the user (./gradlew * for a wrapper project, gradle * when gradleCommand is gradle — an entry for the wrong one covers none of the gate commands):
"To enable Gradle commands, add this to your
.claude/settings.jsonpermissions.allow:""Bash({gradleCommand} *)"
Step 7: Confirmation
Only reached if the Step 4 read-back succeeded. Display final configuration summary:
"Backend WebFlux Plugin initialized successfully." "Configuration saved to
.claude/backend-webflux-plugin.json." "Data profile: {dataProfile}. Web layer: {webLayer}. Seedocs/decisions.mdif you want the rationale behind these defaults before changing them." {When${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plugins/data/backend-webflux-plugin/pluginRootis missing: "The SessionStart hook has not recorded the plugin's install path — start a new session once beforebe-verify/be-review/be-commit."}"Available skills:"
Core pipeline:
/backend-webflux-plugin:be-plan— Spec → backend plan.json/backend-webflux-plugin:be-crud— CQRS CRUD scaffold/backend-webflux-plugin:be-code— TDD feature implementation/backend-webflux-plugin:be-verify— Verification gate (build + checkstyle + tests + coverage)/backend-webflux-plugin:be-review— Multi-dimension code review/backend-webflux-plugin:be-fix— TDD-disciplined review fix/backend-webflux-plugin:be-commit— Smart commitUtility:
/backend-webflux-plugin:be-build— Build + auto-fix/backend-webflux-plugin:be-debug— Systematic debugging/backend-webflux-plugin:be-recall— Rules reference/backend-webflux-plugin:be-progress— Progress dashboardStandalone audits:
/backend-webflux-plugin:be-data— R2DBC / MyBatis data-layer audit/backend-webflux-plugin:be-api-review— API contract audit/backend-webflux-plugin:be-clean-code— Clean code audit/backend-webflux-plugin:be-logging— Logging audit/backend-webflux-plugin:be-test-review— Test quality audit/backend-webflux-plugin:be-security— Security audit/backend-webflux-plugin:be-integrate-review— Vendor/outbound-integration audit
04 同仓库更多 Skills
remotion-video-creation
Best practices for Remotion - Video creation in React. 29 domain-specific rules covering 3D, animations, audio, captions, charts, transitions, and more.
hotcook-recipes
暂无简介
code-helper
Code review and assistance skill
research-assistant
Web research assistant skill using Brave Search MCP
x-api
X/Twitter API integration for posting tweets, threads, reading timelines, search, and analytics. Covers OAuth auth patterns, rate limits, and platform-native content posting. Use when the user wants to interact with X programmatically.
workspace-surface-audit
Audit the active repo, MCP servers, plugins, connectors, env surfaces, and harness setup, then recommend the highest-value ECC-native skills, hooks, agents, and operator workflows. Use when the user wants help setting up Claude Code or understanding what capabilities are actually available in their environment.