@eltonssouza/development-utility-kit 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/agents/analyst.md +198 -0
- package/.claude/agents/backend-developer.md +126 -0
- package/.claude/agents/brain-keeper.md +229 -0
- package/.claude/agents/code-reviewer.md +181 -0
- package/.claude/agents/database-engineer.md +94 -0
- package/.claude/agents/devops-engineer.md +141 -0
- package/.claude/agents/frontend-developer.md +97 -0
- package/.claude/agents/gate-keeper.md +118 -0
- package/.claude/agents/migrator.md +291 -0
- package/.claude/agents/mobile-developer.md +80 -0
- package/.claude/agents/n8n-specialist.md +94 -0
- package/.claude/agents/product-owner.md +115 -0
- package/.claude/agents/qa-engineer.md +232 -0
- package/.claude/agents/release-engineer.md +204 -0
- package/.claude/agents/scaffold.md +87 -0
- package/.claude/agents/security-engineer.md +199 -0
- package/.claude/agents/sprint-runner.md +44 -0
- package/.claude/agents/stack-resolver.md +84 -0
- package/.claude/agents/tech-lead.md +182 -0
- package/.claude/agents/update-template.md +54 -0
- package/.claude/agents/ux-designer.md +118 -0
- package/.claude/settings.json +44 -0
- package/.claude/skills/README.md +332 -0
- package/.claude/skills/active-project/SKILL.md +129 -0
- package/.claude/skills/api-integration-test/SKILL.md +64 -0
- package/.claude/skills/auto-test-guard/SKILL.md +237 -0
- package/.claude/skills/auto-test-guard/resources/backend-tests.md +20 -0
- package/.claude/skills/auto-test-guard/resources/e2e-tests.md +24 -0
- package/.claude/skills/auto-test-guard/resources/execution-report.md +49 -0
- package/.claude/skills/auto-test-guard/resources/frontend-tests.md +18 -0
- package/.claude/skills/auto-test-guard/resources/initial-setup.md +108 -0
- package/.claude/skills/auto-test-guard/resources/run-suite.md +48 -0
- package/.claude/skills/auto-test-guard/resources/senior-gate.md +19 -0
- package/.claude/skills/brain-keeper/SKILL.md +60 -0
- package/.claude/skills/brain-keeper/obsidian/app.json +9 -0
- package/.claude/skills/brain-keeper/obsidian/appearance.json +4 -0
- package/.claude/skills/brain-keeper/obsidian/core-plugins.json +20 -0
- package/.claude/skills/brain-keeper/obsidian/daily-notes.json +5 -0
- package/.claude/skills/brain-keeper/obsidian/graph.json +32 -0
- package/.claude/skills/brain-keeper/obsidian/snippets/folder-colors.css +90 -0
- package/.claude/skills/brain-keeper/obsidian/templates.json +5 -0
- package/.claude/skills/brain-keeper/templates/README.md +51 -0
- package/.claude/skills/brain-keeper/templates/adr.md +40 -0
- package/.claude/skills/brain-keeper/templates/bug.md +35 -0
- package/.claude/skills/brain-keeper/templates/daily.md +38 -0
- package/.claude/skills/brain-keeper/templates/feature.md +62 -0
- package/.claude/skills/brain-keeper/templates/meeting.md +34 -0
- package/.claude/skills/brain-keeper/templates/tech-debt.md +21 -0
- package/.claude/skills/caveman/SKILL.md +187 -0
- package/.claude/skills/create-stack-pack/SKILL.md +281 -0
- package/.claude/skills/grill-me/SKILL.md +79 -0
- package/.claude/skills/honcho-memory/SKILL.md +207 -0
- package/.claude/skills/honcho-memory/docs/api-endpoints-verified.md +75 -0
- package/.claude/skills/honcho-memory/hooks/on-prompt-submit.js +221 -0
- package/.claude/skills/honcho-memory/hooks/on-stop.js +193 -0
- package/.claude/skills/honcho-memory/lib/honcho-client.js +363 -0
- package/.claude/skills/honcho-memory/lib/memory-injector.js +93 -0
- package/.claude/skills/honcho-memory/package.json +32 -0
- package/.claude/skills/honcho-memory/scripts/cli.js +370 -0
- package/.claude/skills/honcho-memory/scripts/setup.js +109 -0
- package/.claude/skills/honcho-memory/tests/t001-api-endpoints-verified.test.js +89 -0
- package/.claude/skills/honcho-memory/tests/t002-structure.test.js +97 -0
- package/.claude/skills/honcho-memory/tests/t003-honcho-client.test.js +162 -0
- package/.claude/skills/honcho-memory/tests/t004-soft-delete.test.js +259 -0
- package/.claude/skills/honcho-memory/tests/t005-memory-injector.test.js +175 -0
- package/.claude/skills/honcho-memory/tests/t006-on-prompt-submit.test.js +215 -0
- package/.claude/skills/honcho-memory/tests/t007-on-stop.test.js +165 -0
- package/.claude/skills/honcho-memory/tests/t008-cli.test.js +214 -0
- package/.claude/skills/honcho-memory/tests/t009-setup.test.js +232 -0
- package/.claude/skills/honcho-memory/tests/t010-skill-md.test.js +114 -0
- package/.claude/skills/honcho-memory/tests/t011-settings-hooks.test.js +105 -0
- package/.claude/skills/honcho-memory/tests/t012-docs-update.test.js +106 -0
- package/.claude/skills/honcho-memory/tests/t013-smoke-e2e.test.js +90 -0
- package/.claude/skills/pair-debug/SKILL.md +288 -0
- package/.claude/skills/prd-ready-check/SKILL.md +58 -0
- package/.claude/skills/project-manager/SKILL.md +167 -0
- package/.claude/skills/quality-standards/SKILL.md +201 -0
- package/.claude/skills/quick-feature/SKILL.md +264 -0
- package/.claude/skills/run-sprint/SKILL.md +342 -0
- package/.claude/skills/scaffold/SKILL.md +58 -0
- package/.claude/skills/stack-discovery/SKILL.md +159 -0
- package/.claude/skills/test-coverage-auditor/SKILL.md +59 -0
- package/.claude/skills/to-issues/SKILL.md +163 -0
- package/.claude/skills/to-prd/SKILL.md +130 -0
- package/.claude/skills/update-template/SKILL.md +254 -0
- package/.claude/stacks/CODEOWNERS +30 -0
- package/.claude/stacks/README.md +88 -0
- package/.claude/stacks/_template.md +116 -0
- package/.claude/stacks/java/spring-boot-3.md +376 -0
- package/.claude/stacks/java/spring-boot-4.md +438 -0
- package/.claude/stacks/typescript/angular-18.md +420 -0
- package/.claude/stacks/typescript/angular-19.md +397 -0
- package/.claude/stacks/typescript/angular-21.md +494 -0
- package/CLAUDE.md +453 -0
- package/README.md +391 -0
- package/bin/cli.js +773 -0
- package/bin/lib/backup.js +62 -0
- package/bin/lib/detect-stack.js +476 -0
- package/bin/lib/help.js +233 -0
- package/bin/lib/identity.js +108 -0
- package/bin/lib/local-dir.js +69 -0
- package/bin/lib/manifest.js +236 -0
- package/bin/lib/sync-all.js +394 -0
- package/bin/lib/version-check.js +398 -0
- package/dashboard/db.js +199 -0
- package/dashboard/package.json +22 -0
- package/dashboard/public/app.js +709 -0
- package/dashboard/public/content/docs/agents-reference.en.md +911 -0
- package/dashboard/public/content/docs/architecture-overview.en.md +260 -0
- package/dashboard/public/content/docs/autonomy-matrix.en.md +186 -0
- package/dashboard/public/content/docs/git-flow.en.md +525 -0
- package/dashboard/public/content/docs/honcho-memory.en.md +394 -0
- package/dashboard/public/content/docs/hooks-reference.en.md +420 -0
- package/dashboard/public/content/docs/pipeline.en.md +400 -0
- package/dashboard/public/content/docs/quality-gate.en.md +315 -0
- package/dashboard/public/content/docs/skills-reference.en.md +500 -0
- package/dashboard/public/content/docs/stack-rules.en.md +362 -0
- package/dashboard/public/content/docs/troubleshooting.en.md +637 -0
- package/dashboard/public/content/manifest.json +102 -0
- package/dashboard/public/content/manual/backend.en.md +1138 -0
- package/dashboard/public/content/manual/existing-project.en.md +831 -0
- package/dashboard/public/content/manual/frontend.en.md +1065 -0
- package/dashboard/public/content/manual/fullstack.en.md +1508 -0
- package/dashboard/public/content/manual/mobile.en.md +866 -0
- package/dashboard/public/index.html +108 -0
- package/dashboard/public/style.css +610 -0
- package/dashboard/public/vendor/marked.min.js +69 -0
- package/dashboard/rtk.js +143 -0
- package/dashboard/server-app.js +403 -0
- package/dashboard/server.js +104 -0
- package/dashboard/test/sprint1.test.js +406 -0
- package/dashboard/test/sprint2.test.js +571 -0
- package/dashboard/test/sprint3.test.js +560 -0
- package/package.json +33 -0
- package/scripts/hooks/subagent-telemetry.sh +14 -0
- package/scripts/hooks/telemetry-writer.js +250 -0
- package/scripts/latest-versions.json +56 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
# Stack Rules
|
|
2
|
+
|
|
3
|
+
Stack rules are **mandatory** across all projects managed by the harness. They cover minimum versions, code conventions, package structure, security, observability, and anti-patterns.
|
|
4
|
+
|
|
5
|
+
Changing a rule requires an ADR approved by `tech-lead`. There is no "in this project it is different" without an ADR.
|
|
6
|
+
|
|
7
|
+
## Mandatory versions
|
|
8
|
+
|
|
9
|
+
| Technology | Minimum version | Notes |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| Java | 25+ (LTS) or 26 | Modernize legacy automatically. Records, sealed types, pattern matching. |
|
|
12
|
+
| Spring Boot | 4.0.x+ | SecurityFilterChain, RestClient, WebClient, ProblemDetail (RFC 9457) |
|
|
13
|
+
| Angular | 21+ | Standalone, Signals, OnPush, lazy loading, Signal Forms |
|
|
14
|
+
| React Native | 0.84+ (latest) | New Architecture, TypeScript strict |
|
|
15
|
+
| Expo SDK | 54+ | EAS Build, Expo Router |
|
|
16
|
+
| Spring AI | latest | ChatClient, Advisors, function calling |
|
|
17
|
+
| PostgreSQL | 17+ | UUID v7, JSONB, generated columns |
|
|
18
|
+
| Redis | 7+ | Cache, session, rate limiting |
|
|
19
|
+
|
|
20
|
+
Versions below the minimum are treated as a mandatory migration. The `migrator` agent is responsible for Java 8/11/17 → 25, Spring Boot 2/3 → 4, Angular 14-20 → 21.
|
|
21
|
+
|
|
22
|
+
## Java / Spring Boot 4 conventions
|
|
23
|
+
|
|
24
|
+
### DTOs
|
|
25
|
+
|
|
26
|
+
- **`record` for immutable DTOs**. Never mutable classes with getters/setters.
|
|
27
|
+
- **Separate req/res DTOs**. `CreateProductRequest` and `ProductResponse` are distinct types.
|
|
28
|
+
- **Never expose JPA entity directly** in a controller. Always map to a record.
|
|
29
|
+
|
|
30
|
+
```java
|
|
31
|
+
public record CreateProductRequest(
|
|
32
|
+
@NotBlank @Size(max = 120) String name,
|
|
33
|
+
@NotNull @PositiveOrZero BigDecimal price,
|
|
34
|
+
@NotNull @PositiveOrZero Integer stock
|
|
35
|
+
) {}
|
|
36
|
+
|
|
37
|
+
public record ProductResponse(
|
|
38
|
+
UUID id,
|
|
39
|
+
String name,
|
|
40
|
+
BigDecimal price,
|
|
41
|
+
Integer stock,
|
|
42
|
+
OffsetDateTime createdAt
|
|
43
|
+
) {
|
|
44
|
+
public static ProductResponse fromEntity(Product p) {
|
|
45
|
+
return new ProductResponse(p.getId(), p.getName(), p.getPrice(), p.getStock(), p.getCreatedAt());
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Validation
|
|
51
|
+
|
|
52
|
+
- **Bean Validation** (`@Valid`, `@NotBlank`, `@Email`, `@Positive`, `@PositiveOrZero`, `@Size`).
|
|
53
|
+
- Compound validation via `@AssertTrue` in a record method.
|
|
54
|
+
- Validation errors → ProblemDetail RFC 9457.
|
|
55
|
+
|
|
56
|
+
### Error handling
|
|
57
|
+
|
|
58
|
+
- Domain exceptions in `domain/` (e.g. `ProductNotFoundException`).
|
|
59
|
+
- Central `@ControllerAdvice` in `web/` maps exception → `ProblemDetail`.
|
|
60
|
+
|
|
61
|
+
```java
|
|
62
|
+
@ControllerAdvice
|
|
63
|
+
public class GlobalExceptionHandler {
|
|
64
|
+
|
|
65
|
+
@ExceptionHandler(ProductNotFoundException.class)
|
|
66
|
+
ProblemDetail handleNotFound(ProductNotFoundException ex, HttpServletRequest req) {
|
|
67
|
+
var pd = ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, ex.getMessage());
|
|
68
|
+
pd.setTitle("Product not found");
|
|
69
|
+
pd.setProperty("path", req.getRequestURI());
|
|
70
|
+
pd.setProperty("traceId", MDC.get("traceId"));
|
|
71
|
+
return pd;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### APIs
|
|
77
|
+
|
|
78
|
+
- **Versioned** `/api/v1/<resource>`. Bump to v2 only with a real breaking change.
|
|
79
|
+
- **Pagination** via `Pageable` + a `PagedResponse<T>` wrapper with metadata (total, page, size).
|
|
80
|
+
- **Semantic HTTP**: 201 + Location on POST, 204 on DELETE, 200 on GET/PUT, 422 on semantic validation, 409 on conflict.
|
|
81
|
+
|
|
82
|
+
### Idempotency
|
|
83
|
+
|
|
84
|
+
Idempotent POSTs receive an `Idempotency-Key` header. The key is cached in Redis with TTL.
|
|
85
|
+
|
|
86
|
+
### Imports and types
|
|
87
|
+
|
|
88
|
+
- **Full imports** (`java.util.UUID`), never `*`.
|
|
89
|
+
- **No `var`** in signature/return. In a method body, `var` is fine when the type is obvious.
|
|
90
|
+
|
|
91
|
+
### Tests
|
|
92
|
+
|
|
93
|
+
- **JUnit 5 + Mockito** for unit. Tests in `src/test/java`.
|
|
94
|
+
- **Testcontainers** for integration. **NEVER H2** — H2 lies about Postgres-specific types.
|
|
95
|
+
- Descriptive naming: `should_return201_when_validProduct()` or `givenValidProduct_whenCreate_thenReturns201()`.
|
|
96
|
+
- Testcontainers for real Postgres:
|
|
97
|
+
|
|
98
|
+
```java
|
|
99
|
+
@SpringBootTest
|
|
100
|
+
@Testcontainers
|
|
101
|
+
class ProductIntegrationTest {
|
|
102
|
+
@Container
|
|
103
|
+
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:17");
|
|
104
|
+
|
|
105
|
+
@DynamicPropertySource
|
|
106
|
+
static void props(DynamicPropertyRegistry r) {
|
|
107
|
+
r.add("spring.datasource.url", postgres::getJdbcUrl);
|
|
108
|
+
r.add("spring.datasource.username", postgres::getUsername);
|
|
109
|
+
r.add("spring.datasource.password", postgres::getPassword);
|
|
110
|
+
}
|
|
111
|
+
// ...
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Migrations
|
|
116
|
+
|
|
117
|
+
- **Flyway** (or Liquibase). Versioned: `V20260527_001__create_product.sql`.
|
|
118
|
+
- **Indexes in the same migration** that creates the table. Every FK has an index on the N side.
|
|
119
|
+
- **Reversible** whenever possible (upgrade + downgrade when supported).
|
|
120
|
+
|
|
121
|
+
### Observability
|
|
122
|
+
|
|
123
|
+
- **Structured JSON logs** (Logback + Logstash encoder).
|
|
124
|
+
- **Correlation ID** via MDC (`traceId`, `spanId` — OpenTelemetry W3C).
|
|
125
|
+
- **Micrometer + Prometheus metrics** (p50/p95/p99, error rate, throughput).
|
|
126
|
+
- **Actuator health** with `/actuator/health/readiness` and `/actuator/health/liveness`.
|
|
127
|
+
- **OpenTelemetry tracing** (W3C Trace Context).
|
|
128
|
+
|
|
129
|
+
### Forbidden anti-patterns
|
|
130
|
+
|
|
131
|
+
- `// TODO` committed → goes to `docs/brain/tech-debt.md`.
|
|
132
|
+
- Token/password/PII in log → `gate-keeper` blocks.
|
|
133
|
+
- Exposing JPA entity in controller.
|
|
134
|
+
- `var` in public signature.
|
|
135
|
+
- H2 in integration test.
|
|
136
|
+
|
|
137
|
+
## Angular 21 conventions
|
|
138
|
+
|
|
139
|
+
### SEPARATE FILES — NON-NEGOTIABLE
|
|
140
|
+
|
|
141
|
+
Every component, directive, or pipe with a template uses **3 physical files**:
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
product-form/
|
|
145
|
+
├── product-form.ts logic (signals, methods)
|
|
146
|
+
├── product-form.html template (via templateUrl)
|
|
147
|
+
└── product-form.scss styles (via styleUrl or styleUrls)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**NEVER** inline `template:` or `styles:` in the `.ts`. No size exception, no "small component" exception, no "presentation only" exception. Violation = hard block — `code-reviewer` and `tech-lead` refuse the merge.
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
// CORRECT
|
|
154
|
+
@Component({
|
|
155
|
+
selector: 'app-product-form',
|
|
156
|
+
templateUrl: './product-form.html',
|
|
157
|
+
styleUrl: './product-form.scss',
|
|
158
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
159
|
+
standalone: true,
|
|
160
|
+
imports: [/* ... */],
|
|
161
|
+
})
|
|
162
|
+
export class ProductFormComponent { /* ... */ }
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
// FORBIDDEN
|
|
167
|
+
@Component({
|
|
168
|
+
selector: 'app-product-form',
|
|
169
|
+
template: `<form>...</form>`, // ❌ HARD BLOCK
|
|
170
|
+
styles: [`form { color: red; }`], // ❌ HARD BLOCK
|
|
171
|
+
})
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Angular 21 patterns
|
|
175
|
+
|
|
176
|
+
- **Standalone components** — no NgModules.
|
|
177
|
+
- **OnPush change detection** always.
|
|
178
|
+
- **Signals** for local state. RxJS only for HTTP/stream.
|
|
179
|
+
- **Lazy loading** mandatory for features.
|
|
180
|
+
- **Typed HttpClient** + interceptors for auth, error, correlation ID.
|
|
181
|
+
- **Never `any`** — use `unknown` + narrowing when needed.
|
|
182
|
+
- **Signal Forms** (Angular 21) preferred over Reactive Forms for new forms.
|
|
183
|
+
|
|
184
|
+
### Style
|
|
185
|
+
|
|
186
|
+
- **ng-bootstrap** as default UI library (modal, tooltip, datepicker, typeahead, etc.).
|
|
187
|
+
- **Design tokens** for color, spacing, typography.
|
|
188
|
+
- **WCAG 2.1 AA a11y** minimum. jest-axe in component tests.
|
|
189
|
+
|
|
190
|
+
### Tests
|
|
191
|
+
|
|
192
|
+
- **Jest + Testing Library** for component.
|
|
193
|
+
- **jest-axe** for component a11y.
|
|
194
|
+
- **Playwright + @axe-core/playwright** for E2E.
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
import { render, screen } from '@testing-library/angular';
|
|
198
|
+
import { axe } from 'jest-axe';
|
|
199
|
+
|
|
200
|
+
describe('ProductFormComponent', () => {
|
|
201
|
+
it('has no a11y violations', async () => {
|
|
202
|
+
const { container } = await render(ProductFormComponent);
|
|
203
|
+
expect(await axe(container)).toHaveNoViolations();
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Package structure — Backend (DDD)
|
|
209
|
+
|
|
210
|
+
```
|
|
211
|
+
com.company.project
|
|
212
|
+
├── domain/ model, repository ports, domain services, domain exceptions
|
|
213
|
+
├── application/ use cases, record req/res DTOs, mappers
|
|
214
|
+
├── infrastructure/ JPA adapters, messaging, security config, external clients
|
|
215
|
+
└── web/ controllers, filters, @ControllerAdvice
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Role of each layer**:
|
|
219
|
+
|
|
220
|
+
- **`domain/`** — business core. Knows nothing about Spring, JPA, HTTP. Models are pure objects with rules. Repository = port (interface).
|
|
221
|
+
- **`application/`** — use cases. Orchestrates the domain via ports. DTOs live here.
|
|
222
|
+
- **`infrastructure/`** — adapters. Implements the domain's ports via JPA, Redis, Kafka, REST clients.
|
|
223
|
+
- **`web/`** — HTTP entry. Thin controllers call use cases.
|
|
224
|
+
|
|
225
|
+
The dependency only points inward: `web → application → domain` and `infrastructure → domain`. **`domain/` depends on nobody**.
|
|
226
|
+
|
|
227
|
+
## Angular structure — Frontend
|
|
228
|
+
|
|
229
|
+
```
|
|
230
|
+
src/app/
|
|
231
|
+
├── core/ auth, http interceptors, guards, error handling
|
|
232
|
+
├── shared/ reusable components, pipes, directives
|
|
233
|
+
├── features/ lazy-loaded feature modules
|
|
234
|
+
└── app.routes.ts
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Role of each folder**:
|
|
238
|
+
|
|
239
|
+
- **`core/`** — app singletons: AuthService, HttpInterceptor, ErrorHandler. Imported once in `app.config.ts`.
|
|
240
|
+
- **`shared/`** — reusable UI pieces (custom buttons, pipes). Standalone, stateless.
|
|
241
|
+
- **`features/`** — features. Each feature is lazy: `features/products/products.routes.ts`.
|
|
242
|
+
|
|
243
|
+
## Security (always applied)
|
|
244
|
+
|
|
245
|
+
- **OAuth2 / OpenID Connect** with **stateless JWT**.
|
|
246
|
+
- **RBAC** with `@PreAuthorize` on service or controller methods.
|
|
247
|
+
- **CORS per domain** (never `*` in prod).
|
|
248
|
+
- **Rate limiting** via Bucket4j (in-app) or API Gateway.
|
|
249
|
+
- **Mandatory headers**: CSP, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy.
|
|
250
|
+
- **Never log** token, password, PII.
|
|
251
|
+
|
|
252
|
+
```java
|
|
253
|
+
@Configuration
|
|
254
|
+
@EnableWebSecurity
|
|
255
|
+
public class SecurityConfig {
|
|
256
|
+
@Bean
|
|
257
|
+
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
|
258
|
+
return http
|
|
259
|
+
.csrf(csrf -> csrf.disable())
|
|
260
|
+
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
|
261
|
+
.authorizeHttpRequests(a -> a
|
|
262
|
+
.requestMatchers("/api/v1/auth/**").permitAll()
|
|
263
|
+
.anyRequest().authenticated())
|
|
264
|
+
.oauth2ResourceServer(o -> o.jwt(Customizer.withDefaults()))
|
|
265
|
+
.headers(h -> h
|
|
266
|
+
.contentSecurityPolicy(csp -> csp.policyDirectives("default-src 'self'"))
|
|
267
|
+
.httpStrictTransportSecurity(hsts -> hsts.maxAgeInSeconds(31536000)))
|
|
268
|
+
.build();
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## Observability (every system in production)
|
|
274
|
+
|
|
275
|
+
- **Logs**: structured JSON (Logback + Logstash encoder), correlation ID via MDC.
|
|
276
|
+
- **Metrics**: Micrometer + Prometheus (`/actuator/prometheus`).
|
|
277
|
+
- **Tracing**: OpenTelemetry (W3C Trace Context).
|
|
278
|
+
- **Health**: Spring Actuator (`/actuator/health/readiness`, `/actuator/health/liveness`).
|
|
279
|
+
|
|
280
|
+
## Database
|
|
281
|
+
|
|
282
|
+
- **PostgreSQL 17+** as default.
|
|
283
|
+
- **UUID v7** as PK (natural temporal ordering).
|
|
284
|
+
- **TIMESTAMPTZ** for every timestamp (never `TIMESTAMP` without tz).
|
|
285
|
+
- **NUMERIC(precision, scale)** for money — never `FLOAT`/`DOUBLE`.
|
|
286
|
+
- **Flyway migrations** versioned + indexes in the same migration.
|
|
287
|
+
- **Every FK has an index on the N side**.
|
|
288
|
+
- **Partial indexes** when applicable (`WHERE deleted_at IS NULL`).
|
|
289
|
+
- **Redis 7+** for distributed cache, session, rate limiting.
|
|
290
|
+
- **MongoDB** only when flexible schema is a real requirement (rare).
|
|
291
|
+
|
|
292
|
+
## Frontend — UI Components
|
|
293
|
+
|
|
294
|
+
- **ng-bootstrap** = default library.
|
|
295
|
+
- Ready components: modal, tooltip, datepicker, typeahead, pagination, accordion, tabs, alerts, toasts.
|
|
296
|
+
- **WCAG 2.1 AA a11y** minimum. ARIA roles and labels on interactive elements.
|
|
297
|
+
- **Design tokens** for color, spacing, typography. No hardcoded color in SCSS.
|
|
298
|
+
|
|
299
|
+
## Infrastructure
|
|
300
|
+
|
|
301
|
+
- **Docker**: multi-stage build, non-root user, HEALTHCHECK in the Dockerfile.
|
|
302
|
+
|
|
303
|
+
```dockerfile
|
|
304
|
+
FROM eclipse-temurin:25-jdk AS build
|
|
305
|
+
WORKDIR /app
|
|
306
|
+
COPY . .
|
|
307
|
+
RUN ./mvnw -B package -DskipTests
|
|
308
|
+
|
|
309
|
+
FROM eclipse-temurin:25-jre
|
|
310
|
+
RUN useradd -r -u 1001 appuser
|
|
311
|
+
USER appuser
|
|
312
|
+
WORKDIR /app
|
|
313
|
+
COPY --from=build /app/target/*.jar app.jar
|
|
314
|
+
HEALTHCHECK --interval=30s --timeout=3s CMD curl -fsS http://localhost:8080/actuator/health/liveness || exit 1
|
|
315
|
+
ENTRYPOINT ["java", "-jar", "app.jar"]
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
- **Compose**: full dev stack (app + Postgres + Redis + Mailhog + Prometheus + Grafana).
|
|
319
|
+
- **CI/CD**: GitHub Actions or GitLab CI (build → test → scan → deploy).
|
|
320
|
+
- **Secrets**: never in code — vault, env var, CI secret.
|
|
321
|
+
|
|
322
|
+
## Credentials
|
|
323
|
+
|
|
324
|
+
To access service VPS, N8N VPS, or API Keys, **always read from**:
|
|
325
|
+
|
|
326
|
+
```
|
|
327
|
+
C:\development\tools\credentials\vps.txt
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Never ask the human if the file exists. Never commit the contents. Never log the value read.
|
|
331
|
+
|
|
332
|
+
## Common anti-patterns (blocked in review)
|
|
333
|
+
|
|
334
|
+
| Anti-pattern | Why blocked | Correct |
|
|
335
|
+
|---|---|---|
|
|
336
|
+
| Exposing JPA entity in controller | Leaks DB schema to client, hard to evolve | Map to record DTO |
|
|
337
|
+
| `var` in method signature | Hurts API readability | Explicit type |
|
|
338
|
+
| `// TODO` committed | Untraceable | Entry in `docs/brain/tech-debt.md` |
|
|
339
|
+
| Secret in code | Credential leak | Env var or vault |
|
|
340
|
+
| Inline Angular template | Violates file separation | 3 physical files |
|
|
341
|
+
| H2 in integration test | Lies about Postgres behavior | Real Postgres via Testcontainers |
|
|
342
|
+
| CORS `*` in prod | CSRF/XSS vulnerability | Explicit allowlist |
|
|
343
|
+
| `any` in TypeScript | Loses compiler guarantee | `unknown` + narrowing |
|
|
344
|
+
| Table without index on FK | Performance degrades under load | Index in the same migration |
|
|
345
|
+
| `FLOAT` for money | Floating-point imprecision | `NUMERIC(15, 2)` |
|
|
346
|
+
| Skipping a11y test | Violates WCAG 2.1 AA | jest-axe mandatory |
|
|
347
|
+
|
|
348
|
+
## General principles
|
|
349
|
+
|
|
350
|
+
- **Clean Code + SOLID** applied through the code, without naming names.
|
|
351
|
+
- **No premature abstraction**. Create an interface when there is a second real consumer.
|
|
352
|
+
- **Every external call with explicit error handling** (timeout, retry, circuit breaker via Resilience4j).
|
|
353
|
+
- **Never suggest a technology without justification**. Simplest solution = best.
|
|
354
|
+
- **Never log token, password, PII**.
|
|
355
|
+
|
|
356
|
+
## Cross-references
|
|
357
|
+
|
|
358
|
+
- [Agents reference](agents-reference) — agents that enforce these rules (`backend-developer`, `frontend-developer`, `code-reviewer`, `tech-lead`)
|
|
359
|
+
- [Quality gate](quality-gate) — thresholds that validate adherence to the rules
|
|
360
|
+
- [Pipeline](pipeline) — where each rule is enforced in the flow
|
|
361
|
+
- [Architecture overview](architecture-overview) — macro model
|
|
362
|
+
- [Git Flow](git-flow) — branch and commit convention
|