@shaykec/bridge 0.4.24 → 0.4.26
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/journeys/ai-engineer.yaml +34 -0
- package/journeys/backend-developer.yaml +36 -0
- package/journeys/business-analyst.yaml +37 -0
- package/journeys/devops-engineer.yaml +37 -0
- package/journeys/engineering-manager.yaml +44 -0
- package/journeys/frontend-developer.yaml +41 -0
- package/journeys/fullstack-developer.yaml +49 -0
- package/journeys/mobile-developer.yaml +42 -0
- package/journeys/product-manager.yaml +35 -0
- package/journeys/qa-engineer.yaml +37 -0
- package/journeys/ux-designer.yaml +43 -0
- package/modules/README.md +52 -0
- package/modules/accessibility-fundamentals/content.md +126 -0
- package/modules/accessibility-fundamentals/exercises.md +88 -0
- package/modules/accessibility-fundamentals/module.yaml +43 -0
- package/modules/accessibility-fundamentals/quick-ref.md +71 -0
- package/modules/accessibility-fundamentals/quiz.md +100 -0
- package/modules/accessibility-fundamentals/resources.md +29 -0
- package/modules/accessibility-fundamentals/walkthrough.md +80 -0
- package/modules/adr-writing/content.md +121 -0
- package/modules/adr-writing/exercises.md +81 -0
- package/modules/adr-writing/module.yaml +41 -0
- package/modules/adr-writing/quick-ref.md +57 -0
- package/modules/adr-writing/quiz.md +73 -0
- package/modules/adr-writing/resources.md +29 -0
- package/modules/adr-writing/walkthrough.md +64 -0
- package/modules/ai-agents/content.md +120 -0
- package/modules/ai-agents/exercises.md +82 -0
- package/modules/ai-agents/module.yaml +42 -0
- package/modules/ai-agents/quick-ref.md +60 -0
- package/modules/ai-agents/quiz.md +103 -0
- package/modules/ai-agents/resources.md +30 -0
- package/modules/ai-agents/walkthrough.md +85 -0
- package/modules/ai-assisted-research/content.md +136 -0
- package/modules/ai-assisted-research/exercises.md +80 -0
- package/modules/ai-assisted-research/module.yaml +42 -0
- package/modules/ai-assisted-research/quick-ref.md +67 -0
- package/modules/ai-assisted-research/quiz.md +73 -0
- package/modules/ai-assisted-research/resources.md +33 -0
- package/modules/ai-assisted-research/walkthrough.md +85 -0
- package/modules/ai-pair-programming/content.md +105 -0
- package/modules/ai-pair-programming/exercises.md +98 -0
- package/modules/ai-pair-programming/module.yaml +39 -0
- package/modules/ai-pair-programming/quick-ref.md +58 -0
- package/modules/ai-pair-programming/quiz.md +73 -0
- package/modules/ai-pair-programming/resources.md +34 -0
- package/modules/ai-pair-programming/walkthrough.md +117 -0
- package/modules/ai-test-generation/content.md +125 -0
- package/modules/ai-test-generation/exercises.md +98 -0
- package/modules/ai-test-generation/module.yaml +39 -0
- package/modules/ai-test-generation/quick-ref.md +65 -0
- package/modules/ai-test-generation/quiz.md +74 -0
- package/modules/ai-test-generation/resources.md +41 -0
- package/modules/ai-test-generation/walkthrough.md +100 -0
- package/modules/api-design/content.md +189 -0
- package/modules/api-design/exercises.md +84 -0
- package/modules/api-design/game.yaml +113 -0
- package/modules/api-design/module.yaml +45 -0
- package/modules/api-design/quick-ref.md +73 -0
- package/modules/api-design/quiz.md +100 -0
- package/modules/api-design/resources.md +55 -0
- package/modules/api-design/walkthrough.md +88 -0
- package/modules/clean-code/content.md +136 -0
- package/modules/clean-code/exercises.md +137 -0
- package/modules/clean-code/game.yaml +172 -0
- package/modules/clean-code/module.yaml +44 -0
- package/modules/clean-code/quick-ref.md +44 -0
- package/modules/clean-code/quiz.md +105 -0
- package/modules/clean-code/resources.md +40 -0
- package/modules/clean-code/walkthrough.md +78 -0
- package/modules/clean-code/workshop.yaml +149 -0
- package/modules/code-review/content.md +130 -0
- package/modules/code-review/exercises.md +95 -0
- package/modules/code-review/game.yaml +83 -0
- package/modules/code-review/module.yaml +42 -0
- package/modules/code-review/quick-ref.md +77 -0
- package/modules/code-review/quiz.md +105 -0
- package/modules/code-review/resources.md +40 -0
- package/modules/code-review/walkthrough.md +106 -0
- package/modules/daily-workflow/content.md +81 -0
- package/modules/daily-workflow/exercises.md +50 -0
- package/modules/daily-workflow/module.yaml +33 -0
- package/modules/daily-workflow/quick-ref.md +37 -0
- package/modules/daily-workflow/quiz.md +65 -0
- package/modules/daily-workflow/resources.md +38 -0
- package/modules/daily-workflow/walkthrough.md +83 -0
- package/modules/debugging-systematically/content.md +139 -0
- package/modules/debugging-systematically/exercises.md +91 -0
- package/modules/debugging-systematically/module.yaml +46 -0
- package/modules/debugging-systematically/quick-ref.md +59 -0
- package/modules/debugging-systematically/quiz.md +105 -0
- package/modules/debugging-systematically/resources.md +42 -0
- package/modules/debugging-systematically/walkthrough.md +84 -0
- package/modules/debugging-systematically/workshop.yaml +127 -0
- package/modules/demo-test/content.md +68 -0
- package/modules/demo-test/exercises.md +28 -0
- package/modules/demo-test/game.yaml +171 -0
- package/modules/demo-test/module.yaml +41 -0
- package/modules/demo-test/quick-ref.md +54 -0
- package/modules/demo-test/quiz.md +74 -0
- package/modules/demo-test/resources.md +21 -0
- package/modules/demo-test/walkthrough.md +122 -0
- package/modules/demo-test/workshop.yaml +31 -0
- package/modules/design-critique/content.md +93 -0
- package/modules/design-critique/exercises.md +71 -0
- package/modules/design-critique/module.yaml +41 -0
- package/modules/design-critique/quick-ref.md +63 -0
- package/modules/design-critique/quiz.md +73 -0
- package/modules/design-critique/resources.md +27 -0
- package/modules/design-critique/walkthrough.md +68 -0
- package/modules/design-patterns/content.md +335 -0
- package/modules/design-patterns/exercises.md +82 -0
- package/modules/design-patterns/game.yaml +55 -0
- package/modules/design-patterns/module.yaml +45 -0
- package/modules/design-patterns/quick-ref.md +44 -0
- package/modules/design-patterns/quiz.md +101 -0
- package/modules/design-patterns/resources.md +40 -0
- package/modules/design-patterns/walkthrough.md +64 -0
- package/modules/exploratory-testing/content.md +133 -0
- package/modules/exploratory-testing/exercises.md +88 -0
- package/modules/exploratory-testing/module.yaml +41 -0
- package/modules/exploratory-testing/quick-ref.md +68 -0
- package/modules/exploratory-testing/quiz.md +75 -0
- package/modules/exploratory-testing/resources.md +39 -0
- package/modules/exploratory-testing/walkthrough.md +87 -0
- package/modules/git/content.md +128 -0
- package/modules/git/exercises.md +53 -0
- package/modules/git/game.yaml +190 -0
- package/modules/git/module.yaml +44 -0
- package/modules/git/quick-ref.md +67 -0
- package/modules/git/quiz.md +89 -0
- package/modules/git/resources.md +49 -0
- package/modules/git/walkthrough.md +92 -0
- package/modules/git/workshop.yaml +145 -0
- package/modules/hiring-interviews/content.md +130 -0
- package/modules/hiring-interviews/exercises.md +88 -0
- package/modules/hiring-interviews/module.yaml +41 -0
- package/modules/hiring-interviews/quick-ref.md +68 -0
- package/modules/hiring-interviews/quiz.md +73 -0
- package/modules/hiring-interviews/resources.md +36 -0
- package/modules/hiring-interviews/walkthrough.md +75 -0
- package/modules/hooks/content.md +97 -0
- package/modules/hooks/exercises.md +69 -0
- package/modules/hooks/module.yaml +39 -0
- package/modules/hooks/quick-ref.md +93 -0
- package/modules/hooks/quiz.md +81 -0
- package/modules/hooks/resources.md +34 -0
- package/modules/hooks/walkthrough.md +105 -0
- package/modules/hooks/workshop.yaml +64 -0
- package/modules/incident-response/content.md +124 -0
- package/modules/incident-response/exercises.md +82 -0
- package/modules/incident-response/game.yaml +132 -0
- package/modules/incident-response/module.yaml +45 -0
- package/modules/incident-response/quick-ref.md +53 -0
- package/modules/incident-response/quiz.md +103 -0
- package/modules/incident-response/resources.md +40 -0
- package/modules/incident-response/walkthrough.md +82 -0
- package/modules/llm-fundamentals/content.md +114 -0
- package/modules/llm-fundamentals/exercises.md +83 -0
- package/modules/llm-fundamentals/module.yaml +42 -0
- package/modules/llm-fundamentals/quick-ref.md +64 -0
- package/modules/llm-fundamentals/quiz.md +103 -0
- package/modules/llm-fundamentals/resources.md +30 -0
- package/modules/llm-fundamentals/walkthrough.md +91 -0
- package/modules/one-on-ones/content.md +133 -0
- package/modules/one-on-ones/exercises.md +81 -0
- package/modules/one-on-ones/module.yaml +44 -0
- package/modules/one-on-ones/quick-ref.md +67 -0
- package/modules/one-on-ones/quiz.md +73 -0
- package/modules/one-on-ones/resources.md +37 -0
- package/modules/one-on-ones/walkthrough.md +69 -0
- package/modules/package.json +9 -0
- package/modules/prioritization-frameworks/content.md +130 -0
- package/modules/prioritization-frameworks/exercises.md +93 -0
- package/modules/prioritization-frameworks/module.yaml +41 -0
- package/modules/prioritization-frameworks/quick-ref.md +77 -0
- package/modules/prioritization-frameworks/quiz.md +73 -0
- package/modules/prioritization-frameworks/resources.md +32 -0
- package/modules/prioritization-frameworks/walkthrough.md +69 -0
- package/modules/prompt-engineering/content.md +123 -0
- package/modules/prompt-engineering/exercises.md +82 -0
- package/modules/prompt-engineering/game.yaml +101 -0
- package/modules/prompt-engineering/module.yaml +45 -0
- package/modules/prompt-engineering/quick-ref.md +65 -0
- package/modules/prompt-engineering/quiz.md +105 -0
- package/modules/prompt-engineering/resources.md +36 -0
- package/modules/prompt-engineering/walkthrough.md +81 -0
- package/modules/rag-fundamentals/content.md +111 -0
- package/modules/rag-fundamentals/exercises.md +80 -0
- package/modules/rag-fundamentals/module.yaml +45 -0
- package/modules/rag-fundamentals/quick-ref.md +58 -0
- package/modules/rag-fundamentals/quiz.md +75 -0
- package/modules/rag-fundamentals/resources.md +34 -0
- package/modules/rag-fundamentals/walkthrough.md +75 -0
- package/modules/react-fundamentals/content.md +140 -0
- package/modules/react-fundamentals/exercises.md +81 -0
- package/modules/react-fundamentals/game.yaml +145 -0
- package/modules/react-fundamentals/module.yaml +45 -0
- package/modules/react-fundamentals/quick-ref.md +62 -0
- package/modules/react-fundamentals/quiz.md +106 -0
- package/modules/react-fundamentals/resources.md +42 -0
- package/modules/react-fundamentals/walkthrough.md +89 -0
- package/modules/react-fundamentals/workshop.yaml +112 -0
- package/modules/react-native-fundamentals/content.md +141 -0
- package/modules/react-native-fundamentals/exercises.md +79 -0
- package/modules/react-native-fundamentals/module.yaml +42 -0
- package/modules/react-native-fundamentals/quick-ref.md +60 -0
- package/modules/react-native-fundamentals/quiz.md +61 -0
- package/modules/react-native-fundamentals/resources.md +24 -0
- package/modules/react-native-fundamentals/walkthrough.md +84 -0
- package/modules/registry.yaml +1650 -0
- package/modules/risk-management/content.md +162 -0
- package/modules/risk-management/exercises.md +86 -0
- package/modules/risk-management/module.yaml +41 -0
- package/modules/risk-management/quick-ref.md +82 -0
- package/modules/risk-management/quiz.md +73 -0
- package/modules/risk-management/resources.md +40 -0
- package/modules/risk-management/walkthrough.md +67 -0
- package/modules/running-effective-standups/content.md +119 -0
- package/modules/running-effective-standups/exercises.md +79 -0
- package/modules/running-effective-standups/module.yaml +40 -0
- package/modules/running-effective-standups/quick-ref.md +61 -0
- package/modules/running-effective-standups/quiz.md +73 -0
- package/modules/running-effective-standups/resources.md +36 -0
- package/modules/running-effective-standups/walkthrough.md +76 -0
- package/modules/solid-principles/content.md +154 -0
- package/modules/solid-principles/exercises.md +107 -0
- package/modules/solid-principles/module.yaml +42 -0
- package/modules/solid-principles/quick-ref.md +50 -0
- package/modules/solid-principles/quiz.md +102 -0
- package/modules/solid-principles/resources.md +39 -0
- package/modules/solid-principles/walkthrough.md +84 -0
- package/modules/sprint-planning/content.md +142 -0
- package/modules/sprint-planning/exercises.md +79 -0
- package/modules/sprint-planning/game.yaml +84 -0
- package/modules/sprint-planning/module.yaml +44 -0
- package/modules/sprint-planning/quick-ref.md +76 -0
- package/modules/sprint-planning/quiz.md +102 -0
- package/modules/sprint-planning/resources.md +39 -0
- package/modules/sprint-planning/walkthrough.md +75 -0
- package/modules/sql-fundamentals/content.md +160 -0
- package/modules/sql-fundamentals/exercises.md +87 -0
- package/modules/sql-fundamentals/game.yaml +105 -0
- package/modules/sql-fundamentals/module.yaml +45 -0
- package/modules/sql-fundamentals/quick-ref.md +53 -0
- package/modules/sql-fundamentals/quiz.md +103 -0
- package/modules/sql-fundamentals/resources.md +42 -0
- package/modules/sql-fundamentals/walkthrough.md +92 -0
- package/modules/sql-fundamentals/workshop.yaml +109 -0
- package/modules/stakeholder-communication/content.md +186 -0
- package/modules/stakeholder-communication/exercises.md +87 -0
- package/modules/stakeholder-communication/module.yaml +38 -0
- package/modules/stakeholder-communication/quick-ref.md +89 -0
- package/modules/stakeholder-communication/quiz.md +73 -0
- package/modules/stakeholder-communication/resources.md +41 -0
- package/modules/stakeholder-communication/walkthrough.md +74 -0
- package/modules/system-design/content.md +149 -0
- package/modules/system-design/exercises.md +83 -0
- package/modules/system-design/game.yaml +95 -0
- package/modules/system-design/module.yaml +46 -0
- package/modules/system-design/quick-ref.md +59 -0
- package/modules/system-design/quiz.md +102 -0
- package/modules/system-design/resources.md +46 -0
- package/modules/system-design/walkthrough.md +90 -0
- package/modules/team-topologies/content.md +166 -0
- package/modules/team-topologies/exercises.md +85 -0
- package/modules/team-topologies/module.yaml +41 -0
- package/modules/team-topologies/quick-ref.md +61 -0
- package/modules/team-topologies/quiz.md +101 -0
- package/modules/team-topologies/resources.md +37 -0
- package/modules/team-topologies/walkthrough.md +76 -0
- package/modules/technical-debt/content.md +111 -0
- package/modules/technical-debt/exercises.md +92 -0
- package/modules/technical-debt/module.yaml +39 -0
- package/modules/technical-debt/quick-ref.md +60 -0
- package/modules/technical-debt/quiz.md +73 -0
- package/modules/technical-debt/resources.md +25 -0
- package/modules/technical-debt/walkthrough.md +94 -0
- package/modules/technical-mentoring/content.md +128 -0
- package/modules/technical-mentoring/exercises.md +84 -0
- package/modules/technical-mentoring/module.yaml +41 -0
- package/modules/technical-mentoring/quick-ref.md +74 -0
- package/modules/technical-mentoring/quiz.md +73 -0
- package/modules/technical-mentoring/resources.md +33 -0
- package/modules/technical-mentoring/walkthrough.md +65 -0
- package/modules/test-strategy/content.md +136 -0
- package/modules/test-strategy/exercises.md +84 -0
- package/modules/test-strategy/game.yaml +99 -0
- package/modules/test-strategy/module.yaml +45 -0
- package/modules/test-strategy/quick-ref.md +66 -0
- package/modules/test-strategy/quiz.md +99 -0
- package/modules/test-strategy/resources.md +60 -0
- package/modules/test-strategy/walkthrough.md +97 -0
- package/modules/test-strategy/workshop.yaml +96 -0
- package/modules/typescript-fundamentals/content.md +127 -0
- package/modules/typescript-fundamentals/exercises.md +79 -0
- package/modules/typescript-fundamentals/game.yaml +111 -0
- package/modules/typescript-fundamentals/module.yaml +45 -0
- package/modules/typescript-fundamentals/quick-ref.md +55 -0
- package/modules/typescript-fundamentals/quiz.md +104 -0
- package/modules/typescript-fundamentals/resources.md +42 -0
- package/modules/typescript-fundamentals/walkthrough.md +71 -0
- package/modules/typescript-fundamentals/workshop.yaml +146 -0
- package/modules/user-story-mapping/content.md +123 -0
- package/modules/user-story-mapping/exercises.md +87 -0
- package/modules/user-story-mapping/module.yaml +41 -0
- package/modules/user-story-mapping/quick-ref.md +64 -0
- package/modules/user-story-mapping/quiz.md +73 -0
- package/modules/user-story-mapping/resources.md +29 -0
- package/modules/user-story-mapping/walkthrough.md +86 -0
- package/modules/writing-prds/content.md +133 -0
- package/modules/writing-prds/exercises.md +93 -0
- package/modules/writing-prds/game.yaml +83 -0
- package/modules/writing-prds/module.yaml +44 -0
- package/modules/writing-prds/quick-ref.md +77 -0
- package/modules/writing-prds/quiz.md +103 -0
- package/modules/writing-prds/resources.md +30 -0
- package/modules/writing-prds/walkthrough.md +87 -0
- package/package.json +5 -3
- package/src/server.js +17 -7
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
scenarios:
|
|
2
|
+
- id: naming-refactor
|
|
3
|
+
title: "Fix Bad Variable and Function Names"
|
|
4
|
+
difficulty: beginner
|
|
5
|
+
xp: 25
|
|
6
|
+
setup:
|
|
7
|
+
- "mkdir -p workshop && cd workshop"
|
|
8
|
+
files:
|
|
9
|
+
- name: utils.js
|
|
10
|
+
content: |
|
|
11
|
+
function d(x) {
|
|
12
|
+
return x * 2;
|
|
13
|
+
}
|
|
14
|
+
function t(a, b) {
|
|
15
|
+
return a + b;
|
|
16
|
+
}
|
|
17
|
+
let a = [1, 2, 3];
|
|
18
|
+
let r = a.map(i => i * 3);
|
|
19
|
+
let m = r.reduce((p, c) => p + c, 0);
|
|
20
|
+
module.exports = { d, t };
|
|
21
|
+
language: javascript
|
|
22
|
+
readonly: false
|
|
23
|
+
task: "Rename all variables and functions to be meaningful and self-documenting. A reader should understand what the code does from names alone."
|
|
24
|
+
validations:
|
|
25
|
+
- label: "utils.js was refactored with clear names"
|
|
26
|
+
check: file-changed
|
|
27
|
+
pattern: "utils.js"
|
|
28
|
+
hints:
|
|
29
|
+
- "What does 'd' do? What would you call a function that doubles a number?"
|
|
30
|
+
- "Consider: inputValue, doubledValue, numbers, tripledNumbers, sum."
|
|
31
|
+
- "Names like double, add, numbers, tripledNumbers, total improve readability."
|
|
32
|
+
agent_prompts:
|
|
33
|
+
on_start: "When you look at this code, what story do the names tell? What would a new teammate guess each function does?"
|
|
34
|
+
|
|
35
|
+
- id: extract-functions
|
|
36
|
+
title: "Extract a Long Function into Smaller Ones"
|
|
37
|
+
difficulty: intermediate
|
|
38
|
+
xp: 30
|
|
39
|
+
setup:
|
|
40
|
+
- "mkdir -p workshop && cd workshop"
|
|
41
|
+
files:
|
|
42
|
+
- name: processOrder.js
|
|
43
|
+
content: |
|
|
44
|
+
function processOrder(order) {
|
|
45
|
+
if (!order || typeof order !== 'object') {
|
|
46
|
+
throw new Error('Invalid order');
|
|
47
|
+
}
|
|
48
|
+
if (!order.items || !Array.isArray(order.items) || order.items.length === 0) {
|
|
49
|
+
throw new Error('Order must have at least one item');
|
|
50
|
+
}
|
|
51
|
+
if (!order.customerId || typeof order.customerId !== 'string') {
|
|
52
|
+
throw new Error('Valid customerId required');
|
|
53
|
+
}
|
|
54
|
+
let subtotal = 0;
|
|
55
|
+
for (const item of order.items) {
|
|
56
|
+
if (!item.price || !item.quantity || item.quantity < 1) {
|
|
57
|
+
throw new Error('Each item must have price and quantity >= 1');
|
|
58
|
+
}
|
|
59
|
+
subtotal += item.price * item.quantity;
|
|
60
|
+
}
|
|
61
|
+
const taxRate = 0.08;
|
|
62
|
+
const tax = subtotal * taxRate;
|
|
63
|
+
const total = subtotal + tax;
|
|
64
|
+
const summary = `Order for customer ${order.customerId}: ${order.items.length} items, subtotal $${subtotal.toFixed(2)}, tax $${tax.toFixed(2)}, total $${total.toFixed(2)}`;
|
|
65
|
+
return { subtotal, tax, total, summary };
|
|
66
|
+
}
|
|
67
|
+
module.exports = { processOrder };
|
|
68
|
+
language: javascript
|
|
69
|
+
readonly: false
|
|
70
|
+
task: "Break this 40-line function into 4-5 smaller, focused functions. Each function should do one thing. The main processOrder should orchestrate them."
|
|
71
|
+
validations:
|
|
72
|
+
- label: "processOrder.js was refactored into smaller functions"
|
|
73
|
+
check: file-changed
|
|
74
|
+
pattern: "processOrder.js"
|
|
75
|
+
hints:
|
|
76
|
+
- "Can you identify distinct responsibilities? Validation, calculation, formatting are often separate."
|
|
77
|
+
- "Functions like validateOrder, calculateSubtotal, calculateTax, formatSummary could each handle one concern."
|
|
78
|
+
- "The main function becomes a sequence of calls—easier to read and test."
|
|
79
|
+
agent_prompts:
|
|
80
|
+
on_start: "What different jobs does this function perform? How might splitting them make the code easier to reason about and test?"
|
|
81
|
+
|
|
82
|
+
- id: remove-duplication
|
|
83
|
+
title: "Apply DRY—Remove Duplication in Handlers"
|
|
84
|
+
difficulty: intermediate
|
|
85
|
+
xp: 35
|
|
86
|
+
setup:
|
|
87
|
+
- "mkdir -p workshop && cd workshop"
|
|
88
|
+
files:
|
|
89
|
+
- name: handlers.js
|
|
90
|
+
content: |
|
|
91
|
+
function handleCreate(req, res) {
|
|
92
|
+
const body = JSON.parse(req.body || '{}');
|
|
93
|
+
if (!body.name || typeof body.name !== 'string') {
|
|
94
|
+
res.status(400).json({ error: 'Name is required' });
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const trimmed = body.name.trim();
|
|
98
|
+
if (trimmed.length === 0) {
|
|
99
|
+
res.status(400).json({ error: 'Name cannot be empty' });
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const item = { id: Date.now(), name: trimmed };
|
|
103
|
+
res.status(201).json(item);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function handleUpdate(req, res) {
|
|
107
|
+
const body = JSON.parse(req.body || '{}');
|
|
108
|
+
if (!body.name || typeof body.name !== 'string') {
|
|
109
|
+
res.status(400).json({ error: 'Name is required' });
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const trimmed = body.name.trim();
|
|
113
|
+
if (trimmed.length === 0) {
|
|
114
|
+
res.status(400).json({ error: 'Name cannot be empty' });
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const item = { id: req.params.id, name: trimmed };
|
|
118
|
+
res.status(200).json(item);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function handlePatch(req, res) {
|
|
122
|
+
const body = JSON.parse(req.body || '{}');
|
|
123
|
+
if (!body.name || typeof body.name !== 'string') {
|
|
124
|
+
res.status(400).json({ error: 'Name is required' });
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const trimmed = body.name.trim();
|
|
128
|
+
if (trimmed.length === 0) {
|
|
129
|
+
res.status(400).json({ error: 'Name cannot be empty' });
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const item = { id: req.params.id, name: trimmed };
|
|
133
|
+
res.status(200).json(item);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
module.exports = { handleCreate, handleUpdate, handlePatch };
|
|
137
|
+
language: javascript
|
|
138
|
+
readonly: false
|
|
139
|
+
task: "Extract the shared validation and logic. The three handlers have nearly identical validation and trimming. Create a helper and reduce duplication."
|
|
140
|
+
validations:
|
|
141
|
+
- label: "handlers.js was refactored to remove duplication"
|
|
142
|
+
check: file-changed
|
|
143
|
+
pattern: "handlers.js"
|
|
144
|
+
hints:
|
|
145
|
+
- "What lines appear in all three handlers? Validation and trimming are identical."
|
|
146
|
+
- "A function like parseAndValidateName(body) could return { valid, error, name }."
|
|
147
|
+
- "Each handler would call the helper and branch on valid/invalid—one place to fix validation bugs."
|
|
148
|
+
agent_prompts:
|
|
149
|
+
on_start: "If the product owner changes the rules for a valid name, how many places would you update today? What would make that number smaller?"
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Code Review — Giving and Receiving Feedback
|
|
2
|
+
|
|
3
|
+
<!-- hint:slides topic="Code review: review checklist (correctness, readability, security), giving constructive feedback, and PR lifecycle" slides="5" -->
|
|
4
|
+
|
|
5
|
+
## Why Code Reviews Matter
|
|
6
|
+
|
|
7
|
+
Code review is a process where someone other than the author examines code before it merges. It catches bugs, improves design, spreads knowledge, and upholds team standards. Reviews are about the code, not the person.
|
|
8
|
+
|
|
9
|
+
## What to Look For
|
|
10
|
+
|
|
11
|
+
### Correctness
|
|
12
|
+
Does the code do what it claims? Are edge cases handled? Could it fail in production?
|
|
13
|
+
|
|
14
|
+
### Readability
|
|
15
|
+
- **Naming:** Clear, consistent variable and function names
|
|
16
|
+
- **Comments:** Explain *why*, not *what*
|
|
17
|
+
- **Structure:** Logic flows naturally; no magic numbers or deep nesting
|
|
18
|
+
|
|
19
|
+
### Performance
|
|
20
|
+
- Unnecessary loops or allocations?
|
|
21
|
+
- O(n²) when O(n) is possible?
|
|
22
|
+
- Blocking calls in hot paths?
|
|
23
|
+
|
|
24
|
+
### Security
|
|
25
|
+
- Input validation and sanitization
|
|
26
|
+
- No hardcoded secrets or credentials
|
|
27
|
+
- Sensitive data handling
|
|
28
|
+
|
|
29
|
+
```javascript
|
|
30
|
+
// ❌ Security risk: SQL injection
|
|
31
|
+
const query = `SELECT * FROM users WHERE id = ${userId}`;
|
|
32
|
+
|
|
33
|
+
// ✅ Parameterized query
|
|
34
|
+
const query = 'SELECT * FROM users WHERE id = ?';
|
|
35
|
+
db.execute(query, [userId]);
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Writing Good PR Descriptions
|
|
39
|
+
|
|
40
|
+
A good description explains **what**, **why**, and **how**:
|
|
41
|
+
|
|
42
|
+
```markdown
|
|
43
|
+
## What
|
|
44
|
+
Add user profile export as JSON.
|
|
45
|
+
|
|
46
|
+
## Why
|
|
47
|
+
Product needs GDPR "data portability" compliance by Q2.
|
|
48
|
+
|
|
49
|
+
## How
|
|
50
|
+
- New `/api/me/export` endpoint
|
|
51
|
+
- Uses existing serialization layer
|
|
52
|
+
- Rate-limited to 1 req/min per user
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Include testing notes, screenshots for UI changes, and migration steps when relevant.
|
|
56
|
+
|
|
57
|
+
## Giving Feedback
|
|
58
|
+
|
|
59
|
+
### Be Specific
|
|
60
|
+
❌ "This is wrong."
|
|
61
|
+
✅ "This loop runs O(n²) when the input can be large; consider a Map for O(n) lookups."
|
|
62
|
+
|
|
63
|
+
### Explain Why
|
|
64
|
+
❌ "Use `const` here."
|
|
65
|
+
✅ "Using `const` here prevents accidental reassignment and signals immutability to readers."
|
|
66
|
+
|
|
67
|
+
### Suggest Alternatives
|
|
68
|
+
❌ "Refactor this."
|
|
69
|
+
✅ "This function is doing three things. Consider extracting validation and formatting into separate helpers."
|
|
70
|
+
|
|
71
|
+
### Separate Nitpicks
|
|
72
|
+
Mark minor preferences as "nit:" so authors can address them without blocking merge.
|
|
73
|
+
|
|
74
|
+
## Receiving Feedback
|
|
75
|
+
|
|
76
|
+
### Don't Take It Personally
|
|
77
|
+
Feedback targets the code, not you. Even senior engineers get thorough reviews.
|
|
78
|
+
|
|
79
|
+
### Ask Questions
|
|
80
|
+
If a suggestion is unclear, ask: "Can you elaborate on why X would be better here?"
|
|
81
|
+
|
|
82
|
+
### Disagree Thoughtfully
|
|
83
|
+
It's OK to push back. Explain your reasoning: "I considered X, but chose Y because..."
|
|
84
|
+
|
|
85
|
+
## Review Checklists
|
|
86
|
+
|
|
87
|
+
**Before submitting:**
|
|
88
|
+
- [ ] Tests pass locally
|
|
89
|
+
- [ ] PR description is complete
|
|
90
|
+
- [ ] No debug logs or commented code
|
|
91
|
+
- [ ] Changes are scoped to the stated goal
|
|
92
|
+
|
|
93
|
+
**When reviewing:**
|
|
94
|
+
- [ ] Understand the goal before reading code
|
|
95
|
+
- [ ] Check tests cover the new behavior
|
|
96
|
+
- [ ] Verify no regressions introduced
|
|
97
|
+
- [ ] Approve or request changes promptly
|
|
98
|
+
|
|
99
|
+
## Common Anti-Patterns
|
|
100
|
+
|
|
101
|
+
| Anti-Pattern | Problem |
|
|
102
|
+
|--------------|---------|
|
|
103
|
+
| "LGTM" without reading | Rubber-stamping; defeats the purpose |
|
|
104
|
+
| Nitpicking style only | Misses design and correctness |
|
|
105
|
+
| Blocking on opinions | Distinguish "must fix" vs "nice to have" |
|
|
106
|
+
| Delayed feedback | Blocks the author's flow |
|
|
107
|
+
| Dismissive tone | "Obviously wrong" → demoralizes |
|
|
108
|
+
|
|
109
|
+
## PR Lifecycle
|
|
110
|
+
|
|
111
|
+
```mermaid
|
|
112
|
+
flowchart TD
|
|
113
|
+
A[Author writes code] --> B[Author creates PR]
|
|
114
|
+
B --> C[Reviewer(s) assigned]
|
|
115
|
+
C --> D{Review passes?}
|
|
116
|
+
D -->|No| E[Author addresses feedback]
|
|
117
|
+
E --> C
|
|
118
|
+
D -->|Yes| F[Approve & merge]
|
|
119
|
+
F --> G[Post-merge: monitor, document]
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Key Takeaways
|
|
125
|
+
|
|
126
|
+
1. **Correctness first** — then readability, performance, security
|
|
127
|
+
2. **Specific, kind feedback** — explain why, suggest alternatives
|
|
128
|
+
3. **Separate blocking vs nitpicks** — unblock quickly when possible
|
|
129
|
+
4. **PR descriptions matter** — context speeds reviews
|
|
130
|
+
5. **Reviews are for the code** — keep feedback professional and constructive
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Code Review Exercises
|
|
2
|
+
|
|
3
|
+
## Exercise 1: Write a PR Description
|
|
4
|
+
|
|
5
|
+
**Task:** Create a PR description for a hypothetical change: "Add input validation to the login form to reject empty username and password."
|
|
6
|
+
|
|
7
|
+
**Validation:**
|
|
8
|
+
- [ ] Contains "What" section describing the change
|
|
9
|
+
- [ ] Contains "Why" section explaining the rationale
|
|
10
|
+
- [ ] Contains "How" section with implementation notes
|
|
11
|
+
- [ ] Includes at least one testing note
|
|
12
|
+
|
|
13
|
+
**Hints:**
|
|
14
|
+
1. What = the concrete change (validation logic, error messages)
|
|
15
|
+
2. Why = security, UX, or compliance reason
|
|
16
|
+
3. How = where validation runs, what gets validated
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Exercise 2: Transform Vague Feedback
|
|
21
|
+
|
|
22
|
+
**Task:** A reviewer wrote: "This could be better." The code in question uses a nested `for` loop to find duplicates in an array. Rewrite this as specific, constructive feedback with a suggested alternative.
|
|
23
|
+
|
|
24
|
+
**Validation:**
|
|
25
|
+
- [ ] Identifies the specific issue (e.g., O(n²) complexity)
|
|
26
|
+
- [ ] Explains why it matters (performance, scalability)
|
|
27
|
+
- [ ] Suggests an alternative (e.g., Set, Map, or sort-then-compare)
|
|
28
|
+
|
|
29
|
+
**Hints:**
|
|
30
|
+
1. Vague feedback leaves the author guessing — be concrete
|
|
31
|
+
2. Explain the tradeoff (nested loops vs Set.has)
|
|
32
|
+
3. A code snippet or pseudocode helps
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Exercise 3: Prioritize Review Comments
|
|
37
|
+
|
|
38
|
+
**Task:** You received these five comments on a PR. Order them by priority (highest first) and label each: blocking, should-fix, or nit.
|
|
39
|
+
|
|
40
|
+
- "Use `const` instead of `let` for `config`"
|
|
41
|
+
- "The password is echoed in logs on line 89"
|
|
42
|
+
- "Consider extracting this into a helper function"
|
|
43
|
+
- "Possible race condition: two requests could overwrite the same file"
|
|
44
|
+
- "Typo: 'recieve' → 'receive'"
|
|
45
|
+
|
|
46
|
+
**Validation:**
|
|
47
|
+
- [ ] Security issue (password in logs) is highest or second-highest
|
|
48
|
+
- [ ] Race condition is blocking or should-fix
|
|
49
|
+
- [ ] Style (const, extract helper) is nit or lower priority
|
|
50
|
+
- [ ] Typo is nit
|
|
51
|
+
|
|
52
|
+
**Hints:**
|
|
53
|
+
1. Security and correctness trump style
|
|
54
|
+
2. Race conditions can cause data loss — treat seriously
|
|
55
|
+
3. Nits improve quality but don't block merge
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Exercise 4: Respond to Critical Feedback
|
|
60
|
+
|
|
61
|
+
**Task:** A senior reviewer wrote: "This approach won't scale. We'll have thousands of users and this does a full table scan per request." Your implementation uses `SELECT * FROM users WHERE ...` without an index.
|
|
62
|
+
|
|
63
|
+
Write a constructive response (2–4 sentences) that:
|
|
64
|
+
1. Acknowledges the concern
|
|
65
|
+
2. Shows you understand the problem
|
|
66
|
+
3. Proposes or asks about a fix (index, caching, or different query)
|
|
67
|
+
|
|
68
|
+
**Validation:**
|
|
69
|
+
- [ ] No defensive tone ("it works for now")
|
|
70
|
+
- [ ] Demonstrates understanding of the scalability issue
|
|
71
|
+
- [ ] Proposes a concrete next step or asks for guidance
|
|
72
|
+
|
|
73
|
+
**Hints:**
|
|
74
|
+
1. "You're right" or "Good catch" shows receptiveness
|
|
75
|
+
2. Indexes, caching, or pagination are common fixes
|
|
76
|
+
3. Asking "Should I add an index on X?" is collaborative
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Exercise 5: Create a Review Checklist
|
|
81
|
+
|
|
82
|
+
**Task:** Build a 6-item checklist for code reviews you perform. Include at least one item from each category: correctness, readability, security, tests, and process.
|
|
83
|
+
|
|
84
|
+
**Validation:**
|
|
85
|
+
- [ ] At least 6 items
|
|
86
|
+
- [ ] Covers correctness (e.g., edge cases, error handling)
|
|
87
|
+
- [ ] Covers readability (naming, structure)
|
|
88
|
+
- [ ] Covers security (inputs, secrets)
|
|
89
|
+
- [ ] Covers tests (new code has tests)
|
|
90
|
+
- [ ] Covers process (PR description, scope)
|
|
91
|
+
|
|
92
|
+
**Hints:**
|
|
93
|
+
1. "Does the PR description explain the goal?" is a good process item
|
|
94
|
+
2. "Are new code paths covered by tests?" ensures quality
|
|
95
|
+
3. "Any hardcoded secrets or credentials?" is a security staple
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
games:
|
|
2
|
+
- type: scenario
|
|
3
|
+
title: "PR Review Crisis"
|
|
4
|
+
startHealth: 5
|
|
5
|
+
steps:
|
|
6
|
+
- id: start
|
|
7
|
+
situation: "A teammate opens a 2,000-line PR that touches auth, DB migrations, and 12 files. It's Friday afternoon. You're asked to review. How do you prioritize?"
|
|
8
|
+
choices:
|
|
9
|
+
- text: "Triage: skim for high-risk areas (auth, migrations, security), then focus feedback there first."
|
|
10
|
+
consequence: "Smart. You use risk to prioritize. Auth and migrations deserve careful review; trivial changes can wait."
|
|
11
|
+
health: 1
|
|
12
|
+
next: tone
|
|
13
|
+
- text: "Review every line from top to bottom."
|
|
14
|
+
consequence: "Thorough but inefficient. A 2000-line PR in one sitting leads to fatigue and missed issues."
|
|
15
|
+
health: -1
|
|
16
|
+
next: tone
|
|
17
|
+
- text: "Approve quickly and say you'll do a deeper pass later."
|
|
18
|
+
consequence: "Approving without proper review risks merging bugs. Later rarely happens."
|
|
19
|
+
health: -2
|
|
20
|
+
next: bad_choice
|
|
21
|
+
- id: tone
|
|
22
|
+
situation: "You find a security issue: the new auth path doesn't validate the redirect URL, enabling open redirect. How do you phrase the feedback?"
|
|
23
|
+
choices:
|
|
24
|
+
- text: "I noticed the redirect URL isn't validated — could lead to open redirect. Suggest we add a allowlist check."
|
|
25
|
+
consequence: "Constructive and specific. You state the problem and a concrete fix. Professional tone."
|
|
26
|
+
health: 1
|
|
27
|
+
next: disagreement
|
|
28
|
+
- text: "This is a security hole. Why wasn't this caught before?"
|
|
29
|
+
consequence: "Accusatory. The author may get defensive. Security matters, but tone affects collaboration."
|
|
30
|
+
health: -1
|
|
31
|
+
next: disagreement
|
|
32
|
+
- text: "LGTM with minor comments."
|
|
33
|
+
consequence: "Open redirect is not minor. Undermining serious feedback can let bugs slip through."
|
|
34
|
+
health: -2
|
|
35
|
+
next: bad_choice
|
|
36
|
+
- id: disagreement
|
|
37
|
+
situation: "The author disagrees with your feedback. They say the redirect is 'internal only' and low risk. You believe it's still exploitable. What do you do?"
|
|
38
|
+
choices:
|
|
39
|
+
- text: "Share a minimal exploit or reference (e.g. OWASP) and suggest discussing in a call if needed."
|
|
40
|
+
consequence: "Evidence-based. You back your point with data. Opens constructive discussion."
|
|
41
|
+
health: 1
|
|
42
|
+
next: approve_decision
|
|
43
|
+
- text: "Insist they fix it or you won't approve."
|
|
44
|
+
consequence: "Standing firm can be right, but escalating without evidence may create friction."
|
|
45
|
+
health: 0
|
|
46
|
+
next: approve_decision
|
|
47
|
+
- text: "Drop it and approve — they own the code."
|
|
48
|
+
consequence: "Security issues shouldn't be dropped for ownership. You're responsible too as reviewer."
|
|
49
|
+
health: -2
|
|
50
|
+
next: bad_choice
|
|
51
|
+
- id: approve_decision
|
|
52
|
+
situation: "The author fixed the redirect issue. You've reviewed the high-risk areas. The PR also has some style nitpicks and a few unclear variable names. Do you approve or request changes?"
|
|
53
|
+
choices:
|
|
54
|
+
- text: "Approve with a short list of non-blocking suggestions (style, naming) for follow-up."
|
|
55
|
+
consequence: "Pragmatic. You unblock the author while capturing improvement ideas. Ship and iterate."
|
|
56
|
+
health: 1
|
|
57
|
+
next: success
|
|
58
|
+
- text: "Request changes — insist on fixing every nit before merge."
|
|
59
|
+
consequence: "Perfectionism can block progress. Critical fixes yes; style nits can be follow-up."
|
|
60
|
+
health: -1
|
|
61
|
+
next: success
|
|
62
|
+
- text: "Approve without any other feedback."
|
|
63
|
+
consequence: "You could have added value with non-blocking suggestions. Missed a teaching moment."
|
|
64
|
+
health: 0
|
|
65
|
+
next: success
|
|
66
|
+
- id: bad_choice
|
|
67
|
+
situation: "That choice didn't serve the team. PR review should be constructive, risk-aware, and collaborative. Try to recover."
|
|
68
|
+
choices:
|
|
69
|
+
- text: "Restart with a better approach."
|
|
70
|
+
consequence: "Every review is a chance to improve."
|
|
71
|
+
health: 0
|
|
72
|
+
next: start
|
|
73
|
+
- text: "Accept the consequences."
|
|
74
|
+
consequence: "Sometimes we learn the hard way."
|
|
75
|
+
health: 0
|
|
76
|
+
next: end
|
|
77
|
+
- id: success
|
|
78
|
+
situation: "The PR is merged. You provided focused, constructive feedback. The author appreciated the security catch. Well done!"
|
|
79
|
+
choices:
|
|
80
|
+
- text: "Continue."
|
|
81
|
+
consequence: "You navigated the PR review crisis successfully."
|
|
82
|
+
health: 0
|
|
83
|
+
next: end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
slug: code-review
|
|
2
|
+
title: "Code Review — Giving and Receiving Feedback"
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
description: "Master code reviews — what to look for, how to give feedback, and how to receive it constructively."
|
|
5
|
+
category: developer-skills
|
|
6
|
+
tags: [code-review, feedback, collaboration, pull-requests, quality]
|
|
7
|
+
difficulty: beginner
|
|
8
|
+
|
|
9
|
+
xp:
|
|
10
|
+
read: 10
|
|
11
|
+
walkthrough: 30
|
|
12
|
+
exercise: 20
|
|
13
|
+
quiz: 15
|
|
14
|
+
quiz-perfect-bonus: 10
|
|
15
|
+
game: 20
|
|
16
|
+
game-perfect-bonus: 10
|
|
17
|
+
|
|
18
|
+
time:
|
|
19
|
+
quick: 5
|
|
20
|
+
read: 15
|
|
21
|
+
guided: 40
|
|
22
|
+
|
|
23
|
+
prerequisites: []
|
|
24
|
+
related: [clean-code, technical-debt]
|
|
25
|
+
|
|
26
|
+
triggers:
|
|
27
|
+
- "How do I do a good code review?"
|
|
28
|
+
- "How do I give constructive code feedback?"
|
|
29
|
+
- "What should I look for in a code review?"
|
|
30
|
+
- "How do I handle code review comments?"
|
|
31
|
+
|
|
32
|
+
visuals:
|
|
33
|
+
diagrams: [diagram-flow]
|
|
34
|
+
quiz-types: [quiz-drag-order, quiz-timed-choice]
|
|
35
|
+
game-types: [scenario]
|
|
36
|
+
playground: null
|
|
37
|
+
slides: true
|
|
38
|
+
|
|
39
|
+
sources:
|
|
40
|
+
- url: "https://google.github.io/eng-practices/review/"
|
|
41
|
+
label: "Google's Engineering Practices (Code Review)"
|
|
42
|
+
type: docs
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Code Review Quick Reference
|
|
2
|
+
|
|
3
|
+
## What to Look For
|
|
4
|
+
|
|
5
|
+
| Area | Questions to Ask |
|
|
6
|
+
|------|------------------|
|
|
7
|
+
| Correctness | Does it work? Edge cases? Error handling? |
|
|
8
|
+
| Readability | Clear names? Comments explain why? Logic easy to follow? |
|
|
9
|
+
| Performance | Unnecessary work? Scalability concerns? |
|
|
10
|
+
| Security | Input validated? No secrets in code? Sensitive data handled safely? |
|
|
11
|
+
| Tests | New behavior covered? Regressions prevented? |
|
|
12
|
+
|
|
13
|
+
## Giving Feedback
|
|
14
|
+
|
|
15
|
+
| Do | Don't |
|
|
16
|
+
|----|-------|
|
|
17
|
+
| Be specific ("Rename `x` to `userCount`") | Be vague ("This could be better") |
|
|
18
|
+
| Explain why ("Prevents accidental reassignment") | Assume they know |
|
|
19
|
+
| Suggest alternatives | Only criticize |
|
|
20
|
+
| Mark nits as "nit:" | Block on style preferences |
|
|
21
|
+
| Respond promptly | Let PRs sit for days |
|
|
22
|
+
|
|
23
|
+
## PR Description Template
|
|
24
|
+
|
|
25
|
+
```markdown
|
|
26
|
+
## What
|
|
27
|
+
[One-line summary of the change]
|
|
28
|
+
|
|
29
|
+
## Why
|
|
30
|
+
[Problem being solved, ticket, compliance]
|
|
31
|
+
|
|
32
|
+
## How
|
|
33
|
+
[Key implementation notes, tradeoffs]
|
|
34
|
+
|
|
35
|
+
## Testing
|
|
36
|
+
[How you tested, what to verify]
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Receiving Feedback
|
|
40
|
+
|
|
41
|
+
| Do | Don't |
|
|
42
|
+
|----|-------|
|
|
43
|
+
| Assume good intent | Take it personally |
|
|
44
|
+
| Ask clarifying questions | Get defensive |
|
|
45
|
+
| Disagree with reasoning | Dismiss without discussion |
|
|
46
|
+
| Thank reviewers | Ignore nits rudely |
|
|
47
|
+
|
|
48
|
+
## Priority Levels
|
|
49
|
+
|
|
50
|
+
| Level | Meaning | Action |
|
|
51
|
+
|-------|---------|--------|
|
|
52
|
+
| Blocking | Must fix before merge | Address before approval |
|
|
53
|
+
| Should fix | Important but not blocking | Fix if quick; otherwise follow up |
|
|
54
|
+
| Nit | Nice to have | Optional; author decides |
|
|
55
|
+
|
|
56
|
+
## Common Anti-Patterns
|
|
57
|
+
|
|
58
|
+
| Anti-Pattern | Fix |
|
|
59
|
+
|--------------|-----|
|
|
60
|
+
| "LGTM" without reading | Actually read and verify |
|
|
61
|
+
| Blocking on opinions | Distinguish must vs nice-to-have |
|
|
62
|
+
| Delayed feedback | Review within 24h when possible |
|
|
63
|
+
| Dismissive tone | Be kind and professional |
|
|
64
|
+
|
|
65
|
+
## Checklist: Before Submitting PR
|
|
66
|
+
|
|
67
|
+
- [ ] Tests pass
|
|
68
|
+
- [ ] Description complete (What/Why/How)
|
|
69
|
+
- [ ] No debug logs or commented code
|
|
70
|
+
- [ ] Changes scoped to stated goal
|
|
71
|
+
|
|
72
|
+
## Checklist: When Reviewing
|
|
73
|
+
|
|
74
|
+
- [ ] Read description first
|
|
75
|
+
- [ ] Verify tests cover new behavior
|
|
76
|
+
- [ ] Check for regressions
|
|
77
|
+
- [ ] Approve or request changes promptly
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Code Review Quiz
|
|
2
|
+
|
|
3
|
+
## Question 1
|
|
4
|
+
|
|
5
|
+
What should you prioritize when reviewing code?
|
|
6
|
+
|
|
7
|
+
A) Style and formatting first
|
|
8
|
+
B) Correctness, then readability, performance, security
|
|
9
|
+
C) Whatever the author asks you to look at
|
|
10
|
+
D) Only security issues
|
|
11
|
+
|
|
12
|
+
<!-- ANSWER: B -->
|
|
13
|
+
<!-- EXPLANATION: Correctness is the foundation — does it work? Then readability (can others maintain it?), performance (will it scale?), and security (is it safe?). Style matters but shouldn't block merge for minor nits. -->
|
|
14
|
+
|
|
15
|
+
## Question 2
|
|
16
|
+
|
|
17
|
+
A reviewer wrote: "Use a better variable name." What's wrong with this feedback?
|
|
18
|
+
|
|
19
|
+
A) Nothing — it's clear enough
|
|
20
|
+
B) It's too vague; the author doesn't know what to change or why
|
|
21
|
+
C) Reviewers shouldn't comment on variable names
|
|
22
|
+
D) It should be marked as blocking
|
|
23
|
+
|
|
24
|
+
<!-- ANSWER: B -->
|
|
25
|
+
<!-- EXPLANATION: Good feedback is specific and explains why. "Use a better variable name" doesn't say which variable or what "better" means. Something like "Rename `x` to `userCount` for clarity" is actionable. -->
|
|
26
|
+
|
|
27
|
+
## Question 3
|
|
28
|
+
|
|
29
|
+
You're about to merge a PR. The tests pass, but you noticed a potential null reference when `data` is undefined. What should you do?
|
|
30
|
+
|
|
31
|
+
A) Merge anyway — tests pass
|
|
32
|
+
B) Request changes and block merge until it's fixed
|
|
33
|
+
C) Merge and file a follow-up bug
|
|
34
|
+
D) Leave a nit comment and merge
|
|
35
|
+
|
|
36
|
+
<!-- ANSWER: B -->
|
|
37
|
+
<!-- EXPLANATION: Potential null references can cause runtime crashes. If tests pass but don't cover the null case, that's a gap. Blocking merge prevents shipping a bug. Nits are style preferences; correctness issues are blocking. -->
|
|
38
|
+
|
|
39
|
+
## Question 4
|
|
40
|
+
|
|
41
|
+
Which PR description is most useful for reviewers?
|
|
42
|
+
|
|
43
|
+
A) "Fixed the bug"
|
|
44
|
+
B) "Updated validation logic per ticket #123"
|
|
45
|
+
C) "What: Add login validation. Why: Prevent empty submissions. How: Client-side check before API call; server re-validates."
|
|
46
|
+
D) "See the code"
|
|
47
|
+
|
|
48
|
+
<!-- ANSWER: C -->
|
|
49
|
+
<!-- EXPLANATION: A good description explains What (the change), Why (the reason), and How (implementation notes). This gives reviewers context to verify the approach and spot issues. Vague descriptions slow reviews. -->
|
|
50
|
+
|
|
51
|
+
## Question 5
|
|
52
|
+
|
|
53
|
+
When receiving critical feedback, what's the most constructive response?
|
|
54
|
+
|
|
55
|
+
A) "I'll fix it" (no further discussion)
|
|
56
|
+
B) "I disagree because [reason]; can we discuss?"
|
|
57
|
+
C) Ignore the comment and merge anyway
|
|
58
|
+
D) "That's not how we do it here"
|
|
59
|
+
|
|
60
|
+
<!-- ANSWER: B -->
|
|
61
|
+
<!-- EXPLANATION: Disagreeing thoughtfully is fine — explain your reasoning and invite discussion. Option A is acceptable but might miss learning. Options C and D are unprofessional and can escalate conflict. -->
|
|
62
|
+
|
|
63
|
+
## Question 6
|
|
64
|
+
|
|
65
|
+
Drag these PR lifecycle steps into the correct order:
|
|
66
|
+
|
|
67
|
+
<!-- VISUAL: quiz-drag-order -->
|
|
68
|
+
<!-- Items: Author addresses feedback, Reviewer approves, Author creates PR, Reviewer requests changes, Merge -->
|
|
69
|
+
|
|
70
|
+
A) Author creates PR → Reviewer requests changes → Author addresses feedback → Reviewer approves → Merge
|
|
71
|
+
B) Author creates PR → Reviewer approves → Merge → Author addresses feedback
|
|
72
|
+
C) Reviewer requests changes → Author creates PR → Merge
|
|
73
|
+
D) Author addresses feedback → Author creates PR → Reviewer approves → Merge
|
|
74
|
+
|
|
75
|
+
<!-- ANSWER: A -->
|
|
76
|
+
<!-- EXPLANATION: The standard flow: author creates PR, reviewer reviews and may request changes, author addresses feedback, cycle repeats until reviewer approves, then merge. -->
|
|
77
|
+
|
|
78
|
+
## Question 7
|
|
79
|
+
|
|
80
|
+
<!-- VISUAL: quiz-drag-order -->
|
|
81
|
+
|
|
82
|
+
Put these code review process steps in the correct order:
|
|
83
|
+
|
|
84
|
+
A) Reviewer reviews code
|
|
85
|
+
B) Author pushes commits addressing feedback
|
|
86
|
+
C) Author requests review
|
|
87
|
+
D) Reviewer approves or requests changes
|
|
88
|
+
E) Merge to main branch
|
|
89
|
+
|
|
90
|
+
<!-- ANSWER: C,A,D,B,E -->
|
|
91
|
+
<!-- EXPLANATION: Author requests review, reviewer reviews the code, reviewer approves or requests changes. If changes are requested, author pushes updates and the cycle repeats until approval, then merge. -->
|
|
92
|
+
|
|
93
|
+
## Question 8
|
|
94
|
+
|
|
95
|
+
<!-- VISUAL: quiz-matching -->
|
|
96
|
+
|
|
97
|
+
Match each review feedback type to its best practice:
|
|
98
|
+
|
|
99
|
+
A) Correctness issue → 1) Block merge until fixed; explain the risk
|
|
100
|
+
B) Style nit → 2) Suggest improvement but don't block; explain why it helps
|
|
101
|
+
C) Security concern → 3) Request changes with clear reproduction steps
|
|
102
|
+
D) Performance concern → 4) Flag as blocking; provide remediation guidance
|
|
103
|
+
|
|
104
|
+
<!-- ANSWER: A3,B2,C4,D2 -->
|
|
105
|
+
<!-- EXPLANATION: Correctness issues need clear reproduction steps and block merge. Style nits are suggestions. Security concerns block merge and need remediation. Performance concerns may block or be suggestions depending on severity. -->
|