@ryuenn3123/agentic-senior-core 1.8.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/.agent-context/blueprints/api-nextjs.md +184 -0
- package/.agent-context/blueprints/aspnet-api.md +247 -0
- package/.agent-context/blueprints/ci-github-actions.md +226 -0
- package/.agent-context/blueprints/ci-gitlab.md +200 -0
- package/.agent-context/blueprints/fastapi-service.md +210 -0
- package/.agent-context/blueprints/go-service.md +217 -0
- package/.agent-context/blueprints/graphql-grpc-api.md +51 -0
- package/.agent-context/blueprints/infrastructure-as-code.md +62 -0
- package/.agent-context/blueprints/kubernetes-manifests.md +76 -0
- package/.agent-context/blueprints/laravel-api.md +223 -0
- package/.agent-context/blueprints/nestjs-logic.md +247 -0
- package/.agent-context/blueprints/observability.md +227 -0
- package/.agent-context/blueprints/spring-boot-api.md +218 -0
- package/.agent-context/policies/llm-judge-threshold.json +20 -0
- package/.agent-context/profiles/platform.md +13 -0
- package/.agent-context/profiles/regulated.md +13 -0
- package/.agent-context/profiles/startup.md +13 -0
- package/.agent-context/prompts/init-project.md +86 -0
- package/.agent-context/prompts/refactor.md +45 -0
- package/.agent-context/prompts/review-code.md +47 -0
- package/.agent-context/review-checklists/architecture-review.md +70 -0
- package/.agent-context/review-checklists/frontend-usability.md +33 -0
- package/.agent-context/review-checklists/performance-audit.md +65 -0
- package/.agent-context/review-checklists/pr-checklist.md +97 -0
- package/.agent-context/review-checklists/release-operations.md +29 -0
- package/.agent-context/review-checklists/security-audit.md +113 -0
- package/.agent-context/rules/api-docs.md +186 -0
- package/.agent-context/rules/architecture.md +198 -0
- package/.agent-context/rules/database-design.md +202 -0
- package/.agent-context/rules/efficiency-vs-hype.md +143 -0
- package/.agent-context/rules/error-handling.md +234 -0
- package/.agent-context/rules/event-driven.md +226 -0
- package/.agent-context/rules/frontend-architecture.md +66 -0
- package/.agent-context/rules/git-workflow.md +200 -0
- package/.agent-context/rules/microservices.md +174 -0
- package/.agent-context/rules/naming-conv.md +141 -0
- package/.agent-context/rules/performance.md +168 -0
- package/.agent-context/rules/realtime.md +47 -0
- package/.agent-context/rules/security.md +195 -0
- package/.agent-context/rules/testing.md +178 -0
- package/.agent-context/stacks/csharp.md +149 -0
- package/.agent-context/stacks/go.md +181 -0
- package/.agent-context/stacks/java.md +135 -0
- package/.agent-context/stacks/php.md +178 -0
- package/.agent-context/stacks/python.md +153 -0
- package/.agent-context/stacks/ruby.md +80 -0
- package/.agent-context/stacks/rust.md +86 -0
- package/.agent-context/stacks/typescript.md +317 -0
- package/.agent-context/state/architecture-map.md +25 -0
- package/.agent-context/state/dependency-map.md +32 -0
- package/.agent-override.md +36 -0
- package/.agents/workflows/init-project.md +29 -0
- package/.agents/workflows/refactor.md +29 -0
- package/.agents/workflows/review-code.md +29 -0
- package/.cursorrules +140 -0
- package/.gemini/instructions.md +97 -0
- package/.github/ISSUE_TEMPLATE/v1.7-frontend-work-item.yml +54 -0
- package/.github/copilot-instructions.md +104 -0
- package/.github/workflows/benchmark-detection.yml +38 -0
- package/.github/workflows/frontend-usability-gate.yml +36 -0
- package/.github/workflows/release-gate.yml +32 -0
- package/.github/workflows/sbom-compliance.yml +32 -0
- package/.windsurfrules +106 -0
- package/AGENTS.md +131 -0
- package/CONTRIBUTING.md +136 -0
- package/LICENSE +21 -0
- package/README.md +239 -0
- package/bin/agentic-senior-core.js +1147 -0
- package/mcp.json +29 -0
- package/package.json +50 -0
- package/scripts/detection-benchmark.mjs +138 -0
- package/scripts/frontend-usability-audit.mjs +87 -0
- package/scripts/generate-sbom.mjs +61 -0
- package/scripts/init-project.ps1 +105 -0
- package/scripts/init-project.sh +131 -0
- package/scripts/llm-judge.mjs +664 -0
- package/scripts/release-gate.mjs +116 -0
- package/scripts/validate.mjs +554 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# Blueprint: Observability Stack (OpenTelemetry)
|
|
2
|
+
|
|
3
|
+
> If you can't see it, you can't fix it.
|
|
4
|
+
> Observability is not optional — it's infrastructure.
|
|
5
|
+
|
|
6
|
+
## Tech Stack
|
|
7
|
+
|
|
8
|
+
| Pillar | Standard | Why |
|
|
9
|
+
|--------|----------|-----|
|
|
10
|
+
| **Tracing** | OpenTelemetry SDK | Vendor-neutral, W3C Trace Context |
|
|
11
|
+
| **Metrics** | OpenTelemetry SDK | OTLP export, histogram/counter/gauge |
|
|
12
|
+
| **Logging** | Structured JSON + OTel correlation | traceId in every log line |
|
|
13
|
+
| **Collector** | OpenTelemetry Collector | Pipeline: receive → process → export |
|
|
14
|
+
| **Backend** | Jaeger / Tempo (traces), Prometheus / Mimir (metrics), Loki (logs) | Or cloud: Datadog, Grafana Cloud, New Relic |
|
|
15
|
+
| **Dashboards** | Grafana | Universal visualization |
|
|
16
|
+
|
|
17
|
+
## The Three Pillars
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
┌──────────────────────────────────────────────────────────┐
|
|
21
|
+
│ Your Application │
|
|
22
|
+
│ │
|
|
23
|
+
│ Traces: "What path did this request take?" │
|
|
24
|
+
│ Metrics: "How is the system performing overall?" │
|
|
25
|
+
│ Logs: "What exactly happened at this moment?" │
|
|
26
|
+
│ │
|
|
27
|
+
│ ── All connected by traceId / spanId ── │
|
|
28
|
+
└────────────────────┬─────────────────────────────────────┘
|
|
29
|
+
│ OTLP (gRPC/HTTP)
|
|
30
|
+
┌─────────▼──────────┐
|
|
31
|
+
│ OTel Collector │
|
|
32
|
+
│ (receive/process/ │
|
|
33
|
+
│ export) │
|
|
34
|
+
└────┬────┬────┬─────┘
|
|
35
|
+
│ │ │
|
|
36
|
+
┌─────▼┐ ┌─▼──┐ ┌▼────┐
|
|
37
|
+
│Jaeger│ │Prom│ │Loki │
|
|
38
|
+
│Tempo │ │ │ │ │
|
|
39
|
+
└──────┘ └────┘ └─────┘
|
|
40
|
+
│
|
|
41
|
+
┌──────▼──────┐
|
|
42
|
+
│ Grafana │
|
|
43
|
+
│ (Dashboards) │
|
|
44
|
+
└─────────────┘
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Instrumentation Standards
|
|
48
|
+
|
|
49
|
+
### Auto-Instrumentation First
|
|
50
|
+
|
|
51
|
+
Start with auto-instrumentation for common libraries (HTTP servers, DB clients, message brokers). Add manual instrumentation for business-critical paths.
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
// Node.js: Initialize OpenTelemetry EARLY (before other imports)
|
|
55
|
+
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
56
|
+
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
|
|
57
|
+
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
|
|
58
|
+
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
|
|
59
|
+
|
|
60
|
+
const sdk = new NodeSDK({
|
|
61
|
+
traceExporter: new OTLPTraceExporter({
|
|
62
|
+
url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
|
|
63
|
+
}),
|
|
64
|
+
metricReader: new PeriodicExportingMetricReader({
|
|
65
|
+
exporter: new OTLPMetricExporter(),
|
|
66
|
+
}),
|
|
67
|
+
instrumentations: [getNodeAutoInstrumentations()],
|
|
68
|
+
serviceName: process.env.OTEL_SERVICE_NAME,
|
|
69
|
+
serviceVersion: process.env.APP_VERSION,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
sdk.start();
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Manual Spans for Business Logic
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import { trace } from '@opentelemetry/api';
|
|
79
|
+
|
|
80
|
+
const tracer = trace.getTracer('order-service');
|
|
81
|
+
|
|
82
|
+
async function processOrder(order: Order): Promise<void> {
|
|
83
|
+
return tracer.startActiveSpan('processOrder', async (span) => {
|
|
84
|
+
try {
|
|
85
|
+
span.setAttribute('order.id', order.id);
|
|
86
|
+
span.setAttribute('order.total', order.total);
|
|
87
|
+
span.setAttribute('order.item_count', order.items.length);
|
|
88
|
+
|
|
89
|
+
await validateInventory(order);
|
|
90
|
+
await processPayment(order);
|
|
91
|
+
await updateInventory(order);
|
|
92
|
+
|
|
93
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
94
|
+
} catch (error) {
|
|
95
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
|
|
96
|
+
span.recordException(error);
|
|
97
|
+
throw error;
|
|
98
|
+
} finally {
|
|
99
|
+
span.end();
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Metric Instruments
|
|
106
|
+
|
|
107
|
+
| Type | When | Example |
|
|
108
|
+
|------|------|---------|
|
|
109
|
+
| **Counter** | Monotonically increasing count | `http.requests.total` |
|
|
110
|
+
| **Histogram** | Distribution of values | `http.request.duration` |
|
|
111
|
+
| **Gauge** | Current snapshot value | `system.memory.usage` |
|
|
112
|
+
| **UpDownCounter** | Value that can go up and down | `queue.depth` |
|
|
113
|
+
|
|
114
|
+
### Structured Logging
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
// REQUIRED: Include traceId and spanId in every log
|
|
118
|
+
logger.info('Order processed', {
|
|
119
|
+
traceId: span.spanContext().traceId,
|
|
120
|
+
spanId: span.spanContext().spanId,
|
|
121
|
+
orderId: order.id,
|
|
122
|
+
userId: order.userId,
|
|
123
|
+
durationMs: Date.now() - startTime,
|
|
124
|
+
itemCount: order.items.length,
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Naming Conventions (Semantic Conventions)
|
|
129
|
+
|
|
130
|
+
Follow OpenTelemetry semantic conventions:
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
Metrics: {namespace}.{component}.{metric}
|
|
134
|
+
http.server.request.duration
|
|
135
|
+
db.client.operation.duration
|
|
136
|
+
messaging.publish.duration
|
|
137
|
+
|
|
138
|
+
Spans: {operation} {target}
|
|
139
|
+
GET /api/users
|
|
140
|
+
SELECT users
|
|
141
|
+
PUBLISH order.created
|
|
142
|
+
|
|
143
|
+
Attributes: {namespace}.{attribute}
|
|
144
|
+
http.request.method
|
|
145
|
+
db.system
|
|
146
|
+
service.name
|
|
147
|
+
service.version
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Alerting Strategy
|
|
151
|
+
|
|
152
|
+
### Golden Signals (Monitor These)
|
|
153
|
+
|
|
154
|
+
| Signal | Metric | Alert When |
|
|
155
|
+
|--------|--------|------------|
|
|
156
|
+
| **Latency** | `http.server.request.duration` p99 | > 500ms for 5 min |
|
|
157
|
+
| **Traffic** | `http.server.request.total` rate | Sudden drop > 50% |
|
|
158
|
+
| **Errors** | `http.server.request.error_ratio` | > 1% for 5 min |
|
|
159
|
+
| **Saturation** | CPU, memory, connection pool | > 80% for 10 min |
|
|
160
|
+
|
|
161
|
+
### Alert Rules
|
|
162
|
+
|
|
163
|
+
1. **Page** (wake someone up): Service is DOWN, error rate > 5%, data loss risk
|
|
164
|
+
2. **Alert** (respond this shift): Latency degradation, resource saturation > 80%
|
|
165
|
+
3. **Inform** (check next business day): Slow queries, disk space trending
|
|
166
|
+
|
|
167
|
+
## Collector Configuration
|
|
168
|
+
|
|
169
|
+
```yaml
|
|
170
|
+
# otel-collector-config.yaml
|
|
171
|
+
receivers:
|
|
172
|
+
otlp:
|
|
173
|
+
protocols:
|
|
174
|
+
grpc:
|
|
175
|
+
endpoint: 0.0.0.0:4317
|
|
176
|
+
http:
|
|
177
|
+
endpoint: 0.0.0.0:4318
|
|
178
|
+
|
|
179
|
+
processors:
|
|
180
|
+
batch:
|
|
181
|
+
timeout: 5s
|
|
182
|
+
send_batch_size: 1024
|
|
183
|
+
memory_limiter:
|
|
184
|
+
limit_mib: 512
|
|
185
|
+
spike_limit_mib: 128
|
|
186
|
+
attributes:
|
|
187
|
+
actions:
|
|
188
|
+
- key: environment
|
|
189
|
+
value: ${ENVIRONMENT}
|
|
190
|
+
action: upsert
|
|
191
|
+
|
|
192
|
+
exporters:
|
|
193
|
+
otlphttp/traces:
|
|
194
|
+
endpoint: http://jaeger:4318
|
|
195
|
+
prometheus:
|
|
196
|
+
endpoint: 0.0.0.0:8889
|
|
197
|
+
loki:
|
|
198
|
+
endpoint: http://loki:3100/loki/api/v1/push
|
|
199
|
+
|
|
200
|
+
service:
|
|
201
|
+
pipelines:
|
|
202
|
+
traces:
|
|
203
|
+
receivers: [otlp]
|
|
204
|
+
processors: [memory_limiter, batch]
|
|
205
|
+
exporters: [otlphttp/traces]
|
|
206
|
+
metrics:
|
|
207
|
+
receivers: [otlp]
|
|
208
|
+
processors: [memory_limiter, batch]
|
|
209
|
+
exporters: [prometheus]
|
|
210
|
+
logs:
|
|
211
|
+
receivers: [otlp]
|
|
212
|
+
processors: [memory_limiter, batch, attributes]
|
|
213
|
+
exporters: [loki]
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Scaffolding Checklist
|
|
217
|
+
|
|
218
|
+
- [ ] Install OpenTelemetry SDK for your language
|
|
219
|
+
- [ ] Configure auto-instrumentation for HTTP, DB, messaging
|
|
220
|
+
- [ ] Set `OTEL_SERVICE_NAME` and `OTEL_EXPORTER_OTLP_ENDPOINT` env vars
|
|
221
|
+
- [ ] Add manual spans to business-critical paths
|
|
222
|
+
- [ ] Ensure structured logs include `traceId` and `spanId`
|
|
223
|
+
- [ ] Deploy OpenTelemetry Collector with batch + memory limiter
|
|
224
|
+
- [ ] Configure exporters for traces, metrics, and logs
|
|
225
|
+
- [ ] Set up Grafana dashboards for golden signals
|
|
226
|
+
- [ ] Define alert rules for latency, errors, saturation
|
|
227
|
+
- [ ] Enable W3C Trace Context propagation across services
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# Blueprint: Spring Boot API
|
|
2
|
+
|
|
3
|
+
> Java backend API service using Spring Boot 4.x, Java 25+, Spring Data JPA, and Flyway.
|
|
4
|
+
|
|
5
|
+
## Tech Stack
|
|
6
|
+
|
|
7
|
+
| Layer | Technology |
|
|
8
|
+
|-------|-----------|
|
|
9
|
+
| Framework | Spring Boot 4.x (Spring Framework 7) |
|
|
10
|
+
| Language | Java 25+ (LTS) |
|
|
11
|
+
| Validation | Jakarta Bean Validation |
|
|
12
|
+
| ORM | Spring Data JPA (Hibernate) |
|
|
13
|
+
| Migration | Flyway |
|
|
14
|
+
| Testing | JUnit 5 + Mockito + Testcontainers |
|
|
15
|
+
| DTO mapping | MapStruct |
|
|
16
|
+
| Logging | SLF4J + Logback (JSON) |
|
|
17
|
+
| API docs | springdoc-openapi (Swagger/Scalar) |
|
|
18
|
+
| Build | Gradle (Kotlin DSL) |
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Project Structure
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
project-name/
|
|
26
|
+
├── src/main/java/com/example/project/
|
|
27
|
+
│ ├── Application.java
|
|
28
|
+
│ │
|
|
29
|
+
│ ├── modules/
|
|
30
|
+
│ │ └── user/
|
|
31
|
+
│ │ ├── UserController.java
|
|
32
|
+
│ │ ├── UserService.java
|
|
33
|
+
│ │ ├── UserRepository.java
|
|
34
|
+
│ │ ├── UserMapper.java # MapStruct
|
|
35
|
+
│ │ ├── dto/
|
|
36
|
+
│ │ │ ├── CreateUserRequest.java # record + validation
|
|
37
|
+
│ │ │ └── UserResponse.java # record
|
|
38
|
+
│ │ ├── entity/
|
|
39
|
+
│ │ │ └── UserEntity.java # JPA entity
|
|
40
|
+
│ │ └── exception/
|
|
41
|
+
│ │ └── UserNotFoundException.java
|
|
42
|
+
│ │
|
|
43
|
+
│ └── shared/
|
|
44
|
+
│ ├── config/
|
|
45
|
+
│ │ ├── SecurityConfig.java
|
|
46
|
+
│ │ └── OpenApiConfig.java
|
|
47
|
+
│ ├── exception/
|
|
48
|
+
│ │ ├── AppException.java
|
|
49
|
+
│ │ ├── ErrorCode.java # Enum
|
|
50
|
+
│ │ ├── ErrorResponse.java # record
|
|
51
|
+
│ │ └── GlobalExceptionHandler.java # @ControllerAdvice
|
|
52
|
+
│ └── util/
|
|
53
|
+
│ └── LogContext.java
|
|
54
|
+
│
|
|
55
|
+
├── src/main/resources/
|
|
56
|
+
│ ├── application.yml
|
|
57
|
+
│ ├── application-dev.yml
|
|
58
|
+
│ └── db/migration/
|
|
59
|
+
│ └── V1__create_users_table.sql
|
|
60
|
+
│
|
|
61
|
+
├── src/test/java/com/example/project/
|
|
62
|
+
│ └── modules/user/
|
|
63
|
+
│ ├── UserServiceTest.java # Unit
|
|
64
|
+
│ └── UserControllerIT.java # Integration
|
|
65
|
+
│
|
|
66
|
+
├── build.gradle.kts
|
|
67
|
+
├── settings.gradle.kts
|
|
68
|
+
├── Dockerfile
|
|
69
|
+
└── .env.example
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## File Patterns
|
|
75
|
+
|
|
76
|
+
### Controller — Thin Transport
|
|
77
|
+
```java
|
|
78
|
+
@RestController
|
|
79
|
+
@RequestMapping("/api/v1/users")
|
|
80
|
+
@Tag(name = "Users")
|
|
81
|
+
public class UserController {
|
|
82
|
+
private final UserService userService;
|
|
83
|
+
|
|
84
|
+
public UserController(UserService userService) {
|
|
85
|
+
this.userService = userService;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@PostMapping
|
|
89
|
+
@ResponseStatus(HttpStatus.CREATED)
|
|
90
|
+
@Operation(summary = "Create a user account")
|
|
91
|
+
@ApiResponse(responseCode = "201", description = "User created")
|
|
92
|
+
@ApiResponse(responseCode = "400", description = "Validation error")
|
|
93
|
+
@ApiResponse(responseCode = "409", description = "Email already exists")
|
|
94
|
+
public UserResponse create(@Valid @RequestBody CreateUserRequest request) {
|
|
95
|
+
return userService.create(request);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@GetMapping
|
|
99
|
+
@Operation(summary = "List users with pagination")
|
|
100
|
+
public Page<UserResponse> list(Pageable pageable) {
|
|
101
|
+
return userService.list(pageable);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### DTOs — Records with Validation
|
|
107
|
+
```java
|
|
108
|
+
public record CreateUserRequest(
|
|
109
|
+
@NotBlank @Size(max = 100)
|
|
110
|
+
@Schema(description = "Display name", example = "Jane Doe")
|
|
111
|
+
String name,
|
|
112
|
+
|
|
113
|
+
@NotBlank @Email
|
|
114
|
+
@Schema(description = "Unique email address", example = "jane@example.com")
|
|
115
|
+
String email,
|
|
116
|
+
|
|
117
|
+
@NotBlank @Size(min = 8)
|
|
118
|
+
String password
|
|
119
|
+
) {}
|
|
120
|
+
|
|
121
|
+
public record UserResponse(
|
|
122
|
+
UUID id,
|
|
123
|
+
String name,
|
|
124
|
+
String email,
|
|
125
|
+
Instant createdAt
|
|
126
|
+
) {}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Service — Business Logic
|
|
130
|
+
```java
|
|
131
|
+
@Service
|
|
132
|
+
@Transactional
|
|
133
|
+
public class UserService {
|
|
134
|
+
private static final Logger log = LoggerFactory.getLogger(UserService.class);
|
|
135
|
+
|
|
136
|
+
private final UserRepository userRepository;
|
|
137
|
+
private final UserMapper userMapper;
|
|
138
|
+
private final PasswordEncoder passwordEncoder;
|
|
139
|
+
|
|
140
|
+
public UserService(UserRepository userRepository, UserMapper userMapper,
|
|
141
|
+
PasswordEncoder passwordEncoder) {
|
|
142
|
+
this.userRepository = userRepository;
|
|
143
|
+
this.userMapper = userMapper;
|
|
144
|
+
this.passwordEncoder = passwordEncoder;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
public UserResponse create(CreateUserRequest request) {
|
|
148
|
+
if (userRepository.existsByEmail(request.email())) {
|
|
149
|
+
throw new AppException(ErrorCode.USER_ALREADY_EXISTS,
|
|
150
|
+
"Email already registered: " + request.email());
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
UserEntity entity = userMapper.toEntity(request);
|
|
154
|
+
entity.setPassword(passwordEncoder.encode(request.password()));
|
|
155
|
+
|
|
156
|
+
UserEntity saved = userRepository.save(entity);
|
|
157
|
+
log.info("User created: id={}, email={}", saved.getId(), saved.getEmail());
|
|
158
|
+
|
|
159
|
+
return userMapper.toResponse(saved);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
@Transactional(readOnly = true)
|
|
163
|
+
public Page<UserResponse> list(Pageable pageable) {
|
|
164
|
+
return userRepository.findAll(pageable).map(userMapper::toResponse);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Global Error Handler
|
|
170
|
+
```java
|
|
171
|
+
@ControllerAdvice
|
|
172
|
+
public class GlobalExceptionHandler {
|
|
173
|
+
|
|
174
|
+
@ExceptionHandler(AppException.class)
|
|
175
|
+
public ResponseEntity<ErrorResponse> handleAppException(AppException ex) {
|
|
176
|
+
return ResponseEntity
|
|
177
|
+
.status(ex.getHttpStatus())
|
|
178
|
+
.body(new ErrorResponse(ex.getCode().name(), ex.getMessage()));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
@ExceptionHandler(MethodArgumentNotValidException.class)
|
|
182
|
+
public ResponseEntity<ErrorResponse> handleValidation(MethodArgumentNotValidException ex) {
|
|
183
|
+
var details = ex.getFieldErrors().stream()
|
|
184
|
+
.map(e -> new ErrorResponse.FieldError(e.getField(), e.getDefaultMessage()))
|
|
185
|
+
.toList();
|
|
186
|
+
return ResponseEntity.badRequest()
|
|
187
|
+
.body(new ErrorResponse("VALIDATION_ERROR", "Invalid input", details));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
public record ErrorResponse(
|
|
192
|
+
String code,
|
|
193
|
+
String message,
|
|
194
|
+
List<FieldError> details
|
|
195
|
+
) {
|
|
196
|
+
public ErrorResponse(String code, String message) {
|
|
197
|
+
this(code, message, List.of());
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
public record FieldError(String field, String message) {}
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Scaffolding Checklist
|
|
207
|
+
|
|
208
|
+
- [ ] Initialize with Spring Initializr (Web, JPA, Validation, Security, Flyway)
|
|
209
|
+
- [ ] Set up modular structure under `modules/`
|
|
210
|
+
- [ ] Configure `application.yml` with profiles (dev, staging, prod)
|
|
211
|
+
- [ ] Create `GlobalExceptionHandler` with `@ControllerAdvice`
|
|
212
|
+
- [ ] Create `AppException` + `ErrorCode` enum
|
|
213
|
+
- [ ] Set up Flyway with initial migration
|
|
214
|
+
- [ ] Configure springdoc-openapi for API docs
|
|
215
|
+
- [ ] Create first module following the pattern
|
|
216
|
+
- [ ] Set up MapStruct for DTO mapping
|
|
217
|
+
- [ ] Create unit + integration tests
|
|
218
|
+
- [ ] Run `./gradlew test` — zero failures
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"selectedProfile": "balanced",
|
|
3
|
+
"profileThresholds": {
|
|
4
|
+
"beginner": {
|
|
5
|
+
"blockingSeverities": ["critical"],
|
|
6
|
+
"failOnMalformedResponse": false,
|
|
7
|
+
"failOnProviderError": false
|
|
8
|
+
},
|
|
9
|
+
"balanced": {
|
|
10
|
+
"blockingSeverities": ["critical", "high"],
|
|
11
|
+
"failOnMalformedResponse": true,
|
|
12
|
+
"failOnProviderError": false
|
|
13
|
+
},
|
|
14
|
+
"strict": {
|
|
15
|
+
"blockingSeverities": ["critical", "high", "medium"],
|
|
16
|
+
"failOnMalformedResponse": true,
|
|
17
|
+
"failOnProviderError": true
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Team Profile Pack: Platform
|
|
2
|
+
|
|
3
|
+
slug: platform
|
|
4
|
+
displayName: Platform Team
|
|
5
|
+
description: Reliability-oriented defaults for shared platform modules across teams.
|
|
6
|
+
defaultProfile: balanced
|
|
7
|
+
defaultStack: go.md
|
|
8
|
+
defaultBlueprint: go-service.md
|
|
9
|
+
ciGuardrails: true
|
|
10
|
+
lockCi: false
|
|
11
|
+
blockingSeverities: critical, high
|
|
12
|
+
owner: platform-foundation
|
|
13
|
+
lastUpdated: 2026-03-19
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Team Profile Pack: Regulated
|
|
2
|
+
|
|
3
|
+
slug: regulated
|
|
4
|
+
displayName: Regulated Team
|
|
5
|
+
description: Compliance-first defaults with strict policy and locked CI guardrails.
|
|
6
|
+
defaultProfile: strict
|
|
7
|
+
defaultStack: typescript.md
|
|
8
|
+
defaultBlueprint: api-nextjs.md
|
|
9
|
+
ciGuardrails: true
|
|
10
|
+
lockCi: true
|
|
11
|
+
blockingSeverities: critical, high, medium
|
|
12
|
+
owner: governance-office
|
|
13
|
+
lastUpdated: 2026-03-19
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Team Profile Pack: Startup
|
|
2
|
+
|
|
3
|
+
slug: startup
|
|
4
|
+
displayName: Startup Team
|
|
5
|
+
description: Fast iteration with balanced guardrails and quick onboarding defaults.
|
|
6
|
+
defaultProfile: balanced
|
|
7
|
+
defaultStack: typescript.md
|
|
8
|
+
defaultBlueprint: api-nextjs.md
|
|
9
|
+
ciGuardrails: true
|
|
10
|
+
lockCi: false
|
|
11
|
+
blockingSeverities: critical, high
|
|
12
|
+
owner: product-engineering
|
|
13
|
+
lastUpdated: 2026-03-19
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Prompts: Initialize Project
|
|
2
|
+
|
|
3
|
+
> Copy-paste one of these prompts to your AI agent (Cursor, Windsurf, Copilot, Antigravity) right after cloning this repository.
|
|
4
|
+
> V1.4 recommendation: run `bunx @fatidaprilian/agentic-senior-core init` first to compile dynamic governance context.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Option 1: The Architect Prompt (Recommended)
|
|
9
|
+
Use this when you have an idea, but want the AI to choose the most efficient stack and framework based on this repository's engineering standards.
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
I want to build a [DESCRIBE YOUR PROJECT AND MAIN FEATURES HERE].
|
|
13
|
+
|
|
14
|
+
Context: You are a Principal Software Architect operating in a workspace with strict engineering standards.
|
|
15
|
+
|
|
16
|
+
Step 1: Context Gathering
|
|
17
|
+
1. Read `AGENTS.md` to understand your role and available knowledge base.
|
|
18
|
+
2. Scan all files in `.agent-context/rules/` to understand our mandatory engineering laws.
|
|
19
|
+
3. Review the available technology stacks in `.agent-context/stacks/` and blueprints in `.agent-context/blueprints/`.
|
|
20
|
+
|
|
21
|
+
Step 2: Architecture Proposal
|
|
22
|
+
Based strictly on my project description and our repository's existing rules (especially `efficiency-vs-hype.md`):
|
|
23
|
+
1. Propose the most efficient technology stack from our approved profiles.
|
|
24
|
+
2. Explain WHY this stack is the best choice for this specific project.
|
|
25
|
+
3. Draft a high-level architecture plan.
|
|
26
|
+
|
|
27
|
+
Do not write any application code yet. Write your proposal and wait for my approval. Once I approve, you will scaffold the project using the relevant blueprint.
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Option 2: The Direct Blueprint Prompt
|
|
33
|
+
Use this when you already know exactly which framework you want to use from the available blueprints.
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
I want to build [PROJECT NAME].
|
|
37
|
+
|
|
38
|
+
Before writing any code:
|
|
39
|
+
1. Read `AGENTS.md` to understand your role.
|
|
40
|
+
2. Read ALL files in `.agent-context/rules/` to understand our engineering standards.
|
|
41
|
+
3. Read `.agent-context/stacks/[STACK].md` for language-specific guidelines.
|
|
42
|
+
4. Read `.agent-context/blueprints/[BLUEPRINT].md` for the project structure.
|
|
43
|
+
|
|
44
|
+
Now scaffold the initial project structure following the blueprint exactly:
|
|
45
|
+
- Create all directories and files from the blueprint
|
|
46
|
+
- Set up the environment config and validation (e.g., Zod, Pydantic, FluentValidation)
|
|
47
|
+
- Set up the error handling foundation (base error class + global handler)
|
|
48
|
+
- Set up the logger
|
|
49
|
+
- Create a health check endpoint
|
|
50
|
+
- Initialize the ORM/Database connection
|
|
51
|
+
|
|
52
|
+
Every file MUST follow the naming conventions from rules/naming-conv.md.
|
|
53
|
+
Every module MUST follow the architecture from rules/architecture.md.
|
|
54
|
+
Every dependency MUST be justified per rules/efficiency-vs-hype.md.
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Available Stacks & Blueprints Reference
|
|
60
|
+
|
|
61
|
+
### Stacks (`[STACK].md`)
|
|
62
|
+
- `typescript`
|
|
63
|
+
- `python`
|
|
64
|
+
- `java`
|
|
65
|
+
- `php`
|
|
66
|
+
- `go`
|
|
67
|
+
- `csharp`
|
|
68
|
+
- `rust`
|
|
69
|
+
- `ruby`
|
|
70
|
+
|
|
71
|
+
### Blueprints (`[BLUEPRINT].md`)
|
|
72
|
+
| Blueprint | Use When |
|
|
73
|
+
|-----------|----------|
|
|
74
|
+
| `api-nextjs` | Next.js App Router API project |
|
|
75
|
+
| `nestjs-logic` | NestJS backend service |
|
|
76
|
+
| `fastapi-service` | Python FastAPI backend service |
|
|
77
|
+
| `laravel-api` | PHP Laravel 12 API |
|
|
78
|
+
| `spring-boot-api`| Java Spring Boot 4 API |
|
|
79
|
+
| `go-service` | Go chi HTTP service |
|
|
80
|
+
| `aspnet-api` | C# ASP.NET Minimal API |
|
|
81
|
+
| `ci-github-actions`| GitHub Actions CI/CD pipeline |
|
|
82
|
+
| `ci-gitlab` | GitLab CI/CD pipeline |
|
|
83
|
+
| `observability` | OpenTelemetry stack |
|
|
84
|
+
| `graphql-grpc-api` | GraphQL / gRPC API definitions |
|
|
85
|
+
| `infrastructure-as-code` | Infrastructure as Code (Terraform | Pulumi) |
|
|
86
|
+
| `kubernetes-manifests` | Kubernetes manifests structure |
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Prompt: Refactor Code
|
|
2
|
+
|
|
3
|
+
> Copy-paste this prompt when code needs restructuring to follow the rules.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## The Prompt
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
Refactor the following code (or module) to comply with our engineering standards.
|
|
11
|
+
|
|
12
|
+
Before making changes:
|
|
13
|
+
1. Read .agent-context/rules/architecture.md — ensure proper layer separation.
|
|
14
|
+
2. Read .agent-context/rules/naming-conv.md — fix all naming violations.
|
|
15
|
+
3. Read .agent-context/rules/error-handling.md — fix error handling patterns.
|
|
16
|
+
4. Read .agent-context/stacks/typescript.md — fix TypeScript-specific issues.
|
|
17
|
+
|
|
18
|
+
For every change you make, provide a Reasoning Chain:
|
|
19
|
+
- What was wrong (rule reference)
|
|
20
|
+
- Why it was wrong (explain the risk/problem)
|
|
21
|
+
- What you changed (show the improvement)
|
|
22
|
+
|
|
23
|
+
Maintain ALL existing functionality. This is a refactor, not a rewrite.
|
|
24
|
+
Add or update tests if the refactored code changes behavior contracts.
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Extract Module Prompt
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
Extract [FEATURE_NAME] into its own module following .agent-context/rules/architecture.md:
|
|
31
|
+
|
|
32
|
+
1. Create the module directory: src/modules/[feature-name]/
|
|
33
|
+
2. Separate into layers:
|
|
34
|
+
- controller (transport — HTTP in/out only)
|
|
35
|
+
- service (business logic — no HTTP, no SQL)
|
|
36
|
+
- repository (data access — no business rules)
|
|
37
|
+
- dto (Zod schemas for input validation)
|
|
38
|
+
- types (type definitions)
|
|
39
|
+
3. Create barrel export (index.ts) exposing ONLY the public API
|
|
40
|
+
4. Update imports in consuming modules to use the new module path
|
|
41
|
+
5. Add unit tests for the service layer
|
|
42
|
+
|
|
43
|
+
Follow naming-conv.md for all file and variable names.
|
|
44
|
+
Provide a Reasoning Chain for every structural decision.
|
|
45
|
+
```
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Prompt: Review Code
|
|
2
|
+
|
|
3
|
+
> Copy-paste this prompt when you want the AI to self-review its own code
|
|
4
|
+
> or review code you've written.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## The Prompt
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
Run a comprehensive code review on the current codebase (or the files I'm about to show you).
|
|
12
|
+
|
|
13
|
+
Use these checklists:
|
|
14
|
+
1. Read .agent-context/review-checklists/pr-checklist.md — apply every item.
|
|
15
|
+
2. Read .agent-context/review-checklists/security-audit.md — apply every item.
|
|
16
|
+
|
|
17
|
+
For EVERY violation found:
|
|
18
|
+
- State the exact file and line
|
|
19
|
+
- Reference the specific rule (file + section)
|
|
20
|
+
- Explain WHY it's a problem (not just "it violates the rule")
|
|
21
|
+
- Provide the corrected code
|
|
22
|
+
|
|
23
|
+
Output format:
|
|
24
|
+
## PR REVIEW RESULTS
|
|
25
|
+
✅ [Item] — Passes
|
|
26
|
+
❌ [Item] — FAILS (with Reasoning Chain)
|
|
27
|
+
|
|
28
|
+
## SECURITY AUDIT RESULTS
|
|
29
|
+
🔴/🟠/🟡/🟢 [Finding] — severity + fix
|
|
30
|
+
|
|
31
|
+
VERDICT: PASS / FAIL
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick Review (Subset)
|
|
35
|
+
|
|
36
|
+
If you want a faster review focusing on the most critical items:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
Quick review the current code. Check ONLY:
|
|
40
|
+
1. Any use of `any` type? (rules/stacks/typescript.md)
|
|
41
|
+
2. Any empty catch blocks? (rules/error-handling.md)
|
|
42
|
+
3. Any N+1 queries? (rules/performance.md)
|
|
43
|
+
4. Any hardcoded secrets? (rules/security.md)
|
|
44
|
+
5. Any missing input validation? (rules/security.md)
|
|
45
|
+
|
|
46
|
+
Use the Reasoning Clause for every finding.
|
|
47
|
+
```
|