docs/es/skills/springboot-verification/SKILL.md
Bucle de verificación para proyectos Spring Boot: build, análisis estático, pruebas con cobertura, escaneos de seguridad y revisión de diff antes del lanzamiento o PR.
npx skillsauth add affaan-m/everything-claude-code springboot-verificationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Ejecutar antes de PRs, después de cambios importantes y antes del despliegue.
mvn -T 4 clean verify -DskipTests
# o
./gradlew clean assemble -x test
Si el build falla, detener y corregir.
Maven (plugins comunes):
mvn -T 4 spotbugs:check pmd:check checkstyle:check
Gradle (si está configurado):
./gradlew checkstyleMain pmdMain spotbugsMain
mvn -T 4 test
mvn jacoco:report # verificar cobertura 80%+
# o
./gradlew test jacocoTestReport
Reporte:
Probar la lógica del servicio en aislamiento con dependencias mockeadas:
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock private UserRepository userRepository;
@InjectMocks private UserService userService;
@Test
void createUser_validInput_returnsUser() {
var dto = new CreateUserDto("Alice", "[email protected]");
var expected = new User(1L, "Alice", "[email protected]");
when(userRepository.save(any(User.class))).thenReturn(expected);
var result = userService.create(dto);
assertThat(result.name()).isEqualTo("Alice");
verify(userRepository).save(any(User.class));
}
@Test
void createUser_duplicateEmail_throwsException() {
var dto = new CreateUserDto("Alice", "[email protected]");
when(userRepository.existsByEmail(dto.email())).thenReturn(true);
assertThatThrownBy(() -> userService.create(dto))
.isInstanceOf(DuplicateEmailException.class);
}
}
Probar contra una base de datos real en lugar de H2:
@SpringBootTest
@Testcontainers
class UserRepositoryIntegrationTest {
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine")
.withDatabaseName("testdb");
@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
}
@Autowired private UserRepository userRepository;
@Test
void findByEmail_existingUser_returnsUser() {
userRepository.save(new User("Alice", "[email protected]"));
var found = userRepository.findByEmail("[email protected]");
assertThat(found).isPresent();
assertThat(found.get().getName()).isEqualTo("Alice");
}
}
Probar la capa controller con el contexto completo de Spring:
@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired private MockMvc mockMvc;
@MockBean private UserService userService;
@Test
void createUser_validInput_returns201() throws Exception {
var user = new UserDto(1L, "Alice", "[email protected]");
when(userService.create(any())).thenReturn(user);
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content("""
{"name": "Alice", "email": "[email protected]"}
"""))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.name").value("Alice"));
}
@Test
void createUser_invalidEmail_returns400() throws Exception {
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content("""
{"name": "Alice", "email": "not-an-email"}
"""))
.andExpect(status().isBadRequest());
}
}
# CVEs de dependencias
mvn org.owasp:dependency-check-maven:check
# o
./gradlew dependencyCheckAnalyze
# Secretos en código fuente
grep -rn "password\s*=\s*\"" src/ --include="*.java" --include="*.yml" --include="*.properties"
grep -rn "sk-\|api_key\|secret" src/ --include="*.java" --include="*.yml"
# Secretos (historial de git)
git secrets --scan # si está configurado
# Verificar System.out.println (usar logger en su lugar)
grep -rn "System\.out\.print" src/main/ --include="*.java"
# Verificar mensajes de excepción en bruto en respuestas
grep -rn "e\.getMessage()" src/main/ --include="*.java"
# Verificar CORS comodín
grep -rn "allowedOrigins.*\*" src/main/ --include="*.java"
mvn spotless:apply # si se usa el plugin Spotless
./gradlew spotlessApply
git diff --stat
git diff
Lista de verificación:
System.out, log.debug sin guardias)REPORTE DE VERIFICACIÓN
=======================
Build: [PASS/FAIL]
Estático: [PASS/FAIL] (spotbugs/pmd/checkstyle)
Pruebas: [PASS/FAIL] (X/Y pasadas, Z% cobertura)
Seguridad: [PASS/FAIL] (hallazgos CVE: N)
Diff: [X archivos modificados]
General: [LISTO / NO LISTO]
Problemas a Corregir:
1. ...
2. ...
mvn -T 4 test + spotbugs para retroalimentación rápidaRecuerda: La retroalimentación rápida supera las sorpresas tardías. Mantener la compuerta estricta — tratar las advertencias como defectos en sistemas de producción.
development
Share durable, inspectable context and handoffs between Claude, Codex, Hermes, Cursor, OpenCode, and other agents through the local ECC Memory Vault. Use when an agent must save work state, transfer context, resume another agent's task, or search shared project knowledge.
development
Use when multiple consumers and providers must evolve an API or event schema without field drift, integration surprises, or one side silently redefining the interface.
tools
Query live GPU inventory, submit an authenticated Itô fixed-rate RFQ, inspect RFQ or procurement status, and run explicitly gated node qualification through the separately installed canonical CLI. Use when a user asks to find H100/H200 capacity, request a fixed compute rate, check Itô compute status, or validate GPU nodes.
data-ai
Instinct-based learning system that observes sessions via hooks, creates atomic instincts with confidence scoring, and evolves them into skills/commands/agents. v2.1 adds project-scoped instincts to prevent cross-project contamination.