dojo.md 0.1.0 → 0.2.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/courses/GENERATION_LOG.md +27 -0
- package/courses/api-error-handling/course.yaml +16 -0
- package/courses/api-error-handling/scenarios/level-1/error-response-format.yaml +131 -0
- package/courses/api-error-handling/scenarios/level-1/http-status-codes-basics.yaml +90 -0
- package/courses/api-error-handling/scenarios/level-1/rate-limiting-basics.yaml +135 -0
- package/courses/api-error-handling/scenarios/level-1/request-validation-errors.yaml +208 -0
- package/courses/api-error-handling/scenarios/level-2/circuit-breaker-pattern.yaml +189 -0
- package/courses/api-error-handling/scenarios/level-2/idempotency-retry-logic.yaml +159 -0
- package/courses/api-error-handling/scenarios/level-2/rfc-7807-problem-details.yaml +178 -0
- package/courses/api-error-handling/scenarios/level-2/webhook-error-handling.yaml +211 -0
- package/courses/api-error-handling/scenarios/level-3/distributed-tracing-errors.yaml +275 -0
- package/courses/github-actions-cicd/course.yaml +10 -0
- package/courses/github-actions-cicd/scenarios/level-1/actions-and-runners.yaml +58 -0
- package/courses/github-actions-cicd/scenarios/level-1/basic-workflow-syntax.yaml +52 -0
- package/courses/github-actions-cicd/scenarios/level-1/branch-protection-checks.yaml +63 -0
- package/courses/github-actions-cicd/scenarios/level-1/environment-variables-secrets.yaml +65 -0
- package/courses/github-actions-cicd/scenarios/level-1/first-cicd-shift.yaml +62 -0
- package/courses/github-actions-cicd/scenarios/level-1/job-dependencies-outputs.yaml +62 -0
- package/courses/github-actions-cicd/scenarios/level-1/simple-ci-pipeline.yaml +57 -0
- package/courses/github-actions-cicd/scenarios/level-1/workflow-debugging.yaml +90 -0
- package/courses/github-actions-cicd/scenarios/level-1/workflow-status-notifications.yaml +59 -0
- package/courses/github-actions-cicd/scenarios/level-1/workflow-triggers.yaml +56 -0
- package/courses/github-actions-cicd/scenarios/level-2/concurrency-control.yaml +58 -0
- package/courses/github-actions-cicd/scenarios/level-2/conditional-execution.yaml +60 -0
- package/courses/github-actions-cicd/scenarios/level-2/custom-actions-development.yaml +55 -0
- package/courses/github-actions-cicd/scenarios/level-2/dependency-caching.yaml +58 -0
- package/courses/github-actions-cicd/scenarios/level-2/deployment-workflows.yaml +61 -0
- package/courses/github-actions-cicd/scenarios/level-2/github-packages-publishing.yaml +59 -0
- package/courses/github-actions-cicd/scenarios/level-2/intermediate-cicd-shift.yaml +68 -0
- package/courses/github-actions-cicd/scenarios/level-2/matrix-builds.yaml +59 -0
- package/courses/github-actions-cicd/scenarios/level-2/reusable-workflows.yaml +61 -0
- package/courses/github-actions-cicd/scenarios/level-2/workflow-cost-optimization.yaml +61 -0
- package/courses/github-actions-cicd/scenarios/level-3/advanced-cicd-shift.yaml +64 -0
- package/courses/github-actions-cicd/scenarios/level-3/compliance-automation.yaml +68 -0
- package/courses/github-actions-cicd/scenarios/level-3/docker-action-development.yaml +65 -0
- package/courses/github-actions-cicd/scenarios/level-3/github-environments.yaml +65 -0
- package/courses/github-actions-cicd/scenarios/level-3/monorepo-ci.yaml +68 -0
- package/courses/github-actions-cicd/scenarios/level-3/oidc-cloud-deployments.yaml +55 -0
- package/courses/github-actions-cicd/scenarios/level-3/release-automation.yaml +61 -0
- package/courses/github-actions-cicd/scenarios/level-3/security-hardening.yaml +63 -0
- package/courses/github-actions-cicd/scenarios/level-3/self-hosted-runners.yaml +60 -0
- package/courses/github-actions-cicd/scenarios/level-3/workflow-optimization.yaml +59 -0
- package/courses/github-actions-cicd/scenarios/level-4/cicd-data-architecture.yaml +63 -0
- package/courses/github-actions-cicd/scenarios/level-4/cicd-economics-roi.yaml +63 -0
- package/courses/github-actions-cicd/scenarios/level-4/cicd-executive-communication.yaml +58 -0
- package/courses/github-actions-cicd/scenarios/level-4/cicd-incident-response.yaml +60 -0
- package/courses/github-actions-cicd/scenarios/level-4/cicd-org-design.yaml +59 -0
- package/courses/github-actions-cicd/scenarios/level-4/cicd-platform-architecture.yaml +63 -0
- package/courses/github-actions-cicd/scenarios/level-4/cicd-training-program.yaml +65 -0
- package/courses/github-actions-cicd/scenarios/level-4/cicd-vendor-evaluation.yaml +59 -0
- package/courses/github-actions-cicd/scenarios/level-4/enterprise-cicd-governance.yaml +55 -0
- package/courses/github-actions-cicd/scenarios/level-4/expert-cicd-shift.yaml +60 -0
- package/courses/github-actions-cicd/scenarios/level-5/cicd-ai-future.yaml +63 -0
- package/courses/github-actions-cicd/scenarios/level-5/cicd-behavioral-science.yaml +70 -0
- package/courses/github-actions-cicd/scenarios/level-5/cicd-board-strategy.yaml +56 -0
- package/courses/github-actions-cicd/scenarios/level-5/cicd-consulting-engagement.yaml +61 -0
- package/courses/github-actions-cicd/scenarios/level-5/cicd-industry-benchmarks.yaml +63 -0
- package/courses/github-actions-cicd/scenarios/level-5/cicd-ma-integration.yaml +73 -0
- package/courses/github-actions-cicd/scenarios/level-5/cicd-product-development.yaml +68 -0
- package/courses/github-actions-cicd/scenarios/level-5/cicd-regulatory-landscape.yaml +72 -0
- package/courses/github-actions-cicd/scenarios/level-5/comprehensive-cicd-system.yaml +66 -0
- package/courses/github-actions-cicd/scenarios/level-5/master-cicd-shift.yaml +76 -0
- package/courses/github-pr-review/scenarios/level-2/api-change-review.yaml +82 -0
- package/courses/github-pr-review/scenarios/level-2/automated-review-tooling.yaml +53 -0
- package/courses/github-pr-review/scenarios/level-2/cross-team-review.yaml +61 -0
- package/courses/github-pr-review/scenarios/level-2/intermediate-review-shift.yaml +66 -0
- package/courses/github-pr-review/scenarios/level-2/performance-review-patterns.yaml +99 -0
- package/courses/github-pr-review/scenarios/level-2/review-disagreement-resolution.yaml +64 -0
- package/courses/github-pr-review/scenarios/level-2/review-metrics-analysis.yaml +63 -0
- package/courses/github-pr-review/scenarios/level-2/review-turnaround-sla.yaml +54 -0
- package/courses/github-pr-review/scenarios/level-2/stacked-pr-review.yaml +65 -0
- package/courses/github-pr-review/scenarios/level-3/advanced-review-shift.yaml +65 -0
- package/courses/github-pr-review/scenarios/level-3/ai-powered-review.yaml +58 -0
- package/courses/github-pr-review/scenarios/level-3/compliance-review-process.yaml +64 -0
- package/courses/github-pr-review/scenarios/level-3/cross-functional-review.yaml +60 -0
- package/courses/github-pr-review/scenarios/level-3/incident-driven-review.yaml +63 -0
- package/courses/github-pr-review/scenarios/level-3/large-scale-review-operations.yaml +55 -0
- package/courses/github-pr-review/scenarios/level-3/monorepo-review-process.yaml +68 -0
- package/courses/github-pr-review/scenarios/level-3/review-automation-platform.yaml +61 -0
- package/courses/github-pr-review/scenarios/level-3/review-culture-design.yaml +62 -0
- package/courses/github-pr-review/scenarios/level-3/review-data-pipeline.yaml +62 -0
- package/courses/github-pr-review/scenarios/level-4/enterprise-review-operations.yaml +61 -0
- package/courses/github-pr-review/scenarios/level-4/expert-review-shift.yaml +62 -0
- package/courses/github-pr-review/scenarios/level-4/review-data-architecture.yaml +69 -0
- package/courses/github-pr-review/scenarios/level-4/review-economics-roi.yaml +63 -0
- package/courses/github-pr-review/scenarios/level-4/review-executive-communication.yaml +61 -0
- package/courses/github-pr-review/scenarios/level-4/review-incident-postmortem.yaml +69 -0
- package/courses/github-pr-review/scenarios/level-4/review-org-design.yaml +62 -0
- package/courses/github-pr-review/scenarios/level-4/review-platform-architecture.yaml +64 -0
- package/courses/github-pr-review/scenarios/level-4/review-training-program.yaml +66 -0
- package/courses/github-pr-review/scenarios/level-4/review-vendor-evaluation.yaml +76 -0
- package/courses/github-pr-review/scenarios/level-5/comprehensive-review-system.yaml +68 -0
- package/courses/github-pr-review/scenarios/level-5/master-review-shift.yaml +73 -0
- package/courses/github-pr-review/scenarios/level-5/review-ai-future.yaml +69 -0
- package/courses/github-pr-review/scenarios/level-5/review-behavioral-science.yaml +66 -0
- package/courses/github-pr-review/scenarios/level-5/review-board-strategy.yaml +62 -0
- package/courses/github-pr-review/scenarios/level-5/review-consulting-engagement.yaml +62 -0
- package/courses/github-pr-review/scenarios/level-5/review-devtools-product.yaml +71 -0
- package/courses/github-pr-review/scenarios/level-5/review-industry-benchmarks.yaml +64 -0
- package/courses/github-pr-review/scenarios/level-5/review-ma-integration.yaml +76 -0
- package/courses/github-pr-review/scenarios/level-5/review-regulatory-landscape.yaml +78 -0
- package/courses/postgresql-query-optimization/course.yaml +11 -0
- package/courses/postgresql-query-optimization/scenarios/level-1/explain-analyze-basics.yaml +80 -0
- package/courses/postgresql-query-optimization/scenarios/level-1/first-optimization-shift.yaml +77 -0
- package/courses/postgresql-query-optimization/scenarios/level-1/index-fundamentals.yaml +76 -0
- package/courses/postgresql-query-optimization/scenarios/level-1/join-basics.yaml +73 -0
- package/courses/postgresql-query-optimization/scenarios/level-1/n-plus-one-queries.yaml +62 -0
- package/courses/postgresql-query-optimization/scenarios/level-1/query-rewriting-basics.yaml +69 -0
- package/courses/postgresql-query-optimization/scenarios/level-1/select-star-problems.yaml +69 -0
- package/courses/postgresql-query-optimization/scenarios/level-1/slow-query-diagnosis.yaml +63 -0
- package/courses/postgresql-query-optimization/scenarios/level-1/vacuum-and-statistics.yaml +62 -0
- package/courses/postgresql-query-optimization/scenarios/level-1/where-clause-optimization.yaml +74 -0
- package/courses/postgresql-query-optimization/scenarios/level-2/autovacuum-tuning.yaml +76 -0
- package/courses/postgresql-query-optimization/scenarios/level-2/composite-index-design.yaml +81 -0
- package/courses/postgresql-query-optimization/scenarios/level-2/covering-indexes.yaml +74 -0
- package/courses/postgresql-query-optimization/scenarios/level-2/cte-optimization.yaml +83 -0
- package/courses/postgresql-query-optimization/scenarios/level-2/intermediate-optimization-shift.yaml +66 -0
- package/courses/postgresql-query-optimization/scenarios/level-2/join-optimization.yaml +72 -0
- package/courses/postgresql-query-optimization/scenarios/level-2/partial-and-expression-indexes.yaml +75 -0
- package/courses/postgresql-query-optimization/scenarios/level-2/query-planner-settings.yaml +62 -0
- package/courses/postgresql-query-optimization/scenarios/level-2/subquery-optimization.yaml +67 -0
- package/courses/postgresql-query-optimization/scenarios/level-2/window-function-optimization.yaml +63 -0
- package/courses/postgresql-query-optimization/scenarios/level-3/advanced-optimization-shift.yaml +71 -0
- package/courses/postgresql-query-optimization/scenarios/level-3/connection-pooling.yaml +60 -0
- package/courses/postgresql-query-optimization/scenarios/level-3/full-text-search-optimization.yaml +66 -0
- package/courses/postgresql-query-optimization/scenarios/level-3/jsonb-optimization.yaml +88 -0
- package/courses/postgresql-query-optimization/scenarios/level-3/lock-contention-analysis.yaml +80 -0
- package/courses/postgresql-query-optimization/scenarios/level-3/materialized-view-optimization.yaml +73 -0
- package/courses/postgresql-query-optimization/scenarios/level-3/parallel-query-execution.yaml +74 -0
- package/courses/postgresql-query-optimization/scenarios/level-3/partitioning-strategies.yaml +71 -0
- package/courses/postgresql-query-optimization/scenarios/level-3/specialized-index-types.yaml +67 -0
- package/courses/postgresql-query-optimization/scenarios/level-3/write-optimization.yaml +65 -0
- package/courses/postgresql-query-optimization/scenarios/level-4/data-architecture-analytics.yaml +64 -0
- package/courses/postgresql-query-optimization/scenarios/level-4/database-executive-communication.yaml +64 -0
- package/courses/postgresql-query-optimization/scenarios/level-4/database-migration-planning.yaml +57 -0
- package/courses/postgresql-query-optimization/scenarios/level-4/enterprise-database-governance.yaml +52 -0
- package/courses/postgresql-query-optimization/scenarios/level-4/expert-optimization-shift.yaml +73 -0
- package/courses/postgresql-query-optimization/scenarios/level-4/high-availability-architecture.yaml +62 -0
- package/courses/postgresql-query-optimization/scenarios/level-4/optimizer-internals.yaml +69 -0
- package/courses/postgresql-query-optimization/scenarios/level-4/performance-sla-design.yaml +58 -0
- package/courses/postgresql-query-optimization/scenarios/level-4/read-replica-optimization.yaml +62 -0
- package/courses/postgresql-query-optimization/scenarios/level-4/vendor-evaluation.yaml +73 -0
- package/courses/rest-api-error-handling/course.yaml +11 -0
- package/courses/rest-api-error-handling/scenarios/level-1/authentication-errors.yaml +71 -0
- package/courses/rest-api-error-handling/scenarios/level-1/content-negotiation-errors.yaml +63 -0
- package/courses/rest-api-error-handling/scenarios/level-1/error-logging-basics.yaml +63 -0
- package/courses/rest-api-error-handling/scenarios/level-1/error-response-format.yaml +58 -0
- package/courses/rest-api-error-handling/scenarios/level-1/first-error-handling-shift.yaml +67 -0
- package/courses/rest-api-error-handling/scenarios/level-1/http-status-codes.yaml +46 -0
- package/courses/rest-api-error-handling/scenarios/level-1/not-found-errors.yaml +52 -0
- package/courses/rest-api-error-handling/scenarios/level-1/rate-limiting-errors.yaml +56 -0
- package/courses/rest-api-error-handling/scenarios/level-1/request-validation-errors.yaml +59 -0
- package/courses/rest-api-error-handling/scenarios/level-1/server-error-handling.yaml +55 -0
- package/courses/rest-api-error-handling/scenarios/level-2/api-versioning-errors.yaml +66 -0
- package/courses/rest-api-error-handling/scenarios/level-2/batch-request-errors.yaml +61 -0
- package/courses/rest-api-error-handling/scenarios/level-2/circuit-breaker-pattern.yaml +52 -0
- package/courses/rest-api-error-handling/scenarios/level-2/error-code-taxonomy.yaml +62 -0
- package/courses/rest-api-error-handling/scenarios/level-2/error-monitoring-alerting.yaml +53 -0
- package/courses/rest-api-error-handling/scenarios/level-2/intermediate-error-shift.yaml +69 -0
- package/courses/rest-api-error-handling/scenarios/level-2/pagination-errors.yaml +66 -0
- package/courses/rest-api-error-handling/scenarios/level-2/retry-and-idempotency.yaml +60 -0
- package/courses/rest-api-error-handling/scenarios/level-2/rfc7807-problem-details.yaml +60 -0
- package/courses/rest-api-error-handling/scenarios/level-2/webhook-error-handling.yaml +55 -0
- package/courses/rest-api-error-handling/scenarios/level-3/advanced-error-shift.yaml +72 -0
- package/courses/rest-api-error-handling/scenarios/level-3/api-gateway-errors.yaml +71 -0
- package/courses/rest-api-error-handling/scenarios/level-3/async-api-errors.yaml +67 -0
- package/courses/rest-api-error-handling/scenarios/level-3/caching-error-scenarios.yaml +65 -0
- package/courses/rest-api-error-handling/scenarios/level-3/chaos-engineering-apis.yaml +62 -0
- package/courses/rest-api-error-handling/scenarios/level-3/database-error-handling.yaml +79 -0
- package/courses/rest-api-error-handling/scenarios/level-3/distributed-error-propagation.yaml +63 -0
- package/courses/rest-api-error-handling/scenarios/level-3/error-budgets-sre.yaml +61 -0
- package/courses/rest-api-error-handling/scenarios/level-3/error-correlation.yaml +58 -0
- package/courses/rest-api-error-handling/scenarios/level-3/graphql-vs-rest-errors.yaml +73 -0
- package/courses/rest-api-error-handling/scenarios/level-4/compliance-error-handling.yaml +65 -0
- package/courses/rest-api-error-handling/scenarios/level-4/enterprise-error-governance.yaml +62 -0
- package/courses/rest-api-error-handling/scenarios/level-4/error-analytics-platform.yaml +65 -0
- package/courses/rest-api-error-handling/scenarios/level-4/error-cost-optimization.yaml +63 -0
- package/courses/rest-api-error-handling/scenarios/level-4/error-executive-communication.yaml +60 -0
- package/courses/rest-api-error-handling/scenarios/level-4/error-handling-architecture.yaml +67 -0
- package/courses/rest-api-error-handling/scenarios/level-4/error-org-design.yaml +68 -0
- package/courses/rest-api-error-handling/scenarios/level-4/error-sla-design.yaml +65 -0
- package/courses/rest-api-error-handling/scenarios/level-4/error-training-program.yaml +61 -0
- package/courses/rest-api-error-handling/scenarios/level-4/expert-error-shift.yaml +63 -0
- package/courses/rest-api-error-handling/scenarios/level-5/comprehensive-error-system.yaml +68 -0
- package/courses/rest-api-error-handling/scenarios/level-5/error-ai-future.yaml +75 -0
- package/courses/rest-api-error-handling/scenarios/level-5/error-behavioral-science.yaml +73 -0
- package/courses/rest-api-error-handling/scenarios/level-5/error-board-strategy.yaml +60 -0
- package/courses/rest-api-error-handling/scenarios/level-5/error-consulting-engagement.yaml +58 -0
- package/courses/rest-api-error-handling/scenarios/level-5/error-industry-benchmarks.yaml +72 -0
- package/courses/rest-api-error-handling/scenarios/level-5/error-ma-integration.yaml +68 -0
- package/courses/rest-api-error-handling/scenarios/level-5/error-product-development.yaml +66 -0
- package/courses/rest-api-error-handling/scenarios/level-5/error-regulatory-landscape.yaml +80 -0
- package/courses/rest-api-error-handling/scenarios/level-5/master-error-shift.yaml +73 -0
- package/dist/cli/commands/add.d.ts.map +1 -1
- package/dist/cli/commands/add.js +6 -5
- package/dist/cli/commands/add.js.map +1 -1
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +4 -0
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/list.d.ts.map +1 -1
- package/dist/cli/commands/list.js +6 -18
- package/dist/cli/commands/list.js.map +1 -1
- package/dist/cli/commands/train.d.ts.map +1 -1
- package/dist/cli/commands/train.js +18 -18
- package/dist/cli/commands/train.js.map +1 -1
- package/dist/cli/index.js +93 -55
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/run-demo.js +2 -1
- package/dist/cli/run-demo.js.map +1 -1
- package/dist/cli/setup.d.ts +18 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +154 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/engine/agent-bridge.d.ts +5 -2
- package/dist/engine/agent-bridge.d.ts.map +1 -1
- package/dist/engine/agent-bridge.js +36 -9
- package/dist/engine/agent-bridge.js.map +1 -1
- package/dist/engine/loader.d.ts +21 -0
- package/dist/engine/loader.d.ts.map +1 -1
- package/dist/engine/loader.js +54 -1
- package/dist/engine/loader.js.map +1 -1
- package/dist/engine/training-loop.d.ts.map +1 -1
- package/dist/engine/training-loop.js +1 -0
- package/dist/engine/training-loop.js.map +1 -1
- package/dist/engine/training.d.ts.map +1 -1
- package/dist/engine/training.js +1 -0
- package/dist/engine/training.js.map +1 -1
- package/dist/generator/skill-generator.d.ts +1 -1
- package/dist/generator/skill-generator.d.ts.map +1 -1
- package/dist/generator/skill-generator.js +21 -2
- package/dist/generator/skill-generator.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +11 -26
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/session-manager.d.ts +3 -1
- package/dist/mcp/session-manager.d.ts.map +1 -1
- package/dist/mcp/session-manager.js +44 -22
- package/dist/mcp/session-manager.js.map +1 -1
- package/dist/types/schemas.d.ts +38 -13
- package/dist/types/schemas.d.ts.map +1 -1
- package/dist/types/schemas.js +9 -5
- package/dist/types/schemas.js.map +1 -1
- package/package.json +1 -1
package/courses/postgresql-query-optimization/scenarios/level-4/read-replica-optimization.yaml
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
id: read-replica-optimization
|
|
3
|
+
level: 4
|
|
4
|
+
course: postgresql-query-optimization
|
|
5
|
+
type: output
|
|
6
|
+
description: "Optimize read replica architecture — design replica routing, handle replication lag, and balance read workloads across PostgreSQL replicas"
|
|
7
|
+
tags: [PostgreSQL, read-replicas, replication-lag, load-balancing, routing, expert]
|
|
8
|
+
|
|
9
|
+
state: {}
|
|
10
|
+
|
|
11
|
+
trigger: |
|
|
12
|
+
Your platform has outgrown a single PostgreSQL primary. Read queries
|
|
13
|
+
account for 85% of total load, and the primary is at 90% CPU during
|
|
14
|
+
peak hours. You've added 3 read replicas, but they're not helping as
|
|
15
|
+
much as expected — some replicas are overloaded while others are idle,
|
|
16
|
+
and users are seeing stale data.
|
|
17
|
+
|
|
18
|
+
Current architecture:
|
|
19
|
+
- Primary: r6g.4xlarge, 100K queries/sec peak
|
|
20
|
+
- Replica 1: r6g.2xlarge — serving analytics team (heavy queries)
|
|
21
|
+
- Replica 2: r6g.4xlarge — serving API reads (high throughput)
|
|
22
|
+
- Replica 3: r6g.2xlarge — mostly idle (recently added)
|
|
23
|
+
|
|
24
|
+
Problems observed:
|
|
25
|
+
1. Replication lag: Replica 1 lags 30 seconds during analytics queries
|
|
26
|
+
because heavy queries consume all CPU, slowing WAL replay.
|
|
27
|
+
2. Stale reads: A user updates their profile, then immediately sees
|
|
28
|
+
the old data because the read is routed to a replica.
|
|
29
|
+
3. Uneven load: Application uses round-robin routing, but analytics
|
|
30
|
+
queries on Replica 1 make it 10x slower than Replica 2.
|
|
31
|
+
4. Failover gaps: When the primary fails, Replica 1 was promoted but
|
|
32
|
+
it was 30 seconds behind — 30 seconds of data was lost.
|
|
33
|
+
5. Connection routing: Each service has hardcoded replica endpoints.
|
|
34
|
+
Adding Replica 3 requires updating 20 service configurations.
|
|
35
|
+
|
|
36
|
+
Architecture questions:
|
|
37
|
+
- How to route reads intelligently (by query type, not round-robin)?
|
|
38
|
+
- How to handle read-after-write consistency without always hitting
|
|
39
|
+
the primary?
|
|
40
|
+
- How to prevent analytics queries from impacting OLTP replicas?
|
|
41
|
+
- How to manage replication lag and make promotion decisions safely?
|
|
42
|
+
- Should you use synchronous replication for any replicas?
|
|
43
|
+
|
|
44
|
+
Task: Design the optimized read replica architecture. Write: the
|
|
45
|
+
replica topology (sizing, roles, sync vs async), the query routing
|
|
46
|
+
strategy (intelligent routing, not round-robin), the consistency
|
|
47
|
+
model (handling stale reads), the replication lag management plan,
|
|
48
|
+
and the failover strategy with RPO guarantees.
|
|
49
|
+
|
|
50
|
+
assertions:
|
|
51
|
+
- type: llm_judge
|
|
52
|
+
criteria: "Replica topology separates workloads — dedicates specific replicas to OLTP reads vs analytics, sizes replicas appropriately for their workload, and explains the sync vs async trade-off (sync for zero-data-loss failover candidate, async for analytics where lag is acceptable). Addresses all 5 observed problems"
|
|
53
|
+
weight: 0.35
|
|
54
|
+
description: "Workload-aware replica topology"
|
|
55
|
+
- type: llm_judge
|
|
56
|
+
criteria: "Query routing is intelligent — uses middleware or proxy (e.g., PgPool-II, HAProxy, application-level routing) to route by query type (writes→primary, OLTP reads→OLTP replicas, analytics→analytics replica), implements read-after-write consistency (session stickiness to primary for N seconds after write, or check replication LSN), and handles adding/removing replicas without application changes"
|
|
57
|
+
weight: 0.35
|
|
58
|
+
description: "Intelligent query routing"
|
|
59
|
+
- type: llm_judge
|
|
60
|
+
criteria: "Replication lag and failover are managed — monitors lag per replica (pg_stat_replication, replay_lag), removes lagging replicas from read pool, uses synchronous replication for at least one failover candidate to guarantee RPO=0, and defines promotion criteria (which replica to promote, how to handle lag gap)"
|
|
61
|
+
weight: 0.30
|
|
62
|
+
description: "Lag management and failover"
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
id: vendor-evaluation
|
|
3
|
+
level: 4
|
|
4
|
+
course: postgresql-query-optimization
|
|
5
|
+
type: output
|
|
6
|
+
description: "Evaluate PostgreSQL hosting vendors — compare RDS, Aurora, self-managed, Citus, and other options for enterprise workloads"
|
|
7
|
+
tags: [PostgreSQL, vendor-evaluation, RDS, Aurora, Citus, TCO, expert]
|
|
8
|
+
|
|
9
|
+
state: {}
|
|
10
|
+
|
|
11
|
+
trigger: |
|
|
12
|
+
Your company is evaluating PostgreSQL hosting options for a
|
|
13
|
+
platform migration. The CTO wants a comprehensive comparison
|
|
14
|
+
with TCO analysis over 3 years.
|
|
15
|
+
|
|
16
|
+
Current state: Self-managed PostgreSQL on bare metal
|
|
17
|
+
- 5 database clusters, 20 instances total
|
|
18
|
+
- 10TB total data
|
|
19
|
+
- 100K queries/second peak
|
|
20
|
+
- 3 DBAs managing the infrastructure
|
|
21
|
+
- Annual infrastructure cost: $800K
|
|
22
|
+
- Annual DBA salary cost: $600K
|
|
23
|
+
- Monthly operational incidents: 3 (average)
|
|
24
|
+
|
|
25
|
+
Vendors to evaluate:
|
|
26
|
+
|
|
27
|
+
1. AWS RDS for PostgreSQL:
|
|
28
|
+
- Managed service, automated backups, Multi-AZ
|
|
29
|
+
- db.r6g.4xlarge ($2.46/hr) × 20 instances
|
|
30
|
+
|
|
31
|
+
2. AWS Aurora PostgreSQL:
|
|
32
|
+
- Distributed storage, up to 15 read replicas
|
|
33
|
+
- db.r6g.4xlarge ($3.28/hr) × 10 instances (Aurora needs fewer)
|
|
34
|
+
|
|
35
|
+
3. Self-managed on AWS EC2:
|
|
36
|
+
- Full control, Patroni for HA
|
|
37
|
+
- r6g.4xlarge ($0.81/hr) × 20 instances + EBS storage
|
|
38
|
+
|
|
39
|
+
4. Citus Cloud (Azure):
|
|
40
|
+
- Distributed PostgreSQL, horizontal scaling
|
|
41
|
+
- Multi-tenant SaaS pattern support
|
|
42
|
+
|
|
43
|
+
5. Neon (serverless PostgreSQL):
|
|
44
|
+
- Scale to zero, branching, compute-storage separation
|
|
45
|
+
- Pay per compute-second
|
|
46
|
+
|
|
47
|
+
Evaluation criteria:
|
|
48
|
+
- Total Cost of Ownership (3-year)
|
|
49
|
+
- Performance (latency, throughput)
|
|
50
|
+
- Availability (SLA guarantees)
|
|
51
|
+
- Operational burden (DBA time saved)
|
|
52
|
+
- Migration complexity
|
|
53
|
+
- Lock-in risk
|
|
54
|
+
- Compliance (SOC 2, PCI DSS, HIPAA)
|
|
55
|
+
|
|
56
|
+
Task: Write the vendor evaluation report. Include: the TCO
|
|
57
|
+
comparison (3-year costs including hidden costs), the performance
|
|
58
|
+
benchmark plan, the migration risk assessment per vendor, the
|
|
59
|
+
recommendation with justification, and the executive summary.
|
|
60
|
+
|
|
61
|
+
assertions:
|
|
62
|
+
- type: llm_judge
|
|
63
|
+
criteria: "TCO analysis includes hidden costs — considers not just instance pricing but also storage, IOPS, data transfer, backup storage, DBA time reduction (or increase), migration cost, training, and the cost of vendor lock-in. 3-year totals are calculated for each option"
|
|
64
|
+
weight: 0.35
|
|
65
|
+
description: "Comprehensive TCO analysis"
|
|
66
|
+
- type: llm_judge
|
|
67
|
+
criteria: "Evaluation is balanced — each vendor has pros and cons documented, the recommendation is justified by the company's specific needs (not just cheapest), and lock-in risk is honestly assessed (Aurora's proprietary storage layer, Citus's distributed query limitations)"
|
|
68
|
+
weight: 0.35
|
|
69
|
+
description: "Balanced vendor evaluation"
|
|
70
|
+
- type: llm_judge
|
|
71
|
+
criteria: "Migration risk and operational impact are assessed — estimates migration timeline per vendor, identifies features that don't transfer (extensions, custom configs), and calculates DBA staffing changes (managed services may reduce 3 DBAs to 1, but requires cloud expertise)"
|
|
72
|
+
weight: 0.30
|
|
73
|
+
description: "Migration and operational assessment"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
id: rest-api-error-handling
|
|
2
|
+
name: "REST API Error Handling"
|
|
3
|
+
description: >
|
|
4
|
+
Master REST API error handling from basic HTTP status codes to enterprise
|
|
5
|
+
error governance. Learn error response design, RFC 7807 Problem Details,
|
|
6
|
+
retry and circuit breaker patterns, distributed system error propagation,
|
|
7
|
+
error budgets, compliance-aware error handling, and API reliability
|
|
8
|
+
architecture for large-scale systems.
|
|
9
|
+
levels: 5
|
|
10
|
+
scenarios_per_level: 10
|
|
11
|
+
tags: [development, REST, API, error-handling, HTTP, status-codes, reliability, DevOps]
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
id: authentication-errors
|
|
3
|
+
level: 1
|
|
4
|
+
course: rest-api-error-handling
|
|
5
|
+
type: output
|
|
6
|
+
description: "Handle authentication errors — design error responses for auth failures without leaking security information"
|
|
7
|
+
tags: [REST, API, authentication, 401, 403, security, beginner]
|
|
8
|
+
|
|
9
|
+
state: {}
|
|
10
|
+
|
|
11
|
+
trigger: |
|
|
12
|
+
You're working on the authentication error handling for a healthcare
|
|
13
|
+
appointment booking API. The security team reviewed your error
|
|
14
|
+
responses and flagged several issues.
|
|
15
|
+
|
|
16
|
+
Current error responses (flagged as problematic):
|
|
17
|
+
|
|
18
|
+
1. Missing token:
|
|
19
|
+
401 { "error": "No Authorization header provided" }
|
|
20
|
+
Security note: "This is fine, but be consistent"
|
|
21
|
+
|
|
22
|
+
2. Malformed token:
|
|
23
|
+
401 { "error": "JWT format invalid: expected 3 parts, got 1" }
|
|
24
|
+
Security note: "Reveals token implementation (JWT)"
|
|
25
|
+
|
|
26
|
+
3. Expired token:
|
|
27
|
+
401 { "error": "Token expired at 2026-02-26T14:30:00Z, current
|
|
28
|
+
time is 2026-02-27T08:15:00Z" }
|
|
29
|
+
Security note: "Reveals server clock — useful for timing attacks"
|
|
30
|
+
|
|
31
|
+
4. Invalid signature:
|
|
32
|
+
401 { "error": "JWT signature verification failed using RS256" }
|
|
33
|
+
Security note: "Reveals signing algorithm"
|
|
34
|
+
|
|
35
|
+
5. Valid token but user deactivated:
|
|
36
|
+
401 { "error": "User account deactivated since 2026-01-15" }
|
|
37
|
+
Security note: "Confirms account existence and status"
|
|
38
|
+
|
|
39
|
+
6. Valid token but wrong role (patient trying admin endpoint):
|
|
40
|
+
403 { "error": "User john.doe@email.com has role 'patient',
|
|
41
|
+
requires role 'admin'" }
|
|
42
|
+
Security note: "Reveals user email and role system"
|
|
43
|
+
|
|
44
|
+
7. Valid token but IP not in allowlist:
|
|
45
|
+
403 { "error": "IP 192.168.1.50 not in allowlist for admin API" }
|
|
46
|
+
Security note: "Reveals IP allowlist exists"
|
|
47
|
+
|
|
48
|
+
8. API key instead of bearer token:
|
|
49
|
+
401 { "error": "Expected Bearer token, received API key
|
|
50
|
+
sk-abc...xyz" }
|
|
51
|
+
Security note: "Echoes back the credential!"
|
|
52
|
+
|
|
53
|
+
Task: Rewrite all 8 error responses to be secure (no information
|
|
54
|
+
leakage) while still being useful enough for legitimate developers
|
|
55
|
+
to debug. Explain the security principle behind each change. Then
|
|
56
|
+
write guidelines for the team on what authentication errors should
|
|
57
|
+
and should not reveal.
|
|
58
|
+
|
|
59
|
+
assertions:
|
|
60
|
+
- type: llm_judge
|
|
61
|
+
criteria: "Rewritten errors eliminate information leakage — no JWT implementation details, no server timestamps, no user emails, no role system details, no IP allowlist information, and absolutely no credential echoing. Each response gives enough information to debug without revealing security internals"
|
|
62
|
+
weight: 0.35
|
|
63
|
+
description: "Secure error responses"
|
|
64
|
+
- type: llm_judge
|
|
65
|
+
criteria: "Security principles are correctly explained — covers information disclosure risks (token type, algorithm, clock), account enumeration prevention, principle of least information, and the difference between logging detailed errors server-side vs returning generic errors to clients"
|
|
66
|
+
weight: 0.35
|
|
67
|
+
description: "Correct security principles"
|
|
68
|
+
- type: llm_judge
|
|
69
|
+
criteria: "Team guidelines are practical — provides clear do/don't list for auth error messages, explains server-side logging of detailed errors for debugging, and addresses the balance between security and developer experience"
|
|
70
|
+
weight: 0.30
|
|
71
|
+
description: "Practical team guidelines"
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
id: content-negotiation-errors
|
|
3
|
+
level: 1
|
|
4
|
+
course: rest-api-error-handling
|
|
5
|
+
type: output
|
|
6
|
+
description: "Handle content negotiation errors — respond correctly when clients send or request unsupported content types"
|
|
7
|
+
tags: [REST, API, content-type, accept, 406, 415, beginner]
|
|
8
|
+
|
|
9
|
+
state: {}
|
|
10
|
+
|
|
11
|
+
trigger: |
|
|
12
|
+
You're building an API that primarily serves JSON but also supports
|
|
13
|
+
XML for legacy enterprise clients. Users keep hitting confusing
|
|
14
|
+
errors related to content types.
|
|
15
|
+
|
|
16
|
+
Support tickets this week:
|
|
17
|
+
|
|
18
|
+
Ticket 1: "I'm sending a POST with form data (Content-Type:
|
|
19
|
+
application/x-www-form-urlencoded) but getting a 500 error with
|
|
20
|
+
'Unexpected token' in the response."
|
|
21
|
+
|
|
22
|
+
Ticket 2: "I set Accept: text/html but got back JSON anyway. My XML
|
|
23
|
+
parser is choking on it."
|
|
24
|
+
|
|
25
|
+
Ticket 3: "I'm uploading a file with Content-Type: multipart/
|
|
26
|
+
form-data to the /reports endpoint but it says 'invalid JSON'."
|
|
27
|
+
|
|
28
|
+
Ticket 4: "My request works in Postman but fails in my code. I
|
|
29
|
+
think it's because Postman auto-sets Content-Type but my HTTP
|
|
30
|
+
library doesn't."
|
|
31
|
+
|
|
32
|
+
Ticket 5: "I'm sending JSON but with Content-Type: text/plain
|
|
33
|
+
and getting a 400 error that says 'Request body is empty' — but
|
|
34
|
+
the body is definitely there!"
|
|
35
|
+
|
|
36
|
+
Ticket 6: "I need CSV export of my data. GET /reports with Accept:
|
|
37
|
+
text/csv returns JSON. Is CSV supported?"
|
|
38
|
+
|
|
39
|
+
Current behavior: The API ignores the Accept header entirely and
|
|
40
|
+
always returns JSON. For request bodies, it tries to parse
|
|
41
|
+
everything as JSON regardless of Content-Type, causing cryptic
|
|
42
|
+
errors.
|
|
43
|
+
|
|
44
|
+
Task: Design the correct content negotiation error handling. For
|
|
45
|
+
each ticket, explain: what's going wrong, what the correct HTTP
|
|
46
|
+
status code and response should be, and what headers the response
|
|
47
|
+
should include. Then write the content negotiation middleware logic
|
|
48
|
+
that handles both request (Content-Type) and response (Accept)
|
|
49
|
+
negotiation properly.
|
|
50
|
+
|
|
51
|
+
assertions:
|
|
52
|
+
- type: llm_judge
|
|
53
|
+
criteria: "Correct status codes for each scenario — 415 Unsupported Media Type when the server can't parse the request body's content type, 406 Not Acceptable when the server can't produce the client's requested format, and appropriate error messages explaining what formats are supported"
|
|
54
|
+
weight: 0.35
|
|
55
|
+
description: "Correct content negotiation status codes"
|
|
56
|
+
- type: llm_judge
|
|
57
|
+
criteria: "All 6 tickets are addressed with clear explanations — explains why form-encoded data fails JSON parsing, why missing Content-Type causes issues, how Accept header should drive response format, and includes the supported content types in error responses"
|
|
58
|
+
weight: 0.35
|
|
59
|
+
description: "All tickets addressed"
|
|
60
|
+
- type: llm_judge
|
|
61
|
+
criteria: "Middleware logic is complete — validates Content-Type on requests with bodies, negotiates Accept header for responses, falls back to JSON when no Accept header is sent, and includes proper Content-Type header on all responses including error responses"
|
|
62
|
+
weight: 0.30
|
|
63
|
+
description: "Complete middleware logic"
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
id: error-logging-basics
|
|
3
|
+
level: 1
|
|
4
|
+
course: rest-api-error-handling
|
|
5
|
+
type: output
|
|
6
|
+
description: "Set up API error logging — design structured error logs that make debugging fast without logging sensitive data"
|
|
7
|
+
tags: [REST, API, logging, debugging, structured-logs, beginner]
|
|
8
|
+
|
|
9
|
+
state: {}
|
|
10
|
+
|
|
11
|
+
trigger: |
|
|
12
|
+
You're debugging a production issue on a food delivery API.
|
|
13
|
+
Customers are getting 500 errors when placing orders, but your
|
|
14
|
+
current logs look like this:
|
|
15
|
+
|
|
16
|
+
2026-02-27 10:15:33 ERROR: Something went wrong
|
|
17
|
+
2026-02-27 10:15:34 ERROR: Something went wrong
|
|
18
|
+
2026-02-27 10:15:35 ERROR: null
|
|
19
|
+
2026-02-27 10:15:36 ERROR: Something went wrong
|
|
20
|
+
2026-02-27 10:15:37 ERROR: [object Object]
|
|
21
|
+
|
|
22
|
+
You have no idea: which endpoint failed, what the request was,
|
|
23
|
+
which user was affected, what the actual error was, or how to
|
|
24
|
+
reproduce it.
|
|
25
|
+
|
|
26
|
+
After 2 hours of blind debugging, you find it's a null pointer
|
|
27
|
+
in the restaurant menu lookup. You realize you need proper error
|
|
28
|
+
logging.
|
|
29
|
+
|
|
30
|
+
Your API has these components:
|
|
31
|
+
- Order placement (POST /orders)
|
|
32
|
+
- Payment processing (POST /orders/:id/pay)
|
|
33
|
+
- Restaurant communication (POST /restaurants/:id/notify)
|
|
34
|
+
- Delivery assignment (POST /deliveries)
|
|
35
|
+
- User notifications (POST /notifications)
|
|
36
|
+
|
|
37
|
+
Sensitive data that must NOT appear in logs:
|
|
38
|
+
- Credit card numbers, CVVs
|
|
39
|
+
- User passwords
|
|
40
|
+
- Full addresses (only city/zip is OK)
|
|
41
|
+
- API keys and tokens
|
|
42
|
+
- Phone numbers (mask all but last 4)
|
|
43
|
+
|
|
44
|
+
Task: Design the structured error logging system. Show: the log
|
|
45
|
+
format (structured JSON), what fields every error log must include,
|
|
46
|
+
what sensitive fields must be masked or excluded, example log entries
|
|
47
|
+
for 3 different error types (validation error, third-party timeout,
|
|
48
|
+
unhandled exception), and how to search these logs to debug the
|
|
49
|
+
original "customers getting 500 errors" issue quickly.
|
|
50
|
+
|
|
51
|
+
assertions:
|
|
52
|
+
- type: llm_judge
|
|
53
|
+
criteria: "Log format is structured and searchable — uses JSON format with consistent fields (timestamp, level, request_id, method, path, status_code, error_type, message, duration_ms, user_id). Includes enough context to reproduce issues without needing to add more logging"
|
|
54
|
+
weight: 0.35
|
|
55
|
+
description: "Structured searchable log format"
|
|
56
|
+
- type: llm_judge
|
|
57
|
+
criteria: "Sensitive data handling is thorough — credit cards, passwords, tokens are never logged. Phone numbers and addresses are properly masked. Explains the masking strategy (middleware vs per-field) and how to prevent accidental logging of request/response bodies containing sensitive data"
|
|
58
|
+
weight: 0.35
|
|
59
|
+
description: "Thorough sensitive data handling"
|
|
60
|
+
- type: llm_judge
|
|
61
|
+
criteria: "Example log entries are realistic and the debugging workflow is practical — shows how to filter logs by request_id, status_code, error_type to quickly identify the root cause. The 3 example entries demonstrate different error severities and contexts"
|
|
62
|
+
weight: 0.30
|
|
63
|
+
description: "Realistic examples and debugging workflow"
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
id: error-response-format
|
|
3
|
+
level: 1
|
|
4
|
+
course: rest-api-error-handling
|
|
5
|
+
type: output
|
|
6
|
+
description: "Design error response format — create a consistent JSON error response structure for a REST API"
|
|
7
|
+
tags: [REST, API, error-response, JSON, format, beginner]
|
|
8
|
+
|
|
9
|
+
state: {}
|
|
10
|
+
|
|
11
|
+
trigger: |
|
|
12
|
+
You're building a recipe sharing API and different endpoints return
|
|
13
|
+
errors in completely different formats. Your team lead says this is
|
|
14
|
+
confusing for frontend developers and asks you to standardize.
|
|
15
|
+
|
|
16
|
+
Current inconsistent error responses across your API:
|
|
17
|
+
|
|
18
|
+
Endpoint 1 - POST /recipes (validation error):
|
|
19
|
+
{ "error": "Title is required" }
|
|
20
|
+
|
|
21
|
+
Endpoint 2 - GET /recipes/999 (not found):
|
|
22
|
+
{ "message": "Recipe not found", "code": 404 }
|
|
23
|
+
|
|
24
|
+
Endpoint 3 - POST /recipes (auth error):
|
|
25
|
+
{ "status": "error", "reason": "Invalid token" }
|
|
26
|
+
|
|
27
|
+
Endpoint 4 - POST /recipes/5/reviews (rate limit):
|
|
28
|
+
"Too many requests, please try again later"
|
|
29
|
+
|
|
30
|
+
Endpoint 5 - PATCH /recipes/5 (validation errors):
|
|
31
|
+
{ "errors": ["Title too long", "Invalid category"] }
|
|
32
|
+
|
|
33
|
+
Frontend developers are complaining:
|
|
34
|
+
- "I never know which field to check for the error message"
|
|
35
|
+
- "Sometimes I get a string, sometimes an object"
|
|
36
|
+
- "Validation errors come in different shapes"
|
|
37
|
+
- "I can't tell if an error is my fault or the server's fault"
|
|
38
|
+
- "There's no way to show specific field errors in the form"
|
|
39
|
+
|
|
40
|
+
Task: Design a unified error response format for the entire API.
|
|
41
|
+
Show: the standard error response schema (with required and optional
|
|
42
|
+
fields), examples for each of the 5 error types above rewritten in
|
|
43
|
+
the new format, guidelines for when to include each optional field,
|
|
44
|
+
and the implementation approach (middleware vs per-handler).
|
|
45
|
+
|
|
46
|
+
assertions:
|
|
47
|
+
- type: llm_judge
|
|
48
|
+
criteria: "Error format is well-designed — includes a machine-readable error code/type, a human-readable message, and the HTTP status code. Handles single errors and multiple validation errors in the same structure. Includes a way to associate errors with specific fields for form validation"
|
|
49
|
+
weight: 0.35
|
|
50
|
+
description: "Well-designed error format"
|
|
51
|
+
- type: llm_judge
|
|
52
|
+
criteria: "All 5 error types are rewritten consistently — validation errors show field-level detail, not-found errors include resource identification, auth errors distinguish authentication vs authorization, rate limit errors include retry-after information, and all follow the same top-level structure"
|
|
53
|
+
weight: 0.35
|
|
54
|
+
description: "Consistent error rewrites"
|
|
55
|
+
- type: llm_judge
|
|
56
|
+
criteria: "Implementation guidance is practical — recommends middleware/error handler pattern for consistency, explains how to throw standardized errors from route handlers, and addresses how to prevent internal error details from leaking to the client"
|
|
57
|
+
weight: 0.30
|
|
58
|
+
description: "Practical implementation guidance"
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
id: first-error-handling-shift
|
|
3
|
+
level: 1
|
|
4
|
+
course: rest-api-error-handling
|
|
5
|
+
type: output
|
|
6
|
+
description: "First error handling shift — handle a stream of real-time API errors during a product launch event"
|
|
7
|
+
tags: [REST, API, error-handling, shift-simulation, launch, beginner]
|
|
8
|
+
|
|
9
|
+
state: {}
|
|
10
|
+
|
|
11
|
+
trigger: |
|
|
12
|
+
You're on your first on-call shift for a ticket marketplace API.
|
|
13
|
+
The company is launching sales for a major concert tonight and
|
|
14
|
+
traffic will spike 10x. Your job is to review the API's error
|
|
15
|
+
handling before the launch.
|
|
16
|
+
|
|
17
|
+
During your pre-launch review, you find these issues:
|
|
18
|
+
|
|
19
|
+
Issue 1 — No global error handler:
|
|
20
|
+
If any route throws an unhandled exception, Express returns:
|
|
21
|
+
<!DOCTYPE html><html><body><pre>TypeError: Cannot read property
|
|
22
|
+
'email' of undefined<br> at /app/src/routes/tickets.js:45
|
|
23
|
+
</pre></body></html>
|
|
24
|
+
(HTML error page with stack trace)
|
|
25
|
+
|
|
26
|
+
Issue 2 — Inconsistent error shapes:
|
|
27
|
+
- /tickets returns { "error": "..." }
|
|
28
|
+
- /orders returns { "message": "...", "code": 123 }
|
|
29
|
+
- /payments returns { "errors": ["..."] }
|
|
30
|
+
- /users returns { "status": "fail", "data": { "message": "..." } }
|
|
31
|
+
|
|
32
|
+
Issue 3 — Database errors leak:
|
|
33
|
+
When the database constraint prevents duplicate ticket purchases:
|
|
34
|
+
"duplicate key value violates unique constraint
|
|
35
|
+
'orders_user_id_ticket_id_key'"
|
|
36
|
+
|
|
37
|
+
Issue 4 — No rate limiting on search:
|
|
38
|
+
GET /tickets/search has no rate limit. During the last sale, bots
|
|
39
|
+
made 50,000 requests/second and the API crashed.
|
|
40
|
+
|
|
41
|
+
Issue 5 — Payment errors are too vague:
|
|
42
|
+
POST /orders/:id/pay returns 400 { "error": "Payment failed" }
|
|
43
|
+
for every payment issue (declined card, insufficient funds,
|
|
44
|
+
expired card, processing timeout, fraud detection).
|
|
45
|
+
|
|
46
|
+
Issue 6 — Timeout errors unhandled:
|
|
47
|
+
The external payment processor sometimes takes 30+ seconds. The API
|
|
48
|
+
has no timeout, so requests hang until the client gives up.
|
|
49
|
+
|
|
50
|
+
Task: Fix all 6 issues before the launch. For each, write: what's
|
|
51
|
+
wrong (the risk for tonight's launch), the fix (code structure or
|
|
52
|
+
configuration), and the expected error response after the fix.
|
|
53
|
+
Prioritize the fixes by launch impact.
|
|
54
|
+
|
|
55
|
+
assertions:
|
|
56
|
+
- type: llm_judge
|
|
57
|
+
criteria: "All 6 issues are fixed with correct solutions — global error handler catches unhandled exceptions (no HTML/stack traces), error format is standardized, database errors are translated to user-friendly messages, rate limiting is implemented for search, payment errors are specific but secure, and timeout handling is added with appropriate status codes"
|
|
58
|
+
weight: 0.35
|
|
59
|
+
description: "All issues fixed correctly"
|
|
60
|
+
- type: llm_judge
|
|
61
|
+
criteria: "Prioritization is sound — identifies which issues pose the greatest risk for a high-traffic launch event (no global error handler and no rate limiting are critical, inconsistent formats are important but not urgent). Each fix includes the expected error response"
|
|
62
|
+
weight: 0.35
|
|
63
|
+
description: "Sound prioritization"
|
|
64
|
+
- type: llm_judge
|
|
65
|
+
criteria: "Solutions are launch-ready — fixes are quick to implement (no major refactors), handle the specific high-traffic scenario (10x spike), and include monitoring so the on-call engineer can see errors in real-time during the launch"
|
|
66
|
+
weight: 0.30
|
|
67
|
+
description: "Launch-ready solutions"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
id: http-status-codes
|
|
3
|
+
level: 1
|
|
4
|
+
course: rest-api-error-handling
|
|
5
|
+
type: output
|
|
6
|
+
description: "Classify HTTP status codes — match API scenarios to correct status codes across 2xx, 4xx, and 5xx families"
|
|
7
|
+
tags: [REST, API, HTTP, status-codes, beginner]
|
|
8
|
+
|
|
9
|
+
state: {}
|
|
10
|
+
|
|
11
|
+
trigger: |
|
|
12
|
+
You're a junior backend developer who just joined a team building a
|
|
13
|
+
task management API. During your first code review, the senior
|
|
14
|
+
developer flagged that your endpoints return wrong status codes.
|
|
15
|
+
|
|
16
|
+
Your current mistakes:
|
|
17
|
+
1. POST /tasks returns 200 when a task is created (should be 201)
|
|
18
|
+
2. DELETE /tasks/:id returns 200 with empty body (should be 204)
|
|
19
|
+
3. GET /tasks/:id returns 200 with { error: "not found" } when the
|
|
20
|
+
task doesn't exist (should be 404)
|
|
21
|
+
4. POST /tasks with missing "title" field returns 500 (should be 400)
|
|
22
|
+
5. GET /tasks with expired auth token returns 403 (should be 401)
|
|
23
|
+
6. PUT /tasks/:id on someone else's task returns 404 (should be 403)
|
|
24
|
+
7. POST /tasks when the database is down returns 400 (should be 503)
|
|
25
|
+
8. PATCH /tasks/:id with Content-Type: text/plain returns 500
|
|
26
|
+
(should be 415)
|
|
27
|
+
|
|
28
|
+
Task: For each of the 8 mistakes, explain: (1) why your current
|
|
29
|
+
status code is wrong, (2) what the correct status code is and why,
|
|
30
|
+
and (3) the general rule for when to use that status code. Then
|
|
31
|
+
create a quick-reference cheat sheet mapping common API scenarios
|
|
32
|
+
to their correct HTTP status codes.
|
|
33
|
+
|
|
34
|
+
assertions:
|
|
35
|
+
- type: llm_judge
|
|
36
|
+
criteria: "Correctly identifies all 8 status code fixes — 201 Created for resource creation, 204 No Content for successful deletion, 404 Not Found for missing resources, 400 Bad Request for validation errors, 401 Unauthorized for expired/missing auth, 403 Forbidden for insufficient permissions, 503 Service Unavailable for downstream failures, 415 Unsupported Media Type for wrong content types"
|
|
37
|
+
weight: 0.35
|
|
38
|
+
description: "Correct status code identification"
|
|
39
|
+
- type: llm_judge
|
|
40
|
+
criteria: "Explanations demonstrate understanding of status code semantics — distinguishes between 401 (identity unknown) and 403 (identity known, permission denied), between 400 (client mistake) and 500 (server mistake), and between 200 (response body) and 204 (no body)"
|
|
41
|
+
weight: 0.35
|
|
42
|
+
description: "Status code semantic understanding"
|
|
43
|
+
- type: llm_judge
|
|
44
|
+
criteria: "Cheat sheet is practical and organized — groups status codes by family (2xx success, 4xx client error, 5xx server error), covers common API scenarios beyond just the 8 mistakes, and is formatted for quick reference"
|
|
45
|
+
weight: 0.30
|
|
46
|
+
description: "Practical cheat sheet"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
id: not-found-errors
|
|
3
|
+
level: 1
|
|
4
|
+
course: rest-api-error-handling
|
|
5
|
+
type: output
|
|
6
|
+
description: "Handle not-found errors — distinguish between missing resources, wrong URLs, and deleted content with appropriate responses"
|
|
7
|
+
tags: [REST, API, 404, not-found, routing, beginner]
|
|
8
|
+
|
|
9
|
+
state: {}
|
|
10
|
+
|
|
11
|
+
trigger: |
|
|
12
|
+
You're maintaining a blog API and users are reporting confusing
|
|
13
|
+
behavior. All of these return the same generic 404 response:
|
|
14
|
+
|
|
15
|
+
{ "error": "Not found" }
|
|
16
|
+
|
|
17
|
+
But they represent very different situations:
|
|
18
|
+
|
|
19
|
+
1. GET /posts/42 — Post exists but is in draft status (not published)
|
|
20
|
+
2. GET /posts/99999 — Post ID doesn't exist at all
|
|
21
|
+
3. GET /posts/abc — Post ID is not a valid integer
|
|
22
|
+
4. GET /postz/42 — Typo in the URL path (postz instead of posts)
|
|
23
|
+
5. GET /posts/42 — Post existed but was deleted 3 days ago
|
|
24
|
+
6. GET /posts/42 — Post exists but belongs to a different tenant
|
|
25
|
+
in your multi-tenant system
|
|
26
|
+
7. GET /users/5/posts/42 — User 5 exists but post 42 belongs to
|
|
27
|
+
user 8
|
|
28
|
+
8. GET /v1/posts/42 — API v1 is deprecated, only v2 exists
|
|
29
|
+
|
|
30
|
+
The frontend developer says: "I can't tell if the user mistyped
|
|
31
|
+
the URL, if the post was deleted, if it's a permission issue, or
|
|
32
|
+
if the endpoint doesn't exist. They all look the same!"
|
|
33
|
+
|
|
34
|
+
Task: Design the appropriate response for each of the 8 scenarios.
|
|
35
|
+
Not all of them should be 404 — decide which HTTP status code
|
|
36
|
+
fits each case and explain why. Write the response body for each
|
|
37
|
+
scenario. Then create a decision tree for "when the resource isn't
|
|
38
|
+
there" that the team can follow.
|
|
39
|
+
|
|
40
|
+
assertions:
|
|
41
|
+
- type: llm_judge
|
|
42
|
+
criteria: "Status code selection is correct for each case — distinguishes between 404 (truly not found), 400 (invalid ID format), 410 Gone (deleted content), 403 (wrong tenant/ownership), and appropriate handling for draft content and deprecated API versions. Not all 8 should be 404"
|
|
43
|
+
weight: 0.35
|
|
44
|
+
description: "Correct status code selection"
|
|
45
|
+
- type: llm_judge
|
|
46
|
+
criteria: "Response bodies are helpful without leaking information — draft posts don't reveal that the post exists (security consideration in multi-tenant), deleted posts may use 410 Gone with deletion context, invalid IDs explain the expected format, and deprecated versions redirect to the current version"
|
|
47
|
+
weight: 0.35
|
|
48
|
+
description: "Helpful secure responses"
|
|
49
|
+
- type: llm_judge
|
|
50
|
+
criteria: "Decision tree is clear and usable — provides a logical flow for developers to determine the right response when a resource isn't found, considers security implications (don't confirm existence to unauthorized users), and handles edge cases like soft deletes and multi-tenancy"
|
|
51
|
+
weight: 0.30
|
|
52
|
+
description: "Clear decision tree"
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
meta:
|
|
2
|
+
id: rate-limiting-errors
|
|
3
|
+
level: 1
|
|
4
|
+
course: rest-api-error-handling
|
|
5
|
+
type: output
|
|
6
|
+
description: "Implement rate limiting errors — design 429 responses with proper headers and retry guidance for API consumers"
|
|
7
|
+
tags: [REST, API, rate-limiting, 429, throttling, beginner]
|
|
8
|
+
|
|
9
|
+
state: {}
|
|
10
|
+
|
|
11
|
+
trigger: |
|
|
12
|
+
You're building a weather data API that offers free and paid tiers.
|
|
13
|
+
The current rate limiting returns 429 with this response:
|
|
14
|
+
|
|
15
|
+
HTTP/1.1 429
|
|
16
|
+
{ "error": "Too many requests" }
|
|
17
|
+
|
|
18
|
+
Customers are complaining:
|
|
19
|
+
- "When can I retry? 1 second? 1 hour?"
|
|
20
|
+
- "How many requests do I have left?"
|
|
21
|
+
- "I didn't even know there was a rate limit until my app broke"
|
|
22
|
+
- "My batch job got rate limited and I lost 2 hours of processing"
|
|
23
|
+
- "The paid plan says 1000 requests/minute but I got limited at 800"
|
|
24
|
+
|
|
25
|
+
Rate limit tiers:
|
|
26
|
+
- Free: 60 requests/minute, 1000 requests/day
|
|
27
|
+
- Basic ($29/mo): 600 requests/minute, 50,000 requests/day
|
|
28
|
+
- Pro ($99/mo): 3000 requests/minute, unlimited daily
|
|
29
|
+
- Enterprise: custom limits
|
|
30
|
+
|
|
31
|
+
Additional rules:
|
|
32
|
+
- Burst allowance: 2x the per-minute limit for up to 10 seconds
|
|
33
|
+
- Different limits for different endpoints (search: 10/min free,
|
|
34
|
+
forecast: 60/min free)
|
|
35
|
+
- Authenticated vs unauthenticated requests have different limits
|
|
36
|
+
|
|
37
|
+
Task: Design the complete rate limiting error response. Include:
|
|
38
|
+
the 429 response body with all necessary information, the rate
|
|
39
|
+
limit headers (standard and custom), the response headers that
|
|
40
|
+
should appear on ALL responses (not just 429) so clients can
|
|
41
|
+
proactively manage their usage, and a guide for API consumers
|
|
42
|
+
on how to handle rate limits gracefully (backoff strategies).
|
|
43
|
+
|
|
44
|
+
assertions:
|
|
45
|
+
- type: llm_judge
|
|
46
|
+
criteria: "429 response includes standard rate limit headers — X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset (or Retry-After), with clear documentation of header semantics. Response body includes retry timing, current limit, and which limit was hit (per-minute vs daily)"
|
|
47
|
+
weight: 0.35
|
|
48
|
+
description: "Proper 429 response with headers"
|
|
49
|
+
- type: llm_judge
|
|
50
|
+
criteria: "Rate limit information appears on ALL responses — successful responses include remaining quota and reset time so clients can proactively avoid hitting limits. The design handles the complexity of multiple limit windows (per-minute and daily) and per-endpoint limits"
|
|
51
|
+
weight: 0.35
|
|
52
|
+
description: "Proactive rate limit headers"
|
|
53
|
+
- type: llm_judge
|
|
54
|
+
criteria: "Consumer guidance is practical — explains exponential backoff with jitter, how to read rate limit headers proactively, how to build a request queue that respects limits, and addresses the batch processing use case (how to process large workloads within rate limits)"
|
|
55
|
+
weight: 0.30
|
|
56
|
+
description: "Practical consumer guidance"
|