@ahumandev/autocode 0.0.1
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/LICENSE.md +21 -0
- package/README.md +379 -0
- package/dist/agents/index.d.ts +25 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.test.d.ts +2 -0
- package/dist/agents/index.test.d.ts.map +1 -0
- package/dist/agents/prompts/assist.d.ts +2 -0
- package/dist/agents/prompts/assist.d.ts.map +1 -0
- package/dist/agents/prompts/assist_git_conflict.d.ts +2 -0
- package/dist/agents/prompts/assist_git_conflict.d.ts.map +1 -0
- package/dist/agents/prompts/assist_troubleshoot.d.ts +2 -0
- package/dist/agents/prompts/assist_troubleshoot.d.ts.map +1 -0
- package/dist/agents/prompts/auto.d.ts +2 -0
- package/dist/agents/prompts/auto.d.ts.map +1 -0
- package/dist/agents/prompts/auto_feature.d.ts +2 -0
- package/dist/agents/prompts/auto_feature.d.ts.map +1 -0
- package/dist/agents/prompts/auto_general.d.ts +2 -0
- package/dist/agents/prompts/auto_general.d.ts.map +1 -0
- package/dist/agents/prompts/auto_refactor.d.ts +2 -0
- package/dist/agents/prompts/auto_refactor.d.ts.map +1 -0
- package/dist/agents/prompts/auto_research.d.ts +2 -0
- package/dist/agents/prompts/auto_research.d.ts.map +1 -0
- package/dist/agents/prompts/auto_review_api.d.ts +2 -0
- package/dist/agents/prompts/auto_review_api.d.ts.map +1 -0
- package/dist/agents/prompts/auto_review_ui.d.ts +2 -0
- package/dist/agents/prompts/auto_review_ui.d.ts.map +1 -0
- package/dist/agents/prompts/auto_test.d.ts +2 -0
- package/dist/agents/prompts/auto_test.d.ts.map +1 -0
- package/dist/agents/prompts/auto_troubleshoot.d.ts +2 -0
- package/dist/agents/prompts/auto_troubleshoot.d.ts.map +1 -0
- package/dist/agents/prompts/design.d.ts +2 -0
- package/dist/agents/prompts/design.d.ts.map +1 -0
- package/dist/agents/prompts/document_agents.d.ts +2 -0
- package/dist/agents/prompts/document_agents.d.ts.map +1 -0
- package/dist/agents/prompts/document_code.d.ts +2 -0
- package/dist/agents/prompts/document_code.d.ts.map +1 -0
- package/dist/agents/prompts/document_conventions.d.ts +2 -0
- package/dist/agents/prompts/document_conventions.d.ts.map +1 -0
- package/dist/agents/prompts/document_install.d.ts +2 -0
- package/dist/agents/prompts/document_install.d.ts.map +1 -0
- package/dist/agents/prompts/document_prd.d.ts +2 -0
- package/dist/agents/prompts/document_prd.d.ts.map +1 -0
- package/dist/agents/prompts/document_ux.d.ts +2 -0
- package/dist/agents/prompts/document_ux.d.ts.map +1 -0
- package/dist/agents/prompts/execute_author.d.ts +2 -0
- package/dist/agents/prompts/execute_author.d.ts.map +1 -0
- package/dist/agents/prompts/execute_code.d.ts +2 -0
- package/dist/agents/prompts/execute_code.d.ts.map +1 -0
- package/dist/agents/prompts/execute_debug.d.ts +2 -0
- package/dist/agents/prompts/execute_debug.d.ts.map +1 -0
- package/dist/agents/prompts/execute_document.d.ts +2 -0
- package/dist/agents/prompts/execute_document.d.ts.map +1 -0
- package/dist/agents/prompts/execute_excel.d.ts +2 -0
- package/dist/agents/prompts/execute_excel.d.ts.map +1 -0
- package/dist/agents/prompts/execute_git_commit.d.ts +2 -0
- package/dist/agents/prompts/execute_git_commit.d.ts.map +1 -0
- package/dist/agents/prompts/execute_os.d.ts +2 -0
- package/dist/agents/prompts/execute_os.d.ts.map +1 -0
- package/dist/agents/prompts/execute_script.d.ts +2 -0
- package/dist/agents/prompts/execute_script.d.ts.map +1 -0
- package/dist/agents/prompts/query_architect.d.ts +2 -0
- package/dist/agents/prompts/query_architect.d.ts.map +1 -0
- package/dist/agents/prompts/query_browser.d.ts +2 -0
- package/dist/agents/prompts/query_browser.d.ts.map +1 -0
- package/dist/agents/prompts/query_code.d.ts +2 -0
- package/dist/agents/prompts/query_code.d.ts.map +1 -0
- package/dist/agents/prompts/query_db.d.ts +2 -0
- package/dist/agents/prompts/query_db.d.ts.map +1 -0
- package/dist/agents/prompts/query_excel.d.ts +2 -0
- package/dist/agents/prompts/query_excel.d.ts.map +1 -0
- package/dist/agents/prompts/query_git.d.ts +2 -0
- package/dist/agents/prompts/query_git.d.ts.map +1 -0
- package/dist/agents/prompts/query_os.d.ts +2 -0
- package/dist/agents/prompts/query_os.d.ts.map +1 -0
- package/dist/agents/prompts/query_text.d.ts +2 -0
- package/dist/agents/prompts/query_text.d.ts.map +1 -0
- package/dist/agents/prompts/query_web.d.ts +2 -0
- package/dist/agents/prompts/query_web.d.ts.map +1 -0
- package/dist/agents/prompts/research.d.ts +2 -0
- package/dist/agents/prompts/research.d.ts.map +1 -0
- package/dist/agents/prompts/temp_concept.d.ts +2 -0
- package/dist/agents/prompts/temp_concept.d.ts.map +1 -0
- package/dist/agents/prompts/temp_manual.d.ts +4 -0
- package/dist/agents/prompts/temp_manual.d.ts.map +1 -0
- package/dist/agents/prompts/temp_report.d.ts +2 -0
- package/dist/agents/prompts/temp_report.d.ts.map +1 -0
- package/dist/agents/rules/caveman.d.ts +2 -0
- package/dist/agents/rules/caveman.d.ts.map +1 -0
- package/dist/agents/rules/definitions.d.ts +2 -0
- package/dist/agents/rules/definitions.d.ts.map +1 -0
- package/dist/agents/rules/error.d.ts +2 -0
- package/dist/agents/rules/error.d.ts.map +1 -0
- package/dist/agents/rules/markdown.d.ts +2 -0
- package/dist/agents/rules/markdown.d.ts.map +1 -0
- package/dist/agents/rules/planner.d.ts +2 -0
- package/dist/agents/rules/planner.d.ts.map +1 -0
- package/dist/agents/rules/question.d.ts +2 -0
- package/dist/agents/rules/question.d.ts.map +1 -0
- package/dist/agents/rules/response.d.ts +2 -0
- package/dist/agents/rules/response.d.ts.map +1 -0
- package/dist/agents/rules/swap2assist.d.ts +2 -0
- package/dist/agents/rules/swap2assist.d.ts.map +1 -0
- package/dist/agents/rules/task.d.ts +2 -0
- package/dist/agents/rules/task.d.ts.map +1 -0
- package/dist/commands/index.d.ts +19 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.test.d.ts +2 -0
- package/dist/commands/index.test.d.ts.map +1 -0
- package/dist/config.d.ts +29 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.test.d.ts +2 -0
- package/dist/config.test.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/plugin.d.ts +4 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +30676 -0
- package/dist/plugin.test.d.ts +2 -0
- package/dist/plugin.test.d.ts.map +1 -0
- package/dist/skills/author-article/SKILL.md +116 -0
- package/dist/skills/author-caveman/SKILL.md +18 -0
- package/dist/skills/author-readme/SKILL.md +199 -0
- package/dist/skills/author-rules/SKILL.md +182 -0
- package/dist/skills/author-skill/SKILL.md +78 -0
- package/dist/skills/author-tutorial/SKILL.md +24 -0
- package/dist/skills/code-java/SKILL.md +345 -0
- package/dist/skills/code-rest/SKILL.md +82 -0
- package/dist/skills/code-typescript/SKILL.md +453 -0
- package/dist/skills/execute-sandbox/SKILL.md +42 -0
- package/dist/skills/test-jest/SKILL.md +211 -0
- package/dist/skills/test-junit/SKILL.md +206 -0
- package/dist/skills/test-mockito/SKILL.md +209 -0
- package/dist/skills/test-vitest/SKILL.md +159 -0
- package/dist/tools/autocode_agent_swap.d.ts +13 -0
- package/dist/tools/autocode_agent_swap.d.ts.map +1 -0
- package/dist/tools/autocode_agent_swap.test.d.ts +2 -0
- package/dist/tools/autocode_agent_swap.test.d.ts.map +1 -0
- package/dist/tools/autocode_concept_create.d.ts +23 -0
- package/dist/tools/autocode_concept_create.d.ts.map +1 -0
- package/dist/tools/autocode_concept_list.d.ts +14 -0
- package/dist/tools/autocode_concept_list.d.ts.map +1 -0
- package/dist/tools/autocode_concept_read.d.ts +20 -0
- package/dist/tools/autocode_concept_read.d.ts.map +1 -0
- package/dist/tools/autocode_criteria.d.ts +52 -0
- package/dist/tools/autocode_criteria.d.ts.map +1 -0
- package/dist/tools/autocode_criteria.test.d.ts +2 -0
- package/dist/tools/autocode_criteria.test.d.ts.map +1 -0
- package/dist/tools/autocode_db.d.ts +80 -0
- package/dist/tools/autocode_db.d.ts.map +1 -0
- package/dist/tools/autocode_db.test.d.ts +2 -0
- package/dist/tools/autocode_db.test.d.ts.map +1 -0
- package/dist/tools/autocode_dependencies.d.ts +4 -0
- package/dist/tools/autocode_dependencies.d.ts.map +1 -0
- package/dist/tools/autocode_dependencies.test.d.ts +2 -0
- package/dist/tools/autocode_dependencies.test.d.ts.map +1 -0
- package/dist/tools/autocode_job_execute.d.ts +14 -0
- package/dist/tools/autocode_job_execute.d.ts.map +1 -0
- package/dist/tools/autocode_job_execute.test.d.ts +2 -0
- package/dist/tools/autocode_job_execute.test.d.ts.map +1 -0
- package/dist/tools/autocode_job_list.d.ts +23 -0
- package/dist/tools/autocode_job_list.d.ts.map +1 -0
- package/dist/tools/autocode_job_list.test.d.ts +3 -0
- package/dist/tools/autocode_job_list.test.d.ts.map +1 -0
- package/dist/tools/autocode_job_status.d.ts +5 -0
- package/dist/tools/autocode_job_status.d.ts.map +1 -0
- package/dist/tools/autocode_job_status.test.d.ts +2 -0
- package/dist/tools/autocode_job_status.test.d.ts.map +1 -0
- package/dist/tools/autocode_logo_find.d.ts +10 -0
- package/dist/tools/autocode_logo_find.d.ts.map +1 -0
- package/dist/tools/autocode_plan_read.d.ts +12 -0
- package/dist/tools/autocode_plan_read.d.ts.map +1 -0
- package/dist/tools/autocode_plan_save.d.ts +48 -0
- package/dist/tools/autocode_plan_save.d.ts.map +1 -0
- package/dist/tools/autocode_sandbox_cli.d.ts +23 -0
- package/dist/tools/autocode_sandbox_cli.d.ts.map +1 -0
- package/dist/tools/autocode_sandbox_create.d.ts +16 -0
- package/dist/tools/autocode_sandbox_create.d.ts.map +1 -0
- package/dist/tools/autocode_sandbox_delete.d.ts +12 -0
- package/dist/tools/autocode_sandbox_delete.d.ts.map +1 -0
- package/dist/tools/autocode_sandbox_file_tools.d.ts +9 -0
- package/dist/tools/autocode_sandbox_file_tools.d.ts.map +1 -0
- package/dist/tools/autocode_sandbox_tools.test.d.ts +2 -0
- package/dist/tools/autocode_sandbox_tools.test.d.ts.map +1 -0
- package/dist/tools/autocode_session_create.d.ts +13 -0
- package/dist/tools/autocode_session_create.d.ts.map +1 -0
- package/dist/tools/autocode_session_create.test.d.ts +2 -0
- package/dist/tools/autocode_session_create.test.d.ts.map +1 -0
- package/dist/tools/autocode_shelve.d.ts +5 -0
- package/dist/tools/autocode_shelve.d.ts.map +1 -0
- package/dist/tools/autocode_shelve.test.d.ts +2 -0
- package/dist/tools/autocode_shelve.test.d.ts.map +1 -0
- package/dist/tools/index.d.ts +324 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.test.d.ts +2 -0
- package/dist/tools/index.test.d.ts.map +1 -0
- package/dist/tools/task_external.d.ts +35 -0
- package/dist/tools/task_external.d.ts.map +1 -0
- package/dist/tools/task_external.test.d.ts +2 -0
- package/dist/tools/task_external.test.d.ts.map +1 -0
- package/dist/tools/task_resume.d.ts +12 -0
- package/dist/tools/task_resume.d.ts.map +1 -0
- package/dist/tools/task_resume.test.d.ts +2 -0
- package/dist/tools/task_resume.test.d.ts.map +1 -0
- package/dist/tools/test_context.d.ts +5 -0
- package/dist/tools/test_context.d.ts.map +1 -0
- package/dist/utils/agent_swap.d.ts +56 -0
- package/dist/utils/agent_swap.d.ts.map +1 -0
- package/dist/utils/agent_swap.test.d.ts +2 -0
- package/dist/utils/agent_swap.test.d.ts.map +1 -0
- package/dist/utils/autocode_dependencies.d.ts +44 -0
- package/dist/utils/autocode_dependencies.d.ts.map +1 -0
- package/dist/utils/autocode_sandbox_helpers.d.ts +12 -0
- package/dist/utils/autocode_sandbox_helpers.d.ts.map +1 -0
- package/dist/utils/db.d.ts +82 -0
- package/dist/utils/db.d.ts.map +1 -0
- package/dist/utils/delegate.d.ts +3 -0
- package/dist/utils/delegate.d.ts.map +1 -0
- package/dist/utils/frontmatter.d.ts +3 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/jobs.d.ts +210 -0
- package/dist/utils/jobs.d.ts.map +1 -0
- package/dist/utils/jobs.test.d.ts +2 -0
- package/dist/utils/jobs.test.d.ts.map +1 -0
- package/dist/utils/sandbox.d.ts +233 -0
- package/dist/utils/sandbox.d.ts.map +1 -0
- package/dist/utils/sandbox.test.d.ts +2 -0
- package/dist/utils/sandbox.test.d.ts.map +1 -0
- package/dist/utils/sandbox_file_tools.d.ts +34 -0
- package/dist/utils/sandbox_file_tools.d.ts.map +1 -0
- package/dist/utils/shelve.d.ts +33 -0
- package/dist/utils/shelve.d.ts.map +1 -0
- package/dist/utils/solution.d.ts +28 -0
- package/dist/utils/solution.d.ts.map +1 -0
- package/dist/utils/solution.test.d.ts +2 -0
- package/dist/utils/solution.test.d.ts.map +1 -0
- package/dist/utils/tool_permission.d.ts +2 -0
- package/dist/utils/tool_permission.d.ts.map +1 -0
- package/dist/utils/tools.d.ts +7 -0
- package/dist/utils/tools.d.ts.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-java
|
|
3
|
+
description: Java Standards - Use this skill to learn how to update Java code. This is the Java coding standard that you MUST apply to all your Java code or when you update `.java` files.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Java Coding Standard
|
|
7
|
+
|
|
8
|
+
## Core Enforcements
|
|
9
|
+
|
|
10
|
+
### Annotations (@Override, @Deprecated)
|
|
11
|
+
|
|
12
|
+
**@Override** mandatory for ALL overridden methods:
|
|
13
|
+
```java
|
|
14
|
+
@Override
|
|
15
|
+
public String toString() {
|
|
16
|
+
return "User{id=" + id + ", name='" + name + '\'' + '}';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@Override
|
|
20
|
+
public boolean equals(Object o) {
|
|
21
|
+
if (this == o) return true;
|
|
22
|
+
if (!(o instanceof User)) return false;
|
|
23
|
+
User user = (User) o;
|
|
24
|
+
return Objects.equals(id, user.id) && Objects.equals(name, user.name);
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**@Deprecated** with Javadoc and replacement:
|
|
29
|
+
```java
|
|
30
|
+
/**
|
|
31
|
+
* @deprecated Use {@link #newMethod()} instead. Removed in v2.0.
|
|
32
|
+
*/
|
|
33
|
+
@Deprecated(since = "1.5", forRemoval = true)
|
|
34
|
+
public void oldMethod() {
|
|
35
|
+
newMethod();
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Exception Handling
|
|
40
|
+
|
|
41
|
+
**Rules:** Catch specific exceptions, never generic `Exception`. NO empty catch blocks. ALWAYS log or rethrow with context.
|
|
42
|
+
|
|
43
|
+
```java
|
|
44
|
+
// ✅ CORRECT
|
|
45
|
+
try {
|
|
46
|
+
fileReader.readFile(filename);
|
|
47
|
+
} catch (FileNotFoundException e) {
|
|
48
|
+
logger.error("Config file not found: {}", filename, e);
|
|
49
|
+
throw new ConfigurationException("Missing config", e);
|
|
50
|
+
} catch (IOException e) {
|
|
51
|
+
logger.error("IO error reading: {}", filename, e);
|
|
52
|
+
throw new ApplicationException("Unable to read", e);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// ❌ WRONG: Catches everything, empty, or swallows exceptions
|
|
56
|
+
try { fileReader.readFile(filename); }
|
|
57
|
+
catch (Exception e) { } // Masks real issues
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Static Member Access
|
|
61
|
+
|
|
62
|
+
Access via class name, never instance variable:
|
|
63
|
+
```java
|
|
64
|
+
// ✅ CORRECT
|
|
65
|
+
String version = ApplicationConstants.APP_VERSION;
|
|
66
|
+
|
|
67
|
+
// ❌ WRONG
|
|
68
|
+
ApplicationConstants instance = new ApplicationConstants();
|
|
69
|
+
String version = instance.APP_VERSION;
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Resource Management
|
|
73
|
+
|
|
74
|
+
Use try-with-resources or Spring lifecycle (@PostConstruct/@PreDestroy):
|
|
75
|
+
```java
|
|
76
|
+
// ✅ Try-with-resources
|
|
77
|
+
try (Connection conn = dataSource.getConnection();
|
|
78
|
+
Statement stmt = conn.createStatement()) {
|
|
79
|
+
ResultSet rs = stmt.executeQuery(sql);
|
|
80
|
+
} catch (SQLException e) {
|
|
81
|
+
logger.error("Database error: {}", sql, e);
|
|
82
|
+
throw e;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ✅ Spring lifecycle
|
|
86
|
+
@Component
|
|
87
|
+
public class DatabaseManager {
|
|
88
|
+
@PostConstruct
|
|
89
|
+
public void initialize() { logger.info("Initializing"); }
|
|
90
|
+
|
|
91
|
+
@PreDestroy
|
|
92
|
+
public void cleanup() { logger.info("Cleaning up"); }
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Null Checking & Optional
|
|
97
|
+
|
|
98
|
+
Prefer Optional for chains; null checks only when necessary:
|
|
99
|
+
```java
|
|
100
|
+
// ✅ Optional pattern
|
|
101
|
+
findByEmail(email)
|
|
102
|
+
.map(User::getName)
|
|
103
|
+
.orElse("Unknown");
|
|
104
|
+
|
|
105
|
+
// ✅ Null check when needed
|
|
106
|
+
if (user != null && user.isActive()) {
|
|
107
|
+
process(user);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// ❌ NPE risk
|
|
111
|
+
String name = user.getName(); // No null check
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Javadoc Requirements (Mandatory)
|
|
117
|
+
|
|
118
|
+
ALL public classes and methods REQUIRE Javadoc with complete tags:
|
|
119
|
+
|
|
120
|
+
```java
|
|
121
|
+
/**
|
|
122
|
+
* Authenticates user with credentials.
|
|
123
|
+
* Validates username/password against auth service.
|
|
124
|
+
* Generates and stores session token on success.
|
|
125
|
+
*
|
|
126
|
+
* @param username login name (non-null, non-empty)
|
|
127
|
+
* @param password password (non-null, non-empty)
|
|
128
|
+
* @return true if auth successful, false if invalid
|
|
129
|
+
* @throws AuthenticationException if service unavailable
|
|
130
|
+
* @throws IllegalArgumentException if username/password null/empty
|
|
131
|
+
* @since 1.0
|
|
132
|
+
*/
|
|
133
|
+
public boolean authenticate(String username, String password)
|
|
134
|
+
throws AuthenticationException { }
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Mandatory Tags:** @param (all params), @return (if not void), @throws (checked exceptions), @deprecated (with replacement), @since (version)
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## SonarQube Critical Rules (Enforced)
|
|
142
|
+
|
|
143
|
+
**S1161:** Missing @Override annotation
|
|
144
|
+
```java
|
|
145
|
+
// ❌ WRONG
|
|
146
|
+
class Child extends Parent {
|
|
147
|
+
public String toString() { return "child"; }
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// ✅ CORRECT
|
|
151
|
+
class Child extends Parent {
|
|
152
|
+
@Override
|
|
153
|
+
public String toString() { return "child"; }
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**S2097:** Unsafe equals() - missing instanceof check
|
|
158
|
+
```java
|
|
159
|
+
// ❌ WRONG
|
|
160
|
+
@Override
|
|
161
|
+
public boolean equals(Object obj) {
|
|
162
|
+
User user = (User) obj; // No type check!
|
|
163
|
+
return Objects.equals(id, user.id);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ✅ CORRECT
|
|
167
|
+
@Override
|
|
168
|
+
public boolean equals(Object obj) {
|
|
169
|
+
if (!(obj instanceof User)) return false;
|
|
170
|
+
User user = (User) obj;
|
|
171
|
+
return Objects.equals(id, user.id);
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**S2737:** Catch doing nothing but rethrowing
|
|
176
|
+
```java
|
|
177
|
+
// ❌ WRONG - catch should do more
|
|
178
|
+
try {
|
|
179
|
+
operation();
|
|
180
|
+
} catch (IOException e) {
|
|
181
|
+
throw e;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// ✅ CORRECT
|
|
185
|
+
try {
|
|
186
|
+
operation();
|
|
187
|
+
} catch (IOException e) {
|
|
188
|
+
logger.error("IO operation failed", e);
|
|
189
|
+
throw new ApplicationException("Operation failed", e);
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Spring-Specific Critical Rules
|
|
194
|
+
|
|
195
|
+
**S6829/S6818:** Single constructor injection, @Autowired not needed
|
|
196
|
+
```java
|
|
197
|
+
// ✅ CORRECT
|
|
198
|
+
@Service
|
|
199
|
+
public class UserService {
|
|
200
|
+
private final UserRepository repository;
|
|
201
|
+
|
|
202
|
+
public UserService(UserRepository repository) {
|
|
203
|
+
this.repository = repository;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**S6838:** @Bean methods must inject dependencies, not call directly
|
|
209
|
+
```java
|
|
210
|
+
// ❌ WRONG
|
|
211
|
+
@Bean
|
|
212
|
+
public Component component() {
|
|
213
|
+
return new Component(service1()); // Direct call
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// ✅ CORRECT
|
|
217
|
+
@Bean
|
|
218
|
+
public Component component(Service service1) { // Inject via parameter
|
|
219
|
+
return new Component(service1);
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**S7184:** @Scheduled methods must have no arguments
|
|
224
|
+
```java
|
|
225
|
+
// ✅ CORRECT
|
|
226
|
+
@Scheduled(fixedRate = 5000)
|
|
227
|
+
public void scheduledTask() { }
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### SonarQube Quality Gates
|
|
231
|
+
|
|
232
|
+
| Metric | Threshold | Action |
|
|
233
|
+
|--------|-----------|--------|
|
|
234
|
+
| Critical Bugs | 0 | Block deployment |
|
|
235
|
+
| Security Vulnerabilities | 0 | Block deployment |
|
|
236
|
+
| Cyclomatic Complexity | ≤ 5 per method | Refactor if exceeded |
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Spring Patterns
|
|
241
|
+
|
|
242
|
+
### Service Layer
|
|
243
|
+
```java
|
|
244
|
+
@Service
|
|
245
|
+
@Transactional
|
|
246
|
+
public class UserService {
|
|
247
|
+
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
|
|
248
|
+
private final UserRepository repository;
|
|
249
|
+
|
|
250
|
+
public UserService(UserRepository repository) {
|
|
251
|
+
this.repository = repository;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Creates new user account.
|
|
256
|
+
* @param userDTO user data (non-null)
|
|
257
|
+
* @return created user
|
|
258
|
+
* @throws ValidationException if data invalid
|
|
259
|
+
*/
|
|
260
|
+
public User createUser(UserDTO userDTO) {
|
|
261
|
+
if (userDTO == null || userDTO.getEmail() == null) {
|
|
262
|
+
throw new ValidationException("Invalid user data");
|
|
263
|
+
}
|
|
264
|
+
User user = new User();
|
|
265
|
+
user.setEmail(userDTO.getEmail());
|
|
266
|
+
repository.save(user);
|
|
267
|
+
logger.info("User created: {}", user.getId());
|
|
268
|
+
return user;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
public Optional<User> getUserById(Long userId) {
|
|
272
|
+
return repository.findById(userId);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Controller Layer
|
|
278
|
+
```java
|
|
279
|
+
@RestController
|
|
280
|
+
@RequestMapping("/api/v1/users")
|
|
281
|
+
public class UserController {
|
|
282
|
+
private final UserService userService;
|
|
283
|
+
|
|
284
|
+
public UserController(UserService userService) {
|
|
285
|
+
this.userService = userService;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
@GetMapping("/{id}")
|
|
289
|
+
public ResponseEntity<UserDTO> getUserById(@PathVariable Long id) {
|
|
290
|
+
return userService.getUserById(id)
|
|
291
|
+
.map(user -> ResponseEntity.ok(mapToDTO(user)))
|
|
292
|
+
.orElse(ResponseEntity.notFound().build());
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
@PostMapping
|
|
296
|
+
public ResponseEntity<UserDTO> createUser(@RequestBody UserDTO userDTO) {
|
|
297
|
+
User created = userService.createUser(userDTO);
|
|
298
|
+
return ResponseEntity.status(HttpStatus.CREATED).body(mapToDTO(created));
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
private UserDTO mapToDTO(User user) {
|
|
302
|
+
UserDTO dto = new UserDTO();
|
|
303
|
+
dto.setId(user.getId());
|
|
304
|
+
dto.setEmail(user.getEmail());
|
|
305
|
+
return dto;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Code Review Checklist
|
|
313
|
+
|
|
314
|
+
- [ ] All overridden methods have @Override
|
|
315
|
+
- [ ] All deprecated methods documented with replacement
|
|
316
|
+
- [ ] Exception handling: specific exceptions, no generic Exception, no empty catch blocks
|
|
317
|
+
- [ ] All exceptions logged or rethrown with context
|
|
318
|
+
- [ ] Javadoc on all public classes/methods with @param, @return, @throws
|
|
319
|
+
- [ ] Static members accessed via class name, not instance
|
|
320
|
+
- [ ] Resources use try-with-resources or Spring lifecycle
|
|
321
|
+
- [ ] Null-safe: Optional for chains, null checks for single values
|
|
322
|
+
- [ ] SonarQube warnings addressed (S1161, S2097, S2737, S6829, S6838, S7184)
|
|
323
|
+
- [ ] No duplicate code
|
|
324
|
+
- [ ] Cyclomatic complexity ≤ 5 per method
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Key Takeaways
|
|
329
|
+
|
|
330
|
+
1. **@Override** mandatory for every overridden method
|
|
331
|
+
2. **Exception handling** specific, logged, never empty
|
|
332
|
+
3. **Javadoc** with @param, @return, @throws required for all public APIs
|
|
333
|
+
4. **Optional** for null-safe chains; null checks for single values
|
|
334
|
+
5. **Resources** managed via try-with-resources or Spring lifecycle
|
|
335
|
+
6. **SonarQube** blocks deployment on critical bugs (S1161, S2097, S2737)
|
|
336
|
+
7. **Spring rules** enforce proper @Bean invocation, @Scheduled args, single constructor injection
|
|
337
|
+
8. **Static** members accessed via class name
|
|
338
|
+
9. **Cyclomatic complexity** ≤ 5 per method
|
|
339
|
+
10. **Code review** checklist used on every pull request
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
**Document Status:** BMW Java Coding Standard
|
|
344
|
+
**Last Updated:** Current
|
|
345
|
+
**Audience:** BMW Java Developers, Backend Engineers
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-rest
|
|
3
|
+
description: Apply `code-rest` skill before design-review REST API or OpenAPI specifications
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Naming Conventions
|
|
7
|
+
|
|
8
|
+
| Element | Convention | Example |
|
|
9
|
+
|---------|-----------|---------|
|
|
10
|
+
| Path segments | lowercase with hyphens | `/vehicle-images/123` |
|
|
11
|
+
| Resources | lowercase, plural, nouns | `/orders`, `/users` |
|
|
12
|
+
| Query parameters | snake_case | `?max_results=10&sort=+id` |
|
|
13
|
+
| Properties | camelCase | `"lifeTimeList"`, `"customerId"` |
|
|
14
|
+
| Enum names | UpperCamelCase | `"DeliverMethods"` |
|
|
15
|
+
| Enum values | UPPER_SNAKE_CASE | `"DELIVER_METHODS_UNSPECIFIED"` |
|
|
16
|
+
| Custom HTTP headers | Hyphenated-Pascal-Case with `BMW-` prefix | `BMW-CV-Transaction-ID` |
|
|
17
|
+
|
|
18
|
+
- MUST avoid trailing slashes in paths.
|
|
19
|
+
- MUST declare resources as nouns — never use verbs in resource paths (use `/orders`, not `/create-orders`).
|
|
20
|
+
- First enum value SHOULD be `<ENUM_TYPE>_UNSPECIFIED`.
|
|
21
|
+
|
|
22
|
+
## HTTP Methods and Safety/Idempotency
|
|
23
|
+
|
|
24
|
+
| Method | Safe | Idempotent | Primary Use |
|
|
25
|
+
|--------|------|------------|-------------|
|
|
26
|
+
| GET | Yes | Yes | Read resources; MUST NOT have request body |
|
|
27
|
+
| HEAD | Yes | Yes | Retrieve headers only |
|
|
28
|
+
| POST | No | No | Create resources on collections or execute procedures |
|
|
29
|
+
| PUT | No | Yes | Create or fully replace a resource |
|
|
30
|
+
| PATCH | No | No | Partial update of a resource |
|
|
31
|
+
| DELETE | No | Yes | Delete a resource |
|
|
32
|
+
| OPTIONS | Yes | Yes | Inspect available operations; support CORS |
|
|
33
|
+
|
|
34
|
+
- MUST distinguish between **resources** (nouns, CRUD via standard methods) and **procedures** (actions via POST).
|
|
35
|
+
|
|
36
|
+
## HTTP Status Codes
|
|
37
|
+
|
|
38
|
+
### MUST declare (when relevant)
|
|
39
|
+
|
|
40
|
+
- **200** OK — success for GET, PUT, POST
|
|
41
|
+
- **201** Created — new resource created (POST)
|
|
42
|
+
- **204** No Content — success with no body (DELETE)
|
|
43
|
+
- **400** Bad Request — invalid structure/types/missing data
|
|
44
|
+
- **401** Unauthorized — missing or invalid credentials
|
|
45
|
+
- **403** Forbidden — authenticated but insufficient permissions
|
|
46
|
+
- **404** Not Found — resource does not exist
|
|
47
|
+
- **500** Internal Server Error — unexpected server failure
|
|
48
|
+
- **503** Service Unavailable — set `Retry-After` header when possible
|
|
49
|
+
|
|
50
|
+
Do not declare other 4xx/5xx codes unless there is a strong justification. Use **422** only for business logic errors.
|
|
51
|
+
|
|
52
|
+
For 401/403 responses, return no body content.
|
|
53
|
+
|
|
54
|
+
## Versioning
|
|
55
|
+
|
|
56
|
+
- MUST use Semantic Versioning (`MAJOR.MINOR.PATCH`) in `/info/version`.
|
|
57
|
+
- MUST include major version in URL path: `/<service-id>/<api-path>/v1/...`
|
|
58
|
+
- Do not put version segments in individual paths — only in the server/basePath.
|
|
59
|
+
|
|
60
|
+
## Compatibility
|
|
61
|
+
|
|
62
|
+
- Add only optional fields — never mandatory ones.
|
|
63
|
+
- Never change field semantics.
|
|
64
|
+
- Use `x-extensible-enum` instead of closed `enum` for output values that may grow.
|
|
65
|
+
- Clients MUST tolerate unknown fields and new enum values.
|
|
66
|
+
- Use the `deprecated` property, `Sunset` HTTP header, and client notification for deprecation.
|
|
67
|
+
|
|
68
|
+
## Data Format
|
|
69
|
+
|
|
70
|
+
- MUST use JSON (`application/json`) for structured data.
|
|
71
|
+
- MUST return JSON objects (not arrays) as top-level response structures.
|
|
72
|
+
- MUST accept unknown properties in models (forward compatibility).
|
|
73
|
+
- MUST use RFC 3339 for dates (`2024-01-15`) and date-times (`2024-01-15T14:07:17.123Z`), stored in UTC.
|
|
74
|
+
- SHOULD use ISO 8601 for durations and intervals.
|
|
75
|
+
- MUST use ISO standards for country (3166-1-alpha2), language (639-1/BCP-47), and currency (4217) codes.
|
|
76
|
+
- MUST use International System of Units (metres, kelvin).
|
|
77
|
+
|
|
78
|
+
## Performance
|
|
79
|
+
|
|
80
|
+
- SHOULD omit null property values from responses.
|
|
81
|
+
- SHOULD paginate lists > 50 items (offset/limit or token-based).
|
|
82
|
+
- SHOULD support `fields` parameter for partial responses on large payloads.
|