guardian-framework 0.1.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.
Files changed (216) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +463 -0
  3. package/dist/cli.js +12958 -0
  4. package/dist/exports.js +12765 -0
  5. package/package.json +61 -0
  6. package/templates/languages/go-patterns.md +411 -0
  7. package/templates/languages/java-patterns.md +545 -0
  8. package/templates/languages/python-patterns.md +312 -0
  9. package/templates/languages/rust-patterns.md +232 -0
  10. package/templates/languages/typescript-patterns.md +313 -0
  11. package/templates/pi/INDEX.md +437 -0
  12. package/templates/pi/agent/AGENTS.md +166 -0
  13. package/templates/pi/agents/architecture-coordinator.md +40 -0
  14. package/templates/pi/agents/architecture-validator.md +36 -0
  15. package/templates/pi/agents/bootstrap-implementer.md +37 -0
  16. package/templates/pi/agents/issue-factory.md +31 -0
  17. package/templates/pi/agents/operations-validator.md +32 -0
  18. package/templates/pi/agents/security-validator.md +33 -0
  19. package/templates/pi/architecture/CHANGELOG.md +78 -0
  20. package/templates/pi/architecture/decisions/ADR-template.md +76 -0
  21. package/templates/pi/architecture/diagrams/system-overview.md +159 -0
  22. package/templates/pi/architecture/modules/module-template.md +152 -0
  23. package/templates/pi/context/checklists.md +91 -0
  24. package/templates/pi/context/domain-workflow.md +180 -0
  25. package/templates/pi/context/output-formats.md +135 -0
  26. package/templates/pi/context/patterns-base.md +47 -0
  27. package/templates/pi/context/patterns.md +38 -0
  28. package/templates/pi/context/project.md +88 -0
  29. package/templates/pi/domain/exploration.md +93 -0
  30. package/templates/pi/domain/ubiquitous-language.md +24 -0
  31. package/templates/pi/extensions/architect-lib/generators.ts +528 -0
  32. package/templates/pi/extensions/architect-lib/helpers.ts +344 -0
  33. package/templates/pi/extensions/architect-lib/types.ts +117 -0
  34. package/templates/pi/extensions/architect.ts +1425 -0
  35. package/templates/pi/extensions/ask-user-question.ts +579 -0
  36. package/templates/pi/extensions/bash-guard.ts +556 -0
  37. package/templates/pi/extensions/config-reload.ts +115 -0
  38. package/templates/pi/extensions/coordinator.ts +304 -0
  39. package/templates/pi/extensions/curator.ts +543 -0
  40. package/templates/pi/extensions/domain-explorer.ts +990 -0
  41. package/templates/pi/extensions/filechanges.ts +656 -0
  42. package/templates/pi/extensions/goal-loop.ts +717 -0
  43. package/templates/pi/extensions/hooks.ts +452 -0
  44. package/templates/pi/extensions/kanban.ts +547 -0
  45. package/templates/pi/extensions/pipeline.ts +1246 -0
  46. package/templates/pi/extensions/plan-mode.ts +209 -0
  47. package/templates/pi/extensions/project-scaffolder.ts +284 -0
  48. package/templates/pi/extensions/read-only-mode.ts +192 -0
  49. package/templates/pi/extensions/redaction.ts +128 -0
  50. package/templates/pi/extensions/session-persistence.ts +174 -0
  51. package/templates/pi/extensions/slash-commands.ts +229 -0
  52. package/templates/pi/extensions/snippets.ts +201 -0
  53. package/templates/pi/extensions/validation-runner.ts +100 -0
  54. package/templates/pi/github/agents/architecture-coordinator.agent.md +27 -0
  55. package/templates/pi/github/agents/architecture-validator.agent.md +20 -0
  56. package/templates/pi/github/agents/bootstrap-implementer.agent.md +20 -0
  57. package/templates/pi/github/agents/epic-planner.agent.md +70 -0
  58. package/templates/pi/github/agents/issue-factory.agent.md +20 -0
  59. package/templates/pi/github/agents/operations-validator.agent.md +20 -0
  60. package/templates/pi/github/agents/security-validator.agent.md +20 -0
  61. package/templates/pi/github/copilot/settings.json +16 -0
  62. package/templates/pi/github/copilot-instructions.md +155 -0
  63. package/templates/pi/github/instructions/architecture.instructions.md +71 -0
  64. package/templates/pi/github/instructions/validation.instructions.md +69 -0
  65. package/templates/pi/github/workflows/01-planning-workflow.md +75 -0
  66. package/templates/pi/github/workflows/02-issue-generation-workflow.md +69 -0
  67. package/templates/pi/github/workflows/03-implementation-workflow.md +80 -0
  68. package/templates/pi/github/workflows/04-validation-workflow.md +68 -0
  69. package/templates/pi/preflight_report.json +99 -0
  70. package/templates/pi/prompts/blueprint-update.md +262 -0
  71. package/templates/pi/prompts/blueprint-validate.md +218 -0
  72. package/templates/pi/prompts/bug-fix.md +50 -0
  73. package/templates/pi/prompts/ci-blueprint.md +131 -0
  74. package/templates/pi/prompts/context-refresh.md +258 -0
  75. package/templates/pi/prompts/epic-plan.md +356 -0
  76. package/templates/pi/prompts/epic-template.md +186 -0
  77. package/templates/pi/prompts/feature-development.md +131 -0
  78. package/templates/pi/prompts/git-issues.md +243 -0
  79. package/templates/pi/prompts/hotfix.md +71 -0
  80. package/templates/pi/prompts/issue-closeout.md +342 -0
  81. package/templates/pi/prompts/issue-draft.md +218 -0
  82. package/templates/pi/prompts/issue-implementation-series.md +173 -0
  83. package/templates/pi/prompts/issue-merge.md +372 -0
  84. package/templates/pi/prompts/issue-template-set.md +392 -0
  85. package/templates/pi/prompts/issue-template.md +207 -0
  86. package/templates/pi/prompts/pattern-extract.md +269 -0
  87. package/templates/pi/prompts/plan-to-issues.md +430 -0
  88. package/templates/pi/prompts/refactoring.md +82 -0
  89. package/templates/pi/prompts/scope-analyzer.md +254 -0
  90. package/templates/pi/prompts/sync-check.md +230 -0
  91. package/templates/pi/scripts/categorize-issues.sh +171 -0
  92. package/templates/pi/scripts/ci/check_architecture_conformance.sh +748 -0
  93. package/templates/pi/scripts/ci/check_planning_packet.py +228 -0
  94. package/templates/pi/scripts/ci/run_hardening_stages.sh +264 -0
  95. package/templates/pi/scripts/ci/run_preflight.sh +649 -0
  96. package/templates/pi/scripts/ci/run_stage.sh +193 -0
  97. package/templates/pi/scripts/ci/stage_docs_policy.sh +82 -0
  98. package/templates/pi/scripts/ci/stage_integration.sh +3 -0
  99. package/templates/pi/scripts/ci/stage_lint.sh +130 -0
  100. package/templates/pi/scripts/ci/stage_migration_verify.sh +3 -0
  101. package/templates/pi/scripts/ci/stage_package_build.sh +3 -0
  102. package/templates/pi/scripts/ci/stage_release_readiness.sh +3 -0
  103. package/templates/pi/scripts/ci/stage_remaining.sh +242 -0
  104. package/templates/pi/scripts/ci/stage_security.sh +3 -0
  105. package/templates/pi/scripts/ci/stage_static_analysis.sh +114 -0
  106. package/templates/pi/scripts/ci/stage_unit.sh +119 -0
  107. package/templates/pi/scripts/ci/validate_agent_output.py +181 -0
  108. package/templates/pi/scripts/ci/validate_agent_output.sh +243 -0
  109. package/templates/pi/scripts/create-feature-branch.sh +136 -0
  110. package/templates/pi/scripts/create-mr.sh +117 -0
  111. package/templates/pi/scripts/fetch-issues.sh +131 -0
  112. package/templates/pi/scripts/generate-architecture.sh +161 -0
  113. package/templates/pi/scripts/git/close-epic.sh +69 -0
  114. package/templates/pi/scripts/git/close-issue.sh +35 -0
  115. package/templates/pi/scripts/git/create-tracking-issue.sh +174 -0
  116. package/templates/pi/scripts/git/link-issue-to-epic.sh +51 -0
  117. package/templates/pi/scripts/git/update-tracking-issue.sh +66 -0
  118. package/templates/pi/scripts/languages/go/validate-architecture.sh +139 -0
  119. package/templates/pi/scripts/languages/go/validate-canonical.sh +129 -0
  120. package/templates/pi/scripts/languages/go/validate-ci.sh +132 -0
  121. package/templates/pi/scripts/languages/go/validate-integration.sh +156 -0
  122. package/templates/pi/scripts/languages/go/validate-operations.sh +146 -0
  123. package/templates/pi/scripts/languages/go/validate-security.sh +135 -0
  124. package/templates/pi/scripts/languages/go/validate-tests.sh +125 -0
  125. package/templates/pi/scripts/languages/java/validate-annotations.sh +185 -0
  126. package/templates/pi/scripts/languages/java/validate-architecture.sh +159 -0
  127. package/templates/pi/scripts/languages/java/validate-canonical.sh +114 -0
  128. package/templates/pi/scripts/languages/java/validate-ci.sh +269 -0
  129. package/templates/pi/scripts/languages/java/validate-integration.sh +149 -0
  130. package/templates/pi/scripts/languages/java/validate-operations.sh +142 -0
  131. package/templates/pi/scripts/languages/java/validate-security.sh +174 -0
  132. package/templates/pi/scripts/languages/java/validate-spring-architecture.sh +227 -0
  133. package/templates/pi/scripts/languages/java/validate-tests.sh +159 -0
  134. package/templates/pi/scripts/languages/python/validate-architecture.sh +99 -0
  135. package/templates/pi/scripts/languages/python/validate-canonical.sh +124 -0
  136. package/templates/pi/scripts/languages/python/validate-ci.sh +130 -0
  137. package/templates/pi/scripts/languages/python/validate-integration.sh +119 -0
  138. package/templates/pi/scripts/languages/python/validate-operations.sh +107 -0
  139. package/templates/pi/scripts/languages/python/validate-security.sh +68 -0
  140. package/templates/pi/scripts/languages/python/validate-tests.sh +102 -0
  141. package/templates/pi/scripts/languages/rust/validate-architecture.sh +188 -0
  142. package/templates/pi/scripts/languages/rust/validate-canonical.sh +146 -0
  143. package/templates/pi/scripts/languages/rust/validate-ci.sh +147 -0
  144. package/templates/pi/scripts/languages/rust/validate-integration.sh +149 -0
  145. package/templates/pi/scripts/languages/rust/validate-operations.sh +154 -0
  146. package/templates/pi/scripts/languages/rust/validate-security.sh +153 -0
  147. package/templates/pi/scripts/languages/rust/validate-tests.sh +150 -0
  148. package/templates/pi/scripts/languages/typescript/validate-architecture.sh +157 -0
  149. package/templates/pi/scripts/languages/typescript/validate-canonical.sh +135 -0
  150. package/templates/pi/scripts/languages/typescript/validate-ci.sh +244 -0
  151. package/templates/pi/scripts/languages/typescript/validate-integration.sh +166 -0
  152. package/templates/pi/scripts/languages/typescript/validate-operations.sh +162 -0
  153. package/templates/pi/scripts/languages/typescript/validate-security.sh +169 -0
  154. package/templates/pi/scripts/languages/typescript/validate-tests.sh +158 -0
  155. package/templates/pi/scripts/merge-mr.sh +95 -0
  156. package/templates/pi/scripts/mr-validation.sh +228 -0
  157. package/templates/pi/scripts/validate-architecture-readiness.sh +153 -0
  158. package/templates/pi/scripts/validate-architecture.sh +22 -0
  159. package/templates/pi/scripts/validate-canonical.sh +22 -0
  160. package/templates/pi/scripts/validate-ci.sh +37 -0
  161. package/templates/pi/scripts/validate-integration.sh +22 -0
  162. package/templates/pi/scripts/validate-operations.sh +22 -0
  163. package/templates/pi/scripts/validate-security.sh +22 -0
  164. package/templates/pi/scripts/validate-tests.sh +22 -0
  165. package/templates/pi/scripts/validate-ubiquitous-language.sh +291 -0
  166. package/templates/pi/scripts/validation-cache.sh +139 -0
  167. package/templates/pi/skills/agents/architecture-coordinator.md +178 -0
  168. package/templates/pi/skills/agents/architecture-generator.md +79 -0
  169. package/templates/pi/skills/agents/architecture-validator.md +74 -0
  170. package/templates/pi/skills/agents/ci-mr-validator.md +46 -0
  171. package/templates/pi/skills/agents/code-developer.md +76 -0
  172. package/templates/pi/skills/agents/commit.md +46 -0
  173. package/templates/pi/skills/agents/curator.md +71 -0
  174. package/templates/pi/skills/agents/debug.md +59 -0
  175. package/templates/pi/skills/agents/documentation-maintainer.md +36 -0
  176. package/templates/pi/skills/agents/goal-loop.md +125 -0
  177. package/templates/pi/skills/agents/hooks.md +122 -0
  178. package/templates/pi/skills/agents/integration-validator.md +35 -0
  179. package/templates/pi/skills/agents/issue-creator.md +75 -0
  180. package/templates/pi/skills/agents/issue-factory.md +143 -0
  181. package/templates/pi/skills/agents/kanban.md +85 -0
  182. package/templates/pi/skills/agents/land.md +59 -0
  183. package/templates/pi/skills/agents/operations-validator.md +43 -0
  184. package/templates/pi/skills/agents/pipeline.md +113 -0
  185. package/templates/pi/skills/agents/plan-mode.md +77 -0
  186. package/templates/pi/skills/agents/pull.md +40 -0
  187. package/templates/pi/skills/agents/push.md +41 -0
  188. package/templates/pi/skills/agents/security-validator.md +85 -0
  189. package/templates/pi/skills/agents/session-persistence.md +119 -0
  190. package/templates/pi/skills/agents/slash-commands.md +117 -0
  191. package/templates/pi/skills/agents/snippets.md +99 -0
  192. package/templates/pi/skills/agents/subagent-registry.md +78 -0
  193. package/templates/pi/skills/agents/test-validator.md +42 -0
  194. package/templates/pi/skills/validators/architecture-validator.md +43 -0
  195. package/templates/pi/skills/validators/ci-validator.md +27 -0
  196. package/templates/pi/skills/validators/context-compaction.md +73 -0
  197. package/templates/pi/skills/validators/integration-validator.md +38 -0
  198. package/templates/pi/skills/validators/model-registry.md +96 -0
  199. package/templates/pi/skills/validators/operations-validator.md +34 -0
  200. package/templates/pi/skills/validators/security-guards.md +72 -0
  201. package/templates/pi/skills/validators/security-validator.md +41 -0
  202. package/templates/pi/skills/validators/system-prompt-tiers.md +69 -0
  203. package/templates/pi/skills/validators/test-validator.md +33 -0
  204. package/templates/pi/types.ts +62 -0
  205. package/templates/pi/validators/README.md +93 -0
  206. package/templates/pi/validators/default.toml +209 -0
  207. package/templates/pi/validators/spring.toml +142 -0
  208. package/templates/pi/workpad.md +53 -0
  209. package/templates/project/java/Dockerfile +14 -0
  210. package/templates/project/java/README.md +40 -0
  211. package/templates/project/java/pom.xml +132 -0
  212. package/templates/project/typescript/Dockerfile +15 -0
  213. package/templates/project/typescript/README.md +29 -0
  214. package/templates/project/typescript/package.json +23 -0
  215. package/templates/project/typescript/tsconfig.json +21 -0
  216. package/templates/workflow.md +123 -0
@@ -0,0 +1,545 @@
1
+ # Java & Spring Boot Code Patterns
2
+
3
+ > **Purpose:** Reusable Java and Spring Boot patterns for Guardian projects.
4
+ > **Source:** Guardian Framework — Java/Spring Support Module
5
+
6
+ ---
7
+
8
+ ## Clean Architecture Layering
9
+
10
+ ```java
11
+ // Package structure with dependency direction:
12
+ //
13
+ // interfaces/ (controllers, DTOs, web config)
14
+ // ↓
15
+ // application/ (use cases, ports, DTOs)
16
+ // ↓
17
+ // domain/ (entities, value objects, domain services)
18
+ // ↑
19
+ // infrastructure/ (repositories, JPA, external APIs, messaging)
20
+ //
21
+ // Rules:
22
+ // domain/ → imports NOTHING from outside domain
23
+ // application/ → imports ONLY domain/
24
+ // infrastructure/ → imports domain/ + application/
25
+ // interfaces/ → imports application/ only
26
+
27
+ // Example package structure
28
+ // com.myproject.domain.model/
29
+ // com.myproject.domain.service/
30
+ // com.myproject.application.port/
31
+ // com.myproject.application.usecase/
32
+ // com.myproject.infrastructure.persistence/
33
+ // com.myproject.infrastructure.messaging/
34
+ // com.myproject.interfaces.web/
35
+ // com.myproject.interfaces.config/
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Spring Annotations Reference
41
+
42
+ ```java
43
+ // === STEREOTYPES ===
44
+ @Component // Generic component (auto-detected via scanning)
45
+ @Service // Business logic in application/domain layer
46
+ @Repository // Data access (Spring adds PersistenceExceptionTranslation)
47
+ @Controller // MVC controller (returns view name)
48
+ @RestController // REST controller (returns response body)
49
+
50
+ // === DEPENDENCY INJECTION ===
51
+ @Autowired // Injects bean (use on constructors, not fields)
52
+ @Qualifier("name") // Disambiguate when multiple beans of same type
53
+ @Primary // Prefer this bean when multiple candidates
54
+ @Scope("prototype") // Non-singleton scope (default is singleton)
55
+
56
+ // === WEB LAYER ===
57
+ @RequestMapping("/api/users") // Class-level mapping
58
+ @GetMapping("/{id}") // GET
59
+ @PostMapping // POST
60
+ @PutMapping("/{id}") // PUT
61
+ @DeleteMapping("/{id}") // DELETE
62
+ @PatchMapping("/{id}") // PATCH
63
+ @PathVariable("id") // Path variable
64
+ @RequestParam("page") // Query parameter
65
+ @RequestBody // Request body deserialization
66
+ @ResponseStatus(HttpStatus.CREATED) // Response status override
67
+
68
+ // === DATA ===
69
+ @Transactional // Transaction boundary (service layer)
70
+ @Transactional(readOnly = true) // Read-only optimization
71
+ @Query("SELECT u FROM User u WHERE u.email = :email")
72
+ @Modifying // Indicates an UPDATE/DELETE @Query
73
+ @Entity // JPA entity
74
+ @Table(name = "users") // Table mapping
75
+ @Column(name = "email", nullable = false, unique = true)
76
+ @Id // Primary key
77
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
78
+ @ManyToOne(fetch = FetchType.LAZY)
79
+ @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
80
+ @Enumerated(EnumType.STRING)
81
+
82
+ // === SECURITY ===
83
+ @PreAuthorize("hasRole('ADMIN')")
84
+ @PostAuthorize("returnObject.owner == authentication.name")
85
+ @Secured("ROLE_ADMIN")
86
+ @RolesAllowed("ADMIN")
87
+
88
+ // === OBSERVABILITY ===
89
+ @Cacheable("users")
90
+ @CacheEvict(value = "users", allEntries = true)
91
+ @Scheduled(cron = "0 0 * * * *")
92
+ @Async
93
+ @EventListener
94
+ @EventListener(condition = "#event.success")
95
+
96
+ // === LIFECYCLE ===
97
+ @PostConstruct // Init callback (ONLY in service/config/component packages)
98
+ @PreDestroy // Cleanup callback
99
+ ```
100
+
101
+ ---
102
+
103
+ ## Dependency Injection Patterns
104
+
105
+ ```java
106
+ // ✅ PREFERRED: Constructor injection (immutable, testable, required deps)
107
+ @Service
108
+ public class UserService {
109
+ private final UserRepository userRepository;
110
+ private final NotificationService notificationService;
111
+
112
+ public UserService(UserRepository userRepository,
113
+ NotificationService notificationService) {
114
+ this.userRepository = userRepository;
115
+ this.notificationService = notificationService;
116
+ }
117
+ }
118
+
119
+ // ✅ ACCEPTABLE: Setter injection (optional dependencies)
120
+ @Service
121
+ public class AuditService {
122
+ private MetricsCollector metricsCollector;
123
+
124
+ @Autowired(required = false)
125
+ public void setMetricsCollector(MetricsCollector metricsCollector) {
126
+ this.metricsCollector = metricsCollector;
127
+ }
128
+ }
129
+
130
+ // ❌ NEVER: Field injection (hard to test, breaks immutability, hidden deps)
131
+ @Service
132
+ public class BadService {
133
+ @Autowired // BAD
134
+ private UserRepository userRepository;
135
+
136
+ @Autowired // BAD
137
+ private NotificationService notificationService;
138
+ }
139
+ ```
140
+
141
+ ---
142
+
143
+ ## JPA Patterns
144
+
145
+ ```java
146
+ // === ENTITY DESIGN ===
147
+ @Entity
148
+ @Table(name = "orders")
149
+ public class Order {
150
+ @Id
151
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
152
+ private Long id;
153
+
154
+ @Column(nullable = false)
155
+ private String orderNumber;
156
+
157
+ @Enumerated(EnumType.STRING)
158
+ private OrderStatus status;
159
+
160
+ @ManyToOne(fetch = FetchType.LAZY)
161
+ @JoinColumn(name = "customer_id")
162
+ private Customer customer;
163
+
164
+ @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
165
+ private List<OrderItem> items = new ArrayList<>();
166
+
167
+ @Version
168
+ private Long version; // Optimistic locking
169
+
170
+ @CreatedDate
171
+ private LocalDateTime createdAt;
172
+
173
+ @LastModifiedDate
174
+ private LocalDateTime updatedAt;
175
+
176
+ // Protected default constructor for JPA
177
+ protected Order() {}
178
+
179
+ // Business-meaningful constructor
180
+ public Order(Customer customer, List<OrderItem> items) {
181
+ this.customer = customer;
182
+ this.items = new ArrayList<>(items);
183
+ this.status = OrderStatus.PENDING;
184
+ this.orderNumber = generateOrderNumber();
185
+ }
186
+ }
187
+
188
+ // === REPOSITORY PATTERNS ===
189
+ public interface OrderRepository extends JpaRepository<Order, Long> {
190
+ // Derived query
191
+ List<Order> findByCustomerIdAndStatus(Long customerId, OrderStatus status);
192
+
193
+ // JPQL query
194
+ @Query("SELECT o FROM Order o WHERE o.orderNumber = :orderNumber")
195
+ Optional<Order> findByOrderNumber(@Param("orderNumber") String orderNumber);
196
+
197
+ // Native query
198
+ @Query(value = "SELECT * FROM orders WHERE total > :amount", nativeQuery = true)
199
+ List<Order> findOrdersAboveAmount(@Param("amount") BigDecimal amount);
200
+
201
+ // Projection
202
+ @Query("SELECT new com.myproject.application.dto.OrderSummary(o.id, o.orderNumber, o.status) FROM Order o")
203
+ List<OrderSummary> findAllSummaries();
204
+
205
+ // Pagination
206
+ Page<Order> findByCustomerId(Long customerId, Pageable pageable);
207
+ }
208
+
209
+ // === AUDITING ===
210
+ @EntityListeners(AuditingEntityListener.class)
211
+ @Entity
212
+ @Table(name = "orders")
213
+ public class AuditableOrder {
214
+ @CreatedBy
215
+ private String createdBy;
216
+
217
+ @LastModifiedBy
218
+ private String lastModifiedBy;
219
+ }
220
+ ```
221
+
222
+ ---
223
+
224
+ ## Testing Patterns
225
+
226
+ ```java
227
+ // === FULL CONTEXT TEST ===
228
+ @SpringBootTest
229
+ class UserServiceTest {
230
+ @Autowired
231
+ private UserService userService;
232
+
233
+ @Test
234
+ void shouldCreateUser() {
235
+ // Given
236
+ CreateUserCommand command = new CreateUserCommand("john@example.com", "John");
237
+
238
+ // When
239
+ User user = userService.createUser(command);
240
+
241
+ // Then
242
+ assertThat(user.getEmail()).isEqualTo("john@example.com");
243
+ assertThat(user.getName()).isEqualTo("John");
244
+ }
245
+ }
246
+
247
+ // === WEB LAYER TEST (sliced) ===
248
+ @WebMvcTest(UserController.class)
249
+ class UserControllerTest {
250
+ @Autowired
251
+ private MockMvc mockMvc;
252
+
253
+ @MockBean
254
+ private UserService userService;
255
+
256
+ @Test
257
+ void shouldReturnUser() throws Exception {
258
+ // Given
259
+ given(userService.findById(1L)).willReturn(new UserDTO(1L, "John"));
260
+
261
+ // When/Then
262
+ mockMvc.perform(get("/api/users/1"))
263
+ .andExpect(status().isOk())
264
+ .andExpect(jsonPath("$.name").value("John"));
265
+ }
266
+ }
267
+
268
+ // === DATA LAYER TEST (sliced) ===
269
+ @DataJpaTest
270
+ class OrderRepositoryTest {
271
+ @Autowired
272
+ private TestEntityManager entityManager;
273
+
274
+ @Autowired
275
+ private OrderRepository orderRepository;
276
+
277
+ @Test
278
+ void shouldFindByCustomerId() {
279
+ // Given
280
+ Customer customer = new Customer("John");
281
+ entityManager.persist(customer);
282
+ Order order = new Order(customer, List.of());
283
+ entityManager.persist(order);
284
+ entityManager.flush();
285
+
286
+ // When
287
+ List<Order> found = orderRepository.findByCustomerId(customer.getId());
288
+
289
+ // Then
290
+ assertThat(found).hasSize(1);
291
+ assertThat(found.get(0).getCustomer().getId()).isEqualTo(customer.getId());
292
+ }
293
+ }
294
+ ```
295
+
296
+ ---
297
+
298
+ ## Error Handling
299
+
300
+ ```java
301
+ // === GLOBAL EXCEPTION HANDLER ===
302
+ @RestControllerAdvice
303
+ public class GlobalExceptionHandler {
304
+
305
+ @ExceptionHandler(ResourceNotFoundException.class)
306
+ @ResponseStatus(HttpStatus.NOT_FOUND)
307
+ public ProblemDetail handleNotFound(ResourceNotFoundException ex) {
308
+ return ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, ex.getMessage());
309
+ }
310
+
311
+ @ExceptionHandler(ValidationException.class)
312
+ @ResponseStatus(HttpStatus.BAD_REQUEST)
313
+ public ProblemDetail handleValidation(ValidationException ex) {
314
+ ProblemDetail problem = ProblemDetail.forStatusAndDetail(
315
+ HttpStatus.BAD_REQUEST, ex.getMessage());
316
+ problem.setTitle("Validation Error");
317
+ problem.setProperty("errors", ex.getErrors());
318
+ return problem;
319
+ }
320
+
321
+ @ExceptionHandler(AccessDeniedException.class)
322
+ @ResponseStatus(HttpStatus.FORBIDDEN)
323
+ public ProblemDetail handleAccessDenied(AccessDeniedException ex) {
324
+ return ProblemDetail.forStatusAndDetail(
325
+ HttpStatus.FORBIDDEN, "Access denied");
326
+ }
327
+
328
+ @ExceptionHandler(Exception.class)
329
+ @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
330
+ public ProblemDetail handleGeneric(Exception ex) {
331
+ // Log full exception, return sanitized response
332
+ log.error("Unexpected error", ex);
333
+ return ProblemDetail.forStatusAndDetail(
334
+ HttpStatus.INTERNAL_SERVER_ERROR, "Internal server error");
335
+ }
336
+ }
337
+
338
+ // === DOMAIN RESULTS ===
339
+ // For operations that can fail without exceptions
340
+ public sealed interface Result<T> {
341
+ record Success<T>(T value) implements Result<T> {}
342
+ record Failure<T>(String error, Map<String, Object> details) implements Result<T> {}
343
+ }
344
+ ```
345
+
346
+ ---
347
+
348
+ ## Configuration
349
+
350
+ ```java
351
+ // === TYPE-SAFE CONFIGURATION ===
352
+ @ConfigurationProperties(prefix = "app.notification")
353
+ public class NotificationProperties {
354
+ private String fromEmail;
355
+ private List<String> adminEmails = new ArrayList<>();
356
+ private Duration timeout = Duration.ofSeconds(30);
357
+ private boolean enabled = true;
358
+
359
+ // getters and setters
360
+ }
361
+
362
+ // === PROFILE-SPECIFIC CONFIG ===
363
+ // application-dev.yml
364
+ // application-prod.yml
365
+ // application-test.yml
366
+
367
+ // Active profile
368
+ @Profile("dev")
369
+ @Component
370
+ public class DevDataInitializer implements CommandLineRunner { ... }
371
+
372
+ // === CONDITIONAL BEANS ===
373
+ @ConditionalOnProperty(name = "app.feature.notifications", havingValue = "true")
374
+ @ConditionalOnClass(name = "com.amazonaws.services.sqs.AmazonSQS")
375
+ @ConditionalOnMissingBean(NotificationService.class)
376
+ ```
377
+
378
+ ---
379
+
380
+ ## Transaction Management
381
+
382
+ ```java
383
+ @Service
384
+ public class OrderService {
385
+
386
+ // Required by default — joins existing or creates new
387
+ @Transactional
388
+ public Order createOrder(CreateOrderCommand command) {
389
+ Order order = new Order(command.customer(), mapItems(command.items()));
390
+ return orderRepository.save(order);
391
+ }
392
+
393
+ // Read-only optimization — hints JPA to skip dirty checking
394
+ @Transactional(readOnly = true)
395
+ public Optional<Order> findById(Long id) {
396
+ return orderRepository.findById(id);
397
+ }
398
+
399
+ // Explicit rollback
400
+ @Transactional(rollbackFor = InsufficientBalanceException.class)
401
+ public void processPayment(Long orderId, BigDecimal amount) {
402
+ // throws InsufficientBalanceException → rollback
403
+ }
404
+
405
+ // Isolation level
406
+ @Transactional(isolation = Isolation.REPEATABLE_READ)
407
+ public BigDecimal calculateDailyRevenue() { ... }
408
+
409
+ // Propagation control
410
+ @Transactional(propagation = Propagation.REQUIRES_NEW)
411
+ public void logAuditTrail(AuditEntry entry) {
412
+ // Always runs in a new transaction
413
+ }
414
+ }
415
+ ```
416
+
417
+ ---
418
+
419
+ ## Anti-Patterns (NEVER DO)
420
+
421
+ ```java
422
+ // ❌ Field injection
423
+ @Service
424
+ public class BadService {
425
+ @Autowired private UserRepository userRepository; // BAD
426
+ }
427
+
428
+ // ❌ @PostConstruct in controllers
429
+ @RestController
430
+ public class BadController {
431
+ @PostConstruct // BAD — lifecycle hooks don't belong in web layer
432
+ public void init() { ... }
433
+ }
434
+
435
+ // ❌ Domain layer importing infrastructure
436
+ // package com.myproject.domain.model;
437
+ // import com.myproject.infrastructure.persistence.JpaUtils; // BAD
438
+
439
+ // ❌ Direct repository access from web layer
440
+ @RestController
441
+ public class BadController {
442
+ @Autowired private UserRepository userRepository; // BAD — use service layer
443
+ }
444
+
445
+ // ❌ Unbounded @RequestMapping
446
+ @RequestMapping // BAD — always specify path
447
+ public class VagueController { ... }
448
+
449
+ // ❌ Using RuntimeException directly
450
+ throw new RuntimeException("something failed"); // BAD — use specific exceptions
451
+
452
+ // ❌ Ignoring @Transactional on service methods
453
+ @Service
454
+ public class OrderService {
455
+ public void createOrder(...) { // BAD — no @Transactional
456
+ // each JPA operation runs in its own transaction
457
+ }
458
+ }
459
+
460
+ // ❌ Eager fetching in entity relationships
461
+ @ManyToOne(fetch = FetchType.EAGER) // BAD — always use LAZY
462
+ ```
463
+
464
+ ---
465
+
466
+ ## Build Commands
467
+
468
+ ```bash
469
+ # Maven
470
+ mvn clean compile -q # Build
471
+ mvn test -q # Test
472
+ mvn checkstyle:check -q # Lint
473
+ mvn spotless:apply # Format
474
+ mvn spotless:check # Format check
475
+ mvn dependency-check:check # Security audit
476
+ mvn verify # Full verification
477
+
478
+ # Gradle
479
+ gradle build -q # Build
480
+ gradle test -q # Test
481
+ gradle checkstyleMain -q # Lint
482
+ gradle spotlessApply # Format
483
+ gradle spotlessCheck # Format check
484
+ gradle dependencyCheck # Security audit
485
+ gradle check # Full verification
486
+ ```
487
+
488
+ ---
489
+
490
+ ## Dependencies
491
+
492
+ ```xml
493
+ <!-- Maven — spring-boot-starter-parent -->
494
+ <parent>
495
+ <groupId>org.springframework.boot</groupId>
496
+ <artifactId>spring-boot-starter-parent</artifactId>
497
+ <version>3.2.0</version>
498
+ </parent>
499
+
500
+ <dependencies>
501
+ <!-- Web -->
502
+ <dependency>
503
+ <groupId>org.springframework.boot</groupId>
504
+ <artifactId>spring-boot-starter-web</artifactId>
505
+ </dependency>
506
+
507
+ <!-- JPA -->
508
+ <dependency>
509
+ <groupId>org.springframework.boot</groupId>
510
+ <artifactId>spring-boot-starter-data-jpa</artifactId>
511
+ </dependency>
512
+
513
+ <!-- Security -->
514
+ <dependency>
515
+ <groupId>org.springframework.boot</groupId>
516
+ <artifactId>spring-boot-starter-security</artifactId>
517
+ </dependency>
518
+
519
+ <!-- Validation -->
520
+ <dependency>
521
+ <groupId>org.springframework.boot</groupId>
522
+ <artifactId>spring-boot-starter-validation</artifactId>
523
+ </dependency>
524
+
525
+ <!-- Database -->
526
+ <dependency>
527
+ <groupId>org.postgresql</groupId>
528
+ <artifactId>postgresql</artifactId>
529
+ <scope>runtime</scope>
530
+ </dependency>
531
+
532
+ <!-- Test -->
533
+ <dependency>
534
+ <groupId>org.springframework.boot</groupId>
535
+ <artifactId>spring-boot-starter-test</artifactId>
536
+ <scope>test</scope>
537
+ </dependency>
538
+
539
+ <!-- Observability -->
540
+ <dependency>
541
+ <groupId>io.micrometer</groupId>
542
+ <artifactId>micrometer-tracing-bridge-brave</artifactId>
543
+ </dependency>
544
+ </dependencies>
545
+ ```