@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,79 @@
|
|
|
1
|
+
# Running Effective Standups — Exercises
|
|
2
|
+
|
|
3
|
+
## Exercise 1: Diagnose and Fix
|
|
4
|
+
|
|
5
|
+
**Task:** You join a team whose standup runs 25 minutes. People go person-by-person; the manager asks follow-up questions; problem-solving happens live. Write a diagnosis (what's wrong) and a 3-step fix.
|
|
6
|
+
|
|
7
|
+
**Validation:**
|
|
8
|
+
- [ ] At least 2 anti-patterns identified
|
|
9
|
+
- [ ] Fix includes a format change and a "take it offline" rule
|
|
10
|
+
- [ ] Fix is specific (e.g., "blockers first, 2 min each")
|
|
11
|
+
|
|
12
|
+
**Hints:**
|
|
13
|
+
1. Manager asking follow-ups → status report; consider manager observing vs participating
|
|
14
|
+
2. Problem-solving live → "Let's grab X and Y after standup for 15 min"
|
|
15
|
+
3. 25 min → timebox 15, strict; move discussions offline
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Exercise 2: Format Comparison
|
|
20
|
+
|
|
21
|
+
**Task:** For each scenario, recommend a standup format and justify in 1–2 sentences: (A) 6-person colocated team, lots of pairing; (B) 4-person distributed across 3 time zones; (C) 3-person team, mostly independent work.
|
|
22
|
+
|
|
23
|
+
**Validation:**
|
|
24
|
+
- [ ] Each scenario has a format recommendation
|
|
25
|
+
- [ ] Justification references coordination needs
|
|
26
|
+
- [ ] Async considered where relevant
|
|
27
|
+
|
|
28
|
+
**Hints:**
|
|
29
|
+
1. Colocated + pairing → walk the board or blockers first; high coordination
|
|
30
|
+
2. Distributed + time zones → async or shortened sync with recorded updates
|
|
31
|
+
3. Small + independent → consider skipping or 2–3×/week
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Exercise 3: Async Template
|
|
36
|
+
|
|
37
|
+
**Task:** Create an async standup template for a Slack channel. Include: what each person posts, format (bullets? emoji?), deadline (e.g., 9am local), and how to escalate a blocker.
|
|
38
|
+
|
|
39
|
+
**Validation:**
|
|
40
|
+
- [ ] Template has clear fields (yesterday, today, blockers)
|
|
41
|
+
- [ ] Deadline and timezone specified
|
|
42
|
+
- [ ] Blocker escalation path defined
|
|
43
|
+
|
|
44
|
+
**Hints:**
|
|
45
|
+
1. Keep it short: 1–2 bullets per section
|
|
46
|
+
2. Blockers: "@channel" or DM to lead? Define it
|
|
47
|
+
3. Consider timezone: "9am in your timezone" vs "9am PT"
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Exercise 4: Anti-Pattern Role-Play
|
|
52
|
+
|
|
53
|
+
**Task:** Write a 30-second "bad standup" script where one person delivers a status report instead of a coordination update. Then rewrite it as a 30-second "good" update (same person, same work). What changed?
|
|
54
|
+
|
|
55
|
+
**Validation:**
|
|
56
|
+
- [ ] Bad script includes status-report language (long list, no asks)
|
|
57
|
+
- [ ] Good script focuses on focus + blockers + coordination
|
|
58
|
+
- [ ] Difference is clear and teachable
|
|
59
|
+
|
|
60
|
+
**Hints:**
|
|
61
|
+
1. Bad: "I worked on X, Y, Z, then did A, B, and I'm almost done with C..."
|
|
62
|
+
2. Good: "Focus today: finishing the auth merge. Blocked on QA env—can someone from DevOps help? Otherwise I'll pair with Jess on the API."
|
|
63
|
+
3. Good = shorter, has a clear "ask" or "offer"
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Exercise 5: Remote Standup Checklist
|
|
68
|
+
|
|
69
|
+
**Task:** Create a 5-item checklist for running a great remote standup. Each item should be concrete and actionable (e.g., "Cameras on for first 2 minutes").
|
|
70
|
+
|
|
71
|
+
**Validation:**
|
|
72
|
+
- [ ] 5 items, each actionable
|
|
73
|
+
- [ ] Covers tech (video, audio), facilitation, and engagement
|
|
74
|
+
- [ ] Usable by any facilitator
|
|
75
|
+
|
|
76
|
+
**Hints:**
|
|
77
|
+
1. Tech: cameras, mute when not speaking, screen share board
|
|
78
|
+
2. Facilitation: timebox, "take it offline" rule
|
|
79
|
+
3. Engagement: rotate facilitator, start with energy ("one word for how you're feeling")
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
slug: running-effective-standups
|
|
2
|
+
title: "Running Effective Standups — Beyond Status Reports"
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
description: "Transform standups from status reports into coordination events: formats, timeboxing, async options, and anti-patterns."
|
|
5
|
+
category: leadership
|
|
6
|
+
tags: [standups, daily-scrum, meetings, team-lead, communication, agile]
|
|
7
|
+
difficulty: beginner
|
|
8
|
+
|
|
9
|
+
xp:
|
|
10
|
+
read: 10
|
|
11
|
+
walkthrough: 30
|
|
12
|
+
exercise: 20
|
|
13
|
+
quiz: 15
|
|
14
|
+
quiz-perfect-bonus: 10
|
|
15
|
+
|
|
16
|
+
time:
|
|
17
|
+
quick: 5
|
|
18
|
+
read: 10
|
|
19
|
+
guided: 35
|
|
20
|
+
|
|
21
|
+
prerequisites: []
|
|
22
|
+
related: [sprint-planning, stakeholder-communication]
|
|
23
|
+
|
|
24
|
+
triggers:
|
|
25
|
+
- "How do I run a good standup?"
|
|
26
|
+
- "Our standups are boring status reports, how do I fix them?"
|
|
27
|
+
- "Should we do async standups?"
|
|
28
|
+
- "How long should a standup be?"
|
|
29
|
+
|
|
30
|
+
visuals:
|
|
31
|
+
diagrams: [diagram-flow]
|
|
32
|
+
quiz-types: [quiz-drag-order, quiz-timed-choice]
|
|
33
|
+
slides: true
|
|
34
|
+
|
|
35
|
+
sources:
|
|
36
|
+
- url: "https://scrumguides.org"
|
|
37
|
+
label: "Scrum Guide"
|
|
38
|
+
type: docs
|
|
39
|
+
- label: "Agile Retrospectives by Derby & Larsen"
|
|
40
|
+
type: book
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Running Effective Standups — Quick Reference
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
**Coordination, not reporting.** Align the team, surface blockers, decide who talks to whom.
|
|
6
|
+
|
|
7
|
+
## Formats
|
|
8
|
+
|
|
9
|
+
| Format | How It Works | Best For |
|
|
10
|
+
|--------|--------------|----------|
|
|
11
|
+
| Three questions | What I did, what I'll do, blockers | Traditional Scrum |
|
|
12
|
+
| Walk the board | Column by column, work-focused | Kanban, visual teams |
|
|
13
|
+
| Blockers first | "Anyone blocked?" then optional focus | High-dependency teams |
|
|
14
|
+
| Async | Post by deadline (Slack, doc, video) | Distributed, flex schedules |
|
|
15
|
+
|
|
16
|
+
## Timeboxing
|
|
17
|
+
|
|
18
|
+
- **Max 15 minutes** — preferably 10 or less
|
|
19
|
+
- **Take it offline:** "Let's sync on that after standup"
|
|
20
|
+
- Use a timer; when someone drones, gently redirect
|
|
21
|
+
|
|
22
|
+
## Anti-Patterns
|
|
23
|
+
|
|
24
|
+
| Avoid | Do Instead |
|
|
25
|
+
|-------|------------|
|
|
26
|
+
| Status report to manager | Facilitate for team; manager observes or skips |
|
|
27
|
+
| Problem-solving in standup | "Grab 2–3 people after" |
|
|
28
|
+
| Running long | Timebox; move discussions offline |
|
|
29
|
+
| Low energy / no one listening | Change format; make it interactive |
|
|
30
|
+
|
|
31
|
+
## Async Template
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
Yesterday: [1–2 bullets]
|
|
35
|
+
Today: [1–2 bullets]
|
|
36
|
+
Blockers: [none / describe]
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Tools:** Slack, Loom, Geekbot, Standuply, shared doc.
|
|
40
|
+
|
|
41
|
+
## Remote Tips
|
|
42
|
+
|
|
43
|
+
1. Cameras on
|
|
44
|
+
2. Screen share the board
|
|
45
|
+
3. Rotate facilitators
|
|
46
|
+
4. Use chat for follow-ups
|
|
47
|
+
5. Stable video/audio
|
|
48
|
+
|
|
49
|
+
## When to Skip
|
|
50
|
+
|
|
51
|
+
- Work is highly independent
|
|
52
|
+
- Team is very small (2–3) and in constant contact
|
|
53
|
+
- No one finds value after trying formats
|
|
54
|
+
|
|
55
|
+
## Sync vs Async
|
|
56
|
+
|
|
57
|
+
| Sync | Async |
|
|
58
|
+
|------|-------|
|
|
59
|
+
| Real-time coordination | Flexibility, no meeting |
|
|
60
|
+
| Good for: high coordination | Good for: independent work |
|
|
61
|
+
| Requires same-time availability | Post by deadline |
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Running Effective Standups — Quiz
|
|
2
|
+
|
|
3
|
+
## Question 1
|
|
4
|
+
|
|
5
|
+
What is the primary purpose of a daily standup?
|
|
6
|
+
|
|
7
|
+
A) Report status to the manager
|
|
8
|
+
B) Coordinate the team and surface blockers
|
|
9
|
+
C) Update the backlog
|
|
10
|
+
D) Assign tasks for the day
|
|
11
|
+
|
|
12
|
+
<!-- ANSWER: B -->
|
|
13
|
+
<!-- EXPLANATION: Standups are for coordination—helping the team align, surface blockers, and decide who needs to talk to whom. Status reporting to a manager is an anti-pattern that undermines the standup's value. -->
|
|
14
|
+
|
|
15
|
+
## Question 2
|
|
16
|
+
|
|
17
|
+
Why do the "three questions" often fail?
|
|
18
|
+
|
|
19
|
+
A) They're too hard to answer
|
|
20
|
+
B) They encourage monologues and status reporting
|
|
21
|
+
C) They take too long
|
|
22
|
+
D) They don't align with Scrum
|
|
23
|
+
|
|
24
|
+
<!-- ANSWER: B -->
|
|
25
|
+
<!-- EXPLANATION: "What did I do, what will I do, any blockers?" often leads to long recitations of work. People stop listening; the focus shifts from coordination to reporting. Alternative formats (walk the board, blockers first) keep the focus on coordination. -->
|
|
26
|
+
|
|
27
|
+
## Question 3
|
|
28
|
+
|
|
29
|
+
What is the recommended maximum time for a standup?
|
|
30
|
+
|
|
31
|
+
A) 5 minutes
|
|
32
|
+
B) 15 minutes
|
|
33
|
+
C) 30 minutes
|
|
34
|
+
D) 1 hour
|
|
35
|
+
|
|
36
|
+
<!-- ANSWER: B -->
|
|
37
|
+
<!-- EXPLANATION: 15 minutes is the upper bound; many effective teams do 10 or less. If standups run longer, take detailed discussions offline and enforce a strict timebox. -->
|
|
38
|
+
|
|
39
|
+
## Question 4
|
|
40
|
+
|
|
41
|
+
When do async standups work best?
|
|
42
|
+
|
|
43
|
+
A) When the team is colocated
|
|
44
|
+
B) When work is highly independent and schedules are flexible
|
|
45
|
+
C) When there are many blockers
|
|
46
|
+
D) When the manager wants daily updates
|
|
47
|
+
|
|
48
|
+
<!-- ANSWER: B -->
|
|
49
|
+
<!-- EXPLANATION: Async works best for distributed teams, flexible schedules, or when work is mostly independent. It saves meeting time but loses real-time discussion—less ideal when lots of coordination is needed. -->
|
|
50
|
+
|
|
51
|
+
## Question 5
|
|
52
|
+
|
|
53
|
+
Which is an anti-pattern in standups?
|
|
54
|
+
|
|
55
|
+
A) Walking the board
|
|
56
|
+
B) Starting with blockers
|
|
57
|
+
C) Problem-solving in the standup
|
|
58
|
+
D) Timeboxing to 15 minutes
|
|
59
|
+
|
|
60
|
+
<!-- ANSWER: C -->
|
|
61
|
+
<!-- EXPLANATION: Problem-solving in standup turns a short coordination meeting into a long discussion. The fix: "Let's grab 2–3 people and discuss after standup." Keep the standup short; take deep dives offline. -->
|
|
62
|
+
|
|
63
|
+
## Question 6
|
|
64
|
+
|
|
65
|
+
When might you skip standup altogether?
|
|
66
|
+
|
|
67
|
+
A) Never—standup is mandatory in Scrum
|
|
68
|
+
B) When the team is small and in constant contact, or work is low-coordination
|
|
69
|
+
C) When the manager is on vacation
|
|
70
|
+
D) Only on Fridays
|
|
71
|
+
|
|
72
|
+
<!-- ANSWER: B -->
|
|
73
|
+
<!-- EXPLANATION: Standup is a tool, not a religion. Skip or reduce frequency when work is highly independent, the team is very small, or no one finds value after trying different formats. -->
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Running Effective Standups — Resources
|
|
2
|
+
|
|
3
|
+
## Official Guides
|
|
4
|
+
|
|
5
|
+
- [Scrum Guide](https://scrumguides.org) — The Daily Scrum section defines the event and its purpose.
|
|
6
|
+
- [Scrum Guide — Daily Scrum](https://scrumguides.org/scrum-guide.html#daily-scrum) — Direct link to daily scrum.
|
|
7
|
+
|
|
8
|
+
## Books
|
|
9
|
+
|
|
10
|
+
- **Agile Retrospectives** by Esther Derby and Diana Larsen — Covers meeting design, including standups; practical facilitation techniques.
|
|
11
|
+
- **Scrum: The Art of Doing Twice the Work in Half the Time** by Jeff Sutherland — Origins of Scrum and daily standups.
|
|
12
|
+
|
|
13
|
+
## Articles
|
|
14
|
+
|
|
15
|
+
- [How to Run Effective Daily Standups](https://www.atlassian.com/agile/scrum/ceremonies/daily-standup) — Atlassian. Format options, tips, anti-patterns.
|
|
16
|
+
- [Why Standups Fail](https://www.mountaingoatsoftware.com/blog/why-daily-stand-ups-fail) — Mountain Goat Software. Common pitfalls.
|
|
17
|
+
- [Async Standups: When and How](https://www.fellow.app/blog/async-standup) — Fellow. Async formats and tools.
|
|
18
|
+
- [Walk the Board — An Alternative to Round-Robin Standups](https://www.scrum.org/resources/blog/walk-board) — Scrum.org. Board-based format.
|
|
19
|
+
|
|
20
|
+
## Tools
|
|
21
|
+
|
|
22
|
+
- [Geekbot](https://geekbot.com/) — Async standup bot for Slack, MS Teams.
|
|
23
|
+
- [Standuply](https://standuply.com/) — Async standups, surveys, retros.
|
|
24
|
+
- [Loom](https://www.loom.com/) — Quick video updates for async standups.
|
|
25
|
+
- [Miro](https://miro.com/) — Virtual boards for walking the board remotely.
|
|
26
|
+
- [Slack](https://slack.com/) — Threaded async standups with reminders.
|
|
27
|
+
|
|
28
|
+
## Videos
|
|
29
|
+
|
|
30
|
+
- [How to Run a Daily Standup](https://www.youtube.com/results?search_query=daily+standup+scrum) — Search for "daily standup scrum" for short explainers.
|
|
31
|
+
- [Engineering Culture](https://www.infoq.com/podcasts/engineering-culture/) — InfoQ podcast; episodes on meetings and team rituals.
|
|
32
|
+
|
|
33
|
+
## Podcasts
|
|
34
|
+
|
|
35
|
+
- [Agile for Humans](https://ryanripley.com/agile-for-humans/) — Episodes on standups and ceremonies.
|
|
36
|
+
- [Scrum Master Toolbox](https://www.scrummastertoolbox.com/) — Daily tips from practicing Scrum Masters.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Running Effective Standups Walkthrough — Learn by Doing
|
|
2
|
+
|
|
3
|
+
## Before We Begin
|
|
4
|
+
|
|
5
|
+
**Diagnostic:** What is a standup *for*? If the goal were only "share status," would a Slack thread be enough? What does a standup do that async updates can't?
|
|
6
|
+
|
|
7
|
+
**Checkpoint:** You can name at least one purpose beyond status—e.g., unblocking, alignment, coordination—and why it might need to be *live*.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Step 1: Diagnose Your Current Standup
|
|
12
|
+
|
|
13
|
+
**Task:** Reflect on your team's current standup (or one you've observed). List 2–3 things that work and 2–3 things that don't. Is it coordination-focused or status-report-focused?
|
|
14
|
+
|
|
15
|
+
**Question:** What would "success" look like for your standup? How would you know if it's working?
|
|
16
|
+
|
|
17
|
+
**Checkpoint:** You've identified at least one concrete problem (e.g., "runs 25 minutes," "no one listens," "manager uses it for status").
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Step 2: Choose an Alternative Format
|
|
22
|
+
|
|
23
|
+
<!-- hint:buttons type="single" prompt="Which format puts the work—not the people—at the center?" options="Walk the board,Blockers first,Topic-based,Round-robin" -->
|
|
24
|
+
<!-- hint:list style="cards" -->
|
|
25
|
+
|
|
26
|
+
**Task:** Pick one alternative format (walk the board, blockers first, or topic-based). Write a 1-paragraph "standup script" explaining how your team would run it: who speaks when, what questions are asked, how long each part takes.
|
|
27
|
+
|
|
28
|
+
**Question:** What would need to change for this format to work? (Board? Facilitator? Team habits?)
|
|
29
|
+
|
|
30
|
+
**Checkpoint:** Script is clear enough that someone could run the standup from it.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Step 3: Design a 10-Minute Timebox
|
|
35
|
+
|
|
36
|
+
**Task:** Design a 10-minute standup agenda. Allocate time per section (e.g., blockers 3 min, walk the board 5 min, wrap 2 min). What's your rule for "we need to discuss this in detail"?
|
|
37
|
+
|
|
38
|
+
**Question:** What typically causes standups to run over? How does your design prevent that?
|
|
39
|
+
|
|
40
|
+
**Checkpoint:** Agenda fits in 10 minutes; you have a clear "take it offline" rule.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Step 4: Create an Async Standup Template
|
|
45
|
+
|
|
46
|
+
<!-- hint:list style="cards" -->
|
|
47
|
+
|
|
48
|
+
**Task:** Create an async standup template (Slack, doc, or tool of choice). Include: what each person posts, deadline, how blockers are escalated. Write 2–3 sentences on when async would work for your team and when it wouldn't.
|
|
49
|
+
|
|
50
|
+
**Question:** What would you lose by going async? What would you gain?
|
|
51
|
+
|
|
52
|
+
**Checkpoint:** Template is complete; trade-offs are articulated.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Step 5: List Anti-Patterns and Fixes
|
|
57
|
+
|
|
58
|
+
<!-- hint:card type="warning" title="Standup Anti-Patterns" -->
|
|
59
|
+
|
|
60
|
+
**Task:** List 3 standup anti-patterns you've seen (in your team or elsewhere). For each, write one concrete fix you could try.
|
|
61
|
+
|
|
62
|
+
**Question:** Why do these anti-patterns persist? What would make the fix stick?
|
|
63
|
+
|
|
64
|
+
**Checkpoint:** Anti-patterns are specific; fixes are actionable.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Step 6: Redesign Your Standup
|
|
69
|
+
|
|
70
|
+
<!-- hint:celebrate -->
|
|
71
|
+
|
|
72
|
+
**Task:** Produce a one-page "Standup Redesign" for your team. Include: format, timebox, roles (who facilitates, who attends), and one experiment to try for the next 2 weeks (e.g., "walk the board instead of round-robin").
|
|
73
|
+
|
|
74
|
+
**Question:** How will you know if the redesign worked? What would cause you to revert?
|
|
75
|
+
|
|
76
|
+
**Checkpoint:** Redesign is practical and includes a testable experiment.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# SOLID Principles — Writing Code That Survives Change
|
|
2
|
+
|
|
3
|
+
SOLID is five principles for object-oriented design that make software more maintainable and extensible.
|
|
4
|
+
|
|
5
|
+
```mermaid
|
|
6
|
+
mindmap
|
|
7
|
+
root((SOLID))
|
|
8
|
+
S
|
|
9
|
+
Single Responsibility
|
|
10
|
+
O
|
|
11
|
+
Open/Closed
|
|
12
|
+
L
|
|
13
|
+
Liskov Substitution
|
|
14
|
+
I
|
|
15
|
+
Interface Segregation
|
|
16
|
+
D
|
|
17
|
+
Dependency Inversion
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## S — Single Responsibility Principle (SRP)
|
|
21
|
+
|
|
22
|
+
**A class should have only one reason to change.**
|
|
23
|
+
|
|
24
|
+
Each module should own one axis of change. Mixing concerns (e.g., validation + persistence + formatting) means any change to one affects the others.
|
|
25
|
+
|
|
26
|
+
**Before:**
|
|
27
|
+
```typescript
|
|
28
|
+
class UserService {
|
|
29
|
+
validate(user: User) { /* ... */ }
|
|
30
|
+
save(user: User) { /* ... */ }
|
|
31
|
+
sendWelcomeEmail(user: User) { /* ... */ }
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**After:**
|
|
36
|
+
```typescript
|
|
37
|
+
class UserValidator { validate(user: User) { /* ... */ } }
|
|
38
|
+
class UserRepository { save(user: User) { /* ... */ } }
|
|
39
|
+
class EmailNotifier { sendWelcome(user: User) { /* ... */ } }
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## O — Open/Closed Principle (OCP)
|
|
43
|
+
|
|
44
|
+
**Software should be open for extension, closed for modification.**
|
|
45
|
+
|
|
46
|
+
Add behavior via new code (inheritance, composition, plugins), not by editing existing code.
|
|
47
|
+
|
|
48
|
+
**Before:** Adding a new shape requires editing a central function.
|
|
49
|
+
```typescript
|
|
50
|
+
function area(shape: any) {
|
|
51
|
+
if (shape.type === 'circle') return Math.PI * shape.r ** 2;
|
|
52
|
+
if (shape.type === 'rect') return shape.w * shape.h;
|
|
53
|
+
// Must edit here for each new shape
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**After:** Each shape extends behavior without changing others.
|
|
58
|
+
```typescript
|
|
59
|
+
interface Shape { area(): number; }
|
|
60
|
+
class Circle implements Shape { area() { return Math.PI * this.r ** 2; } }
|
|
61
|
+
class Rect implements Shape { area() { return this.w * this.h; } }
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## L — Liskov Substitution Principle (LSP)
|
|
65
|
+
|
|
66
|
+
**Subtypes must be substitutable for their base types.**
|
|
67
|
+
|
|
68
|
+
If `B` extends `A`, any code that expects `A` should work with `B` without surprises. Don't weaken preconditions or strengthen postconditions.
|
|
69
|
+
|
|
70
|
+
**Violation:**
|
|
71
|
+
```typescript
|
|
72
|
+
class Rectangle { setWidth(w: number) { this.w = w; } setHeight(h: number) { this.h = h; } }
|
|
73
|
+
class Square extends Rectangle {
|
|
74
|
+
setWidth(w: number) { this.w = this.h = w; } // Surprise: changes both!
|
|
75
|
+
setHeight(h: number) { this.w = this.h = h; }
|
|
76
|
+
}
|
|
77
|
+
// Code expecting Rectangle gets unexpected behavior
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Better:** Don't make Square extend Rectangle if it can't honor the contract.
|
|
81
|
+
|
|
82
|
+
## I — Interface Segregation Principle (ISP)
|
|
83
|
+
|
|
84
|
+
**Clients should not depend on interfaces they don't use.**
|
|
85
|
+
|
|
86
|
+
Prefer small, focused interfaces over large "god" interfaces. Fat interfaces force implementers to add no-op methods.
|
|
87
|
+
|
|
88
|
+
**Before:**
|
|
89
|
+
```typescript
|
|
90
|
+
interface Worker {
|
|
91
|
+
work(): void;
|
|
92
|
+
eat(): void;
|
|
93
|
+
sleep(): void;
|
|
94
|
+
}
|
|
95
|
+
class Robot implements Worker {
|
|
96
|
+
work() { /* ... */ }
|
|
97
|
+
eat() { /* no-op */ } // Robot doesn't eat
|
|
98
|
+
sleep() { /* no-op */ } // Robot doesn't sleep
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**After:**
|
|
103
|
+
```typescript
|
|
104
|
+
interface Workable { work(): void; }
|
|
105
|
+
interface Eatable { eat(): void; }
|
|
106
|
+
class Robot implements Workable { work() { /* ... */ } }
|
|
107
|
+
class Human implements Workable, Eatable { work() { /* ... */ } eat() { /* ... */ } }
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## D — Dependency Inversion Principle (DIP)
|
|
111
|
+
|
|
112
|
+
**Depend on abstractions, not concretions.**
|
|
113
|
+
|
|
114
|
+
High-level modules should not depend on low-level modules. Both should depend on abstractions (interfaces).
|
|
115
|
+
|
|
116
|
+
```mermaid
|
|
117
|
+
flowchart TB
|
|
118
|
+
subgraph Bad
|
|
119
|
+
A1[OrderService] -->|depends on| B1[MySqlDatabase]
|
|
120
|
+
end
|
|
121
|
+
subgraph Good
|
|
122
|
+
A2[OrderService] -->|depends on| I[Database Interface]
|
|
123
|
+
B2[MySqlDatabase] -->|implements| I
|
|
124
|
+
B3[PostgresDatabase] -->|implements| I
|
|
125
|
+
end
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Before:** OrderService directly uses MySqlDatabase.
|
|
129
|
+
```typescript
|
|
130
|
+
class OrderService {
|
|
131
|
+
private db = new MySqlDatabase();
|
|
132
|
+
save(order: Order) { this.db.insert('orders', order); }
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**After:** Both depend on an abstraction.
|
|
137
|
+
```typescript
|
|
138
|
+
interface Database { insert(table: string, data: object): void; }
|
|
139
|
+
class OrderService {
|
|
140
|
+
constructor(private db: Database) {}
|
|
141
|
+
save(order: Order) { this.db.insert('orders', order); }
|
|
142
|
+
}
|
|
143
|
+
// Inject MySqlDatabase or PostgresDatabase at runtime
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Summary
|
|
147
|
+
|
|
148
|
+
| Principle | One-Liner |
|
|
149
|
+
|-----------|-----------|
|
|
150
|
+
| SRP | One reason to change |
|
|
151
|
+
| OCP | Extend, don't modify |
|
|
152
|
+
| LSP | Subtypes replace base types |
|
|
153
|
+
| ISP | Small interfaces |
|
|
154
|
+
| DIP | Depend on abstractions |
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# SOLID Exercises
|
|
2
|
+
|
|
3
|
+
## Exercise 1: SRP — Split the User Module
|
|
4
|
+
|
|
5
|
+
**Task:** This class does validation, persistence, and notification. Split it into 3 classes (Validator, Repository, Notifier) and have a service orchestrate them.
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
class UserService {
|
|
9
|
+
createUser(data: any) {
|
|
10
|
+
if (!data.email?.includes('@')) throw new Error('Invalid email');
|
|
11
|
+
const user = { id: generateId(), ...data };
|
|
12
|
+
db.save('users', user);
|
|
13
|
+
emailService.send(user.email, 'Welcome!');
|
|
14
|
+
return user;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Validation:**
|
|
20
|
+
- [ ] At least 3 focused classes
|
|
21
|
+
- [ ] Service orchestrates, doesn't implement validation/DB/email
|
|
22
|
+
- [ ] Each class has one clear responsibility
|
|
23
|
+
|
|
24
|
+
**Hints:**
|
|
25
|
+
1. UserValidator.validate(data) throws or returns
|
|
26
|
+
2. UserRepository.save(user)
|
|
27
|
+
3. EmailNotifier.sendWelcome(email)
|
|
28
|
+
4. UserService.createUser calls all three
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Exercise 2: OCP — Pluggable Exporters
|
|
33
|
+
|
|
34
|
+
**Task:** You have a Report class that exports to CSV. Add JSON and XML export without modifying the Report class. Use a strategy/exporter interface.
|
|
35
|
+
|
|
36
|
+
**Validation:**
|
|
37
|
+
- [ ] New exporters added without changing Report
|
|
38
|
+
- [ ] Report depends on an exporter interface
|
|
39
|
+
- [ ] At least 2 exporter implementations
|
|
40
|
+
|
|
41
|
+
**Hints:**
|
|
42
|
+
1. interface Exporter { export(data: Data): string }
|
|
43
|
+
2. class CsvExporter implements Exporter
|
|
44
|
+
3. class JsonExporter implements Exporter
|
|
45
|
+
4. Report receives Exporter in constructor
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Exercise 3: LSP — Fix the Violation
|
|
50
|
+
|
|
51
|
+
**Task:** This violates LSP. Redesign so Bird subtypes are substitutable, or explain why a different hierarchy is better.
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
class Bird { fly() { console.log('Flying'); } }
|
|
55
|
+
class Sparrow extends Bird { }
|
|
56
|
+
class Penguin extends Bird { fly() { throw new Error("Can't fly"); } }
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Validation:**
|
|
60
|
+
- [ ] No subtype surprises callers of the base
|
|
61
|
+
- [ ] Either fix hierarchy or use composition
|
|
62
|
+
|
|
63
|
+
**Hints:**
|
|
64
|
+
1. Penguin shouldn't extend Bird if Bird guarantees fly()
|
|
65
|
+
2. Consider: FlyingBird vs Bird, or Bird has optional fly capability
|
|
66
|
+
3. Composition: Bird has FlyBehavior (strategy)
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Exercise 4: ISP — Segregate the Interface
|
|
71
|
+
|
|
72
|
+
**Task:** This interface forces printers to implement scan/fax. Split it so a simple printer only implements print.
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
interface Machine {
|
|
76
|
+
print(doc: string): void;
|
|
77
|
+
scan(doc: string): void;
|
|
78
|
+
fax(doc: string): void;
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Validation:**
|
|
83
|
+
- [ ] At least Printer, Scanner, Faxer (or combined) interfaces
|
|
84
|
+
- [ ] SimplePrinter implements only Printer
|
|
85
|
+
- [ ] No no-op methods required
|
|
86
|
+
|
|
87
|
+
**Hints:**
|
|
88
|
+
1. interface Printer { print(doc: string): void }
|
|
89
|
+
2. interface Scanner { scan(doc: string): void }
|
|
90
|
+
3. MultiFunctionDevice implements both
|
|
91
|
+
4. SimplePrinter implements Printer only
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Exercise 5: DIP — Inject the Logger
|
|
96
|
+
|
|
97
|
+
**Task:** Refactor OrderProcessor to receive its logger via constructor. Define a Logger interface. Create ConsoleLogger and MockLogger implementations.
|
|
98
|
+
|
|
99
|
+
**Validation:**
|
|
100
|
+
- [ ] OrderProcessor depends on Logger interface
|
|
101
|
+
- [ ] Logger injected in constructor
|
|
102
|
+
- [ ] Easy to test with MockLogger
|
|
103
|
+
|
|
104
|
+
**Hints:**
|
|
105
|
+
1. interface Logger { log(msg: string): void }
|
|
106
|
+
2. constructor(private logger: Logger)
|
|
107
|
+
3. MockLogger stores messages for assertions
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
slug: solid-principles
|
|
2
|
+
title: "SOLID Principles — Writing Code That Survives Change"
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
description: "Master the five SOLID principles for maintainable, extensible object-oriented design."
|
|
5
|
+
category: fundamentals
|
|
6
|
+
tags: [solid, object-oriented, design-principles, clean-code, architecture]
|
|
7
|
+
difficulty: intermediate
|
|
8
|
+
|
|
9
|
+
xp:
|
|
10
|
+
read: 15
|
|
11
|
+
walkthrough: 40
|
|
12
|
+
exercise: 25
|
|
13
|
+
quiz: 20
|
|
14
|
+
quiz-perfect-bonus: 10
|
|
15
|
+
|
|
16
|
+
time:
|
|
17
|
+
quick: 5
|
|
18
|
+
read: 20
|
|
19
|
+
guided: 50
|
|
20
|
+
|
|
21
|
+
prerequisites: [clean-code]
|
|
22
|
+
related: [design-patterns, api-design]
|
|
23
|
+
|
|
24
|
+
triggers:
|
|
25
|
+
- "What are the SOLID principles?"
|
|
26
|
+
- "What is the Single Responsibility Principle?"
|
|
27
|
+
- "How do I write maintainable code?"
|
|
28
|
+
- "What is dependency inversion?"
|
|
29
|
+
|
|
30
|
+
visuals:
|
|
31
|
+
diagrams: [diagram-mermaid, diagram-flow]
|
|
32
|
+
quiz-types: [quiz-matching, quiz-timed-choice]
|
|
33
|
+
playground: javascript
|
|
34
|
+
slides: true
|
|
35
|
+
|
|
36
|
+
sources:
|
|
37
|
+
- url: "https://martinfowler.com"
|
|
38
|
+
label: "Martin Fowler's Blog"
|
|
39
|
+
type: docs
|
|
40
|
+
- url: "https://www.oreilly.com/library/view/clean-code-a/9780136083238/"
|
|
41
|
+
label: "Clean Code by Robert Martin"
|
|
42
|
+
type: docs
|