@shaykec/bridge 0.4.25 → 0.4.27
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 +2 -2
- package/canvas-dist/assets/_basePickBy-BovdgFIW.js +0 -1
- package/canvas-dist/assets/_basePickBy-BtkHe2u_.js +0 -1
- package/canvas-dist/assets/_basePickBy-C0936578.js +0 -1
- package/canvas-dist/assets/_basePickBy-CE2Qvuh7.js +0 -1
- package/canvas-dist/assets/_basePickBy-DV6sX4CG.js +0 -1
- package/canvas-dist/assets/_basePickBy-DZX6ZNMT.js +0 -1
- package/canvas-dist/assets/_baseUniq-B7dN28TM.js +0 -1
- package/canvas-dist/assets/_baseUniq-Cl23fCdR.js +0 -1
- package/canvas-dist/assets/_baseUniq-CojWFw7B.js +0 -1
- package/canvas-dist/assets/_baseUniq-DA640BJl.js +0 -1
- package/canvas-dist/assets/_baseUniq-Ds-62CCj.js +0 -1
- package/canvas-dist/assets/_baseUniq-KG7SRw9H.js +0 -1
- package/canvas-dist/assets/arc-7E9FFKlC.js +0 -1
- package/canvas-dist/assets/arc-BSMfRZtt.js +0 -1
- package/canvas-dist/assets/arc-C6nT-koR.js +0 -1
- package/canvas-dist/assets/arc-D_fOnjmo.js +0 -1
- package/canvas-dist/assets/arc-Khfvgkr3.js +0 -1
- package/canvas-dist/assets/arc-ieS-i42x.js +0 -1
- package/canvas-dist/assets/architectureDiagram-VXUJARFQ-DF4t6GQD.js +0 -36
- package/canvas-dist/assets/architectureDiagram-VXUJARFQ-DXgSlsio.js +0 -36
- package/canvas-dist/assets/architectureDiagram-VXUJARFQ-DiomxPB4.js +0 -36
- package/canvas-dist/assets/architectureDiagram-VXUJARFQ-DnFaxvXD.js +0 -36
- package/canvas-dist/assets/architectureDiagram-VXUJARFQ-Dt38C0LJ.js +0 -36
- package/canvas-dist/assets/architectureDiagram-VXUJARFQ-egbtMwua.js +0 -36
- package/canvas-dist/assets/blockDiagram-VD42YOAC-CUNKQd-b.js +0 -122
- package/canvas-dist/assets/blockDiagram-VD42YOAC-D-NiLXxd.js +0 -122
- package/canvas-dist/assets/blockDiagram-VD42YOAC-Dx6Dh9gg.js +0 -122
- package/canvas-dist/assets/blockDiagram-VD42YOAC-_r-PmlQy.js +0 -122
- package/canvas-dist/assets/blockDiagram-VD42YOAC-bvYKZLMc.js +0 -122
- package/canvas-dist/assets/blockDiagram-VD42YOAC-l85QT9Ig.js +0 -122
- package/canvas-dist/assets/c4Diagram-YG6GDRKO-BWKCTyQi.js +0 -10
- package/canvas-dist/assets/c4Diagram-YG6GDRKO-CbXs2xzC.js +0 -10
- package/canvas-dist/assets/c4Diagram-YG6GDRKO-CjiS-GNK.js +0 -10
- package/canvas-dist/assets/c4Diagram-YG6GDRKO-D7SnLlHp.js +0 -10
- package/canvas-dist/assets/c4Diagram-YG6GDRKO-RTTCSVf2.js +0 -10
- package/canvas-dist/assets/c4Diagram-YG6GDRKO-yvqJ_AqX.js +0 -10
- package/canvas-dist/assets/channel-CSXq7GP6.js +0 -1
- package/canvas-dist/assets/channel-CvujjGiJ.js +0 -1
- package/canvas-dist/assets/channel-D959Iony.js +0 -1
- package/canvas-dist/assets/channel-DOSwCnrB.js +0 -1
- package/canvas-dist/assets/channel-sw61LzxF.js +0 -1
- package/canvas-dist/assets/channel-vZVnNhOK.js +0 -1
- package/canvas-dist/assets/chunk-4BX2VUAB-BBjuAwXr.js +0 -1
- package/canvas-dist/assets/chunk-4BX2VUAB-BXRNyucU.js +0 -1
- package/canvas-dist/assets/chunk-4BX2VUAB-Bgq5Z77T.js +0 -1
- package/canvas-dist/assets/chunk-4BX2VUAB-BuoMCMCr.js +0 -1
- package/canvas-dist/assets/chunk-4BX2VUAB-COD5n7vg.js +0 -1
- package/canvas-dist/assets/chunk-4BX2VUAB-K8DepKJO.js +0 -1
- package/canvas-dist/assets/chunk-55IACEB6-Bic_bMrQ.js +0 -1
- package/canvas-dist/assets/chunk-55IACEB6-DEy2QUDq.js +0 -1
- package/canvas-dist/assets/chunk-55IACEB6-Dcgbmfzg.js +0 -1
- package/canvas-dist/assets/chunk-55IACEB6-DfmuNm_E.js +0 -1
- package/canvas-dist/assets/chunk-55IACEB6-DlQRcczm.js +0 -1
- package/canvas-dist/assets/chunk-55IACEB6-p2qMY-fm.js +0 -1
- package/canvas-dist/assets/chunk-B4BG7PRW-BpbyxBP2.js +0 -165
- package/canvas-dist/assets/chunk-B4BG7PRW-CCPqvPrP.js +0 -165
- package/canvas-dist/assets/chunk-B4BG7PRW-CEeDPAki.js +0 -165
- package/canvas-dist/assets/chunk-B4BG7PRW-D2UFN_2M.js +0 -165
- package/canvas-dist/assets/chunk-B4BG7PRW-DFI5h6HC.js +0 -165
- package/canvas-dist/assets/chunk-B4BG7PRW-DKOiFGMU.js +0 -165
- package/canvas-dist/assets/chunk-DI55MBZ5-BV6nHjNQ.js +0 -220
- package/canvas-dist/assets/chunk-DI55MBZ5-CEZJmC0E.js +0 -220
- package/canvas-dist/assets/chunk-DI55MBZ5-DOZT99Ek.js +0 -220
- package/canvas-dist/assets/chunk-DI55MBZ5-DmC2LoG2.js +0 -220
- package/canvas-dist/assets/chunk-DI55MBZ5-DpkcJdZP.js +0 -220
- package/canvas-dist/assets/chunk-DI55MBZ5-fVTGx0zh.js +0 -220
- package/canvas-dist/assets/chunk-FMBD7UC4-BOCyQpI7.js +0 -15
- package/canvas-dist/assets/chunk-FMBD7UC4-C76FrRL8.js +0 -15
- package/canvas-dist/assets/chunk-FMBD7UC4-CAq-btWc.js +0 -15
- package/canvas-dist/assets/chunk-FMBD7UC4-CidVsej6.js +0 -15
- package/canvas-dist/assets/chunk-FMBD7UC4-DPpfskdX.js +0 -15
- package/canvas-dist/assets/chunk-FMBD7UC4-DnLtclge.js +0 -15
- package/canvas-dist/assets/chunk-QN33PNHL-BclpCUi8.js +0 -1
- package/canvas-dist/assets/chunk-QN33PNHL-DDUw8IU1.js +0 -1
- package/canvas-dist/assets/chunk-QN33PNHL-DdJFAUXw.js +0 -1
- package/canvas-dist/assets/chunk-QN33PNHL-DjV4jUn9.js +0 -1
- package/canvas-dist/assets/chunk-QN33PNHL-N-HTycqU.js +0 -1
- package/canvas-dist/assets/chunk-QN33PNHL-sd8p21DW.js +0 -1
- package/canvas-dist/assets/chunk-QZHKN3VN-B6mT-JkP.js +0 -1
- package/canvas-dist/assets/chunk-QZHKN3VN-BCo8pc7x.js +0 -1
- package/canvas-dist/assets/chunk-QZHKN3VN-C8IIu6es.js +0 -1
- package/canvas-dist/assets/chunk-QZHKN3VN-D9FF492U.js +0 -1
- package/canvas-dist/assets/chunk-QZHKN3VN-DWMbUjXT.js +0 -1
- package/canvas-dist/assets/chunk-QZHKN3VN-l5FBJ77g.js +0 -1
- package/canvas-dist/assets/chunk-TZMSLE5B-BASt-UWt.js +0 -1
- package/canvas-dist/assets/chunk-TZMSLE5B-BCfaZWLT.js +0 -1
- package/canvas-dist/assets/chunk-TZMSLE5B-BKIk_hBR.js +0 -1
- package/canvas-dist/assets/chunk-TZMSLE5B-C4pt-Ir8.js +0 -1
- package/canvas-dist/assets/chunk-TZMSLE5B-DwGlELvo.js +0 -1
- package/canvas-dist/assets/chunk-TZMSLE5B-jJKG-WvJ.js +0 -1
- package/canvas-dist/assets/classDiagram-2ON5EDUG-B7YQfPU4.js +0 -1
- package/canvas-dist/assets/classDiagram-2ON5EDUG-BZ61MaHY.js +0 -1
- package/canvas-dist/assets/classDiagram-2ON5EDUG-CGseYor2.js +0 -1
- package/canvas-dist/assets/classDiagram-2ON5EDUG-CKzOc99J.js +0 -1
- package/canvas-dist/assets/classDiagram-2ON5EDUG-Ce_LPjwW.js +0 -1
- package/canvas-dist/assets/classDiagram-2ON5EDUG-DorPdibv.js +0 -1
- package/canvas-dist/assets/classDiagram-v2-WZHVMYZB-B7YQfPU4.js +0 -1
- package/canvas-dist/assets/classDiagram-v2-WZHVMYZB-BZ61MaHY.js +0 -1
- package/canvas-dist/assets/classDiagram-v2-WZHVMYZB-CGseYor2.js +0 -1
- package/canvas-dist/assets/classDiagram-v2-WZHVMYZB-CKzOc99J.js +0 -1
- package/canvas-dist/assets/classDiagram-v2-WZHVMYZB-Ce_LPjwW.js +0 -1
- package/canvas-dist/assets/classDiagram-v2-WZHVMYZB-DorPdibv.js +0 -1
- package/canvas-dist/assets/clone-74KSto7H.js +0 -1
- package/canvas-dist/assets/clone-CJQgAYVe.js +0 -1
- package/canvas-dist/assets/clone-DLeTuhHE.js +0 -1
- package/canvas-dist/assets/clone-D_IHK_lQ.js +0 -1
- package/canvas-dist/assets/clone-DxMUv1L9.js +0 -1
- package/canvas-dist/assets/clone-UNKf_nED.js +0 -1
- package/canvas-dist/assets/cose-bilkent-S5V4N54A-BTyQiCkr.js +0 -1
- package/canvas-dist/assets/cose-bilkent-S5V4N54A-BtPAe24N.js +0 -1
- package/canvas-dist/assets/cose-bilkent-S5V4N54A-DIjE7V3m.js +0 -1
- package/canvas-dist/assets/cose-bilkent-S5V4N54A-DKL_BGvE.js +0 -1
- package/canvas-dist/assets/cose-bilkent-S5V4N54A-LZ4OsCLU.js +0 -1
- package/canvas-dist/assets/cose-bilkent-S5V4N54A-XWeJtgga.js +0 -1
- package/canvas-dist/assets/dagre-6UL2VRFP-BJ2vcFwR.js +0 -4
- package/canvas-dist/assets/dagre-6UL2VRFP-C1FlE5s8.js +0 -4
- package/canvas-dist/assets/dagre-6UL2VRFP-C3BWFgl6.js +0 -4
- package/canvas-dist/assets/dagre-6UL2VRFP-CUnx73Rf.js +0 -4
- package/canvas-dist/assets/dagre-6UL2VRFP-Do10BY1y.js +0 -4
- package/canvas-dist/assets/dagre-6UL2VRFP-rOZEkrsg.js +0 -4
- package/canvas-dist/assets/diagram-PSM6KHXK-BGi_qzbq.js +0 -24
- package/canvas-dist/assets/diagram-PSM6KHXK-C3Nv7h_j.js +0 -24
- package/canvas-dist/assets/diagram-PSM6KHXK-CsMy-r0n.js +0 -24
- package/canvas-dist/assets/diagram-PSM6KHXK-Dj8g7kGt.js +0 -24
- package/canvas-dist/assets/diagram-PSM6KHXK-Dxb1w_7r.js +0 -24
- package/canvas-dist/assets/diagram-PSM6KHXK-kVMBkEyV.js +0 -24
- package/canvas-dist/assets/diagram-QEK2KX5R-4bsrr1WZ.js +0 -43
- package/canvas-dist/assets/diagram-QEK2KX5R-Bv7BmKfI.js +0 -43
- package/canvas-dist/assets/diagram-QEK2KX5R-C_FLN6hv.js +0 -43
- package/canvas-dist/assets/diagram-QEK2KX5R-Csuk5L3z.js +0 -43
- package/canvas-dist/assets/diagram-QEK2KX5R-D5Aszgz4.js +0 -43
- package/canvas-dist/assets/diagram-QEK2KX5R-DX58f87l.js +0 -43
- package/canvas-dist/assets/diagram-S2PKOQOG-1Q7hwiSd.js +0 -24
- package/canvas-dist/assets/diagram-S2PKOQOG-Bz9Vxi5V.js +0 -24
- package/canvas-dist/assets/diagram-S2PKOQOG-CdWgZIIc.js +0 -24
- package/canvas-dist/assets/diagram-S2PKOQOG-DBicbKFU.js +0 -24
- package/canvas-dist/assets/diagram-S2PKOQOG-DsXKwPtU.js +0 -24
- package/canvas-dist/assets/diagram-S2PKOQOG-L_SMHLXs.js +0 -24
- package/canvas-dist/assets/erDiagram-Q2GNP2WA-BYu7fh6H.js +0 -60
- package/canvas-dist/assets/erDiagram-Q2GNP2WA-CvnQ69BF.js +0 -60
- package/canvas-dist/assets/erDiagram-Q2GNP2WA-D3xm-Tdm.js +0 -60
- package/canvas-dist/assets/erDiagram-Q2GNP2WA-DIPpD8sj.js +0 -60
- package/canvas-dist/assets/erDiagram-Q2GNP2WA-DNgu6dMd.js +0 -60
- package/canvas-dist/assets/erDiagram-Q2GNP2WA-Decm8aB4.js +0 -60
- package/canvas-dist/assets/flowDiagram-NV44I4VS-2ymk2kw2.js +0 -162
- package/canvas-dist/assets/flowDiagram-NV44I4VS-BEPFOt6U.js +0 -162
- package/canvas-dist/assets/flowDiagram-NV44I4VS-BwqXYGfK.js +0 -162
- package/canvas-dist/assets/flowDiagram-NV44I4VS-CS1jax_z.js +0 -162
- package/canvas-dist/assets/flowDiagram-NV44I4VS-DQz5bf7r.js +0 -162
- package/canvas-dist/assets/flowDiagram-NV44I4VS-KW4T1sqF.js +0 -162
- package/canvas-dist/assets/ganttDiagram-JELNMOA3-B811prZt.js +0 -267
- package/canvas-dist/assets/ganttDiagram-JELNMOA3-C75pWm7X.js +0 -267
- package/canvas-dist/assets/ganttDiagram-JELNMOA3-CWsbo0fn.js +0 -267
- package/canvas-dist/assets/ganttDiagram-JELNMOA3-CbJozPBN.js +0 -267
- package/canvas-dist/assets/ganttDiagram-JELNMOA3-Co0cFt4c.js +0 -267
- package/canvas-dist/assets/ganttDiagram-JELNMOA3-I4PDqrRh.js +0 -267
- package/canvas-dist/assets/gitGraphDiagram-V2S2FVAM-B-z0cLPt.js +0 -65
- package/canvas-dist/assets/gitGraphDiagram-V2S2FVAM-Be40z-LF.js +0 -65
- package/canvas-dist/assets/gitGraphDiagram-V2S2FVAM-BejNaAVm.js +0 -65
- package/canvas-dist/assets/gitGraphDiagram-V2S2FVAM-BqWDYr0X.js +0 -65
- package/canvas-dist/assets/gitGraphDiagram-V2S2FVAM-DSvWGY-e.js +0 -65
- package/canvas-dist/assets/gitGraphDiagram-V2S2FVAM-HLYbyNJ5.js +0 -65
- package/canvas-dist/assets/graph-BE8KKsdf.js +0 -1
- package/canvas-dist/assets/graph-D6DzzszU.js +0 -1
- package/canvas-dist/assets/graph-DFR8Y_8s.js +0 -1
- package/canvas-dist/assets/graph-Da385cDY.js +0 -1
- package/canvas-dist/assets/graph-MU7gZz2B.js +0 -1
- package/canvas-dist/assets/graph-wjSBJwnf.js +0 -1
- package/canvas-dist/assets/index--ztw-8Rw.js +0 -647
- package/canvas-dist/assets/index-5TpIM6B1.js +0 -11
- package/canvas-dist/assets/index-BSswTuBk.js +0 -11
- package/canvas-dist/assets/index-BVvhMmjs.js +0 -11
- package/canvas-dist/assets/index-BY92Mj5g.js +0 -572
- package/canvas-dist/assets/index-CV7palC3.js +0 -572
- package/canvas-dist/assets/index-D9bmQGsB.js +0 -11
- package/canvas-dist/assets/index-DDIKkGv8.js +0 -592
- package/canvas-dist/assets/index-Dyo0NkPb.js +0 -574
- package/canvas-dist/assets/index-iQWajCow.js +0 -572
- package/canvas-dist/assets/index-m68YlAMU.js +0 -11
- package/canvas-dist/assets/index-mEoP57az.js +0 -11
- package/canvas-dist/assets/infoDiagram-HS3SLOUP--9BirqgJ.js +0 -2
- package/canvas-dist/assets/infoDiagram-HS3SLOUP-CSJVED2y.js +0 -2
- package/canvas-dist/assets/infoDiagram-HS3SLOUP-D68HIb2t.js +0 -2
- package/canvas-dist/assets/infoDiagram-HS3SLOUP-DK2VLGGz.js +0 -2
- package/canvas-dist/assets/infoDiagram-HS3SLOUP-PaFhn4yD.js +0 -2
- package/canvas-dist/assets/infoDiagram-HS3SLOUP-zLNG47sU.js +0 -2
- package/canvas-dist/assets/journeyDiagram-XKPGCS4Q-Bue2dR2X.js +0 -139
- package/canvas-dist/assets/journeyDiagram-XKPGCS4Q-CrgZfpdU.js +0 -139
- package/canvas-dist/assets/journeyDiagram-XKPGCS4Q-DUxWmkkC.js +0 -139
- package/canvas-dist/assets/journeyDiagram-XKPGCS4Q-OTFkv4pd.js +0 -139
- package/canvas-dist/assets/journeyDiagram-XKPGCS4Q-eK2_Zuu3.js +0 -139
- package/canvas-dist/assets/journeyDiagram-XKPGCS4Q-uds5Tz8D.js +0 -139
- package/canvas-dist/assets/kanban-definition-3W4ZIXB7-BETdiI7I.js +0 -89
- package/canvas-dist/assets/kanban-definition-3W4ZIXB7-BdVh7KdN.js +0 -89
- package/canvas-dist/assets/kanban-definition-3W4ZIXB7-Cxl8UM9S.js +0 -89
- package/canvas-dist/assets/kanban-definition-3W4ZIXB7-DVPlx3I2.js +0 -89
- package/canvas-dist/assets/kanban-definition-3W4ZIXB7-LtNWeoYB.js +0 -89
- package/canvas-dist/assets/kanban-definition-3W4ZIXB7-uvhEMvyE.js +0 -89
- package/canvas-dist/assets/layout-1OzszN14.js +0 -1
- package/canvas-dist/assets/layout-CJSupFcF.js +0 -1
- package/canvas-dist/assets/layout-DFRmxN_c.js +0 -1
- package/canvas-dist/assets/layout-DSu-zk7y.js +0 -1
- package/canvas-dist/assets/layout-TGcrvApd.js +0 -1
- package/canvas-dist/assets/layout-eStc8SYK.js +0 -1
- package/canvas-dist/assets/linear-9qlE6xa7.js +0 -1
- package/canvas-dist/assets/linear-CBfFWnLD.js +0 -1
- package/canvas-dist/assets/linear-Cv4ai8Hq.js +0 -1
- package/canvas-dist/assets/linear-DDzz65E6.js +0 -1
- package/canvas-dist/assets/linear-wbIqhwDf.js +0 -1
- package/canvas-dist/assets/linear-wyNKl76F.js +0 -1
- package/canvas-dist/assets/mindmap-definition-VGOIOE7T-3l4YzhEM.js +0 -68
- package/canvas-dist/assets/mindmap-definition-VGOIOE7T-B-KkpNlw.js +0 -68
- package/canvas-dist/assets/mindmap-definition-VGOIOE7T-DHMHWgmT.js +0 -68
- package/canvas-dist/assets/mindmap-definition-VGOIOE7T-Dqfyg4Z2.js +0 -68
- package/canvas-dist/assets/mindmap-definition-VGOIOE7T-NeRYOzsq.js +0 -68
- package/canvas-dist/assets/mindmap-definition-VGOIOE7T-xyu628P9.js +0 -68
- package/canvas-dist/assets/pieDiagram-ADFJNKIX-BWNzVAGj.js +0 -30
- package/canvas-dist/assets/pieDiagram-ADFJNKIX-Bm3PXYs-.js +0 -30
- package/canvas-dist/assets/pieDiagram-ADFJNKIX-BvvN7VvQ.js +0 -30
- package/canvas-dist/assets/pieDiagram-ADFJNKIX-BwU7AN7W.js +0 -30
- package/canvas-dist/assets/pieDiagram-ADFJNKIX-CHgwWCaM.js +0 -30
- package/canvas-dist/assets/pieDiagram-ADFJNKIX-DlZc8YOh.js +0 -30
- package/canvas-dist/assets/quadrantDiagram-AYHSOK5B-B-Zd8OFp.js +0 -7
- package/canvas-dist/assets/quadrantDiagram-AYHSOK5B-B1CnJyxI.js +0 -7
- package/canvas-dist/assets/quadrantDiagram-AYHSOK5B-C0Qo00b9.js +0 -7
- package/canvas-dist/assets/quadrantDiagram-AYHSOK5B-C9bx3nEJ.js +0 -7
- package/canvas-dist/assets/quadrantDiagram-AYHSOK5B-UHENkiRO.js +0 -7
- package/canvas-dist/assets/quadrantDiagram-AYHSOK5B-jKfurTPU.js +0 -7
- package/canvas-dist/assets/requirementDiagram-UZGBJVZJ-BPpNNusD.js +0 -64
- package/canvas-dist/assets/requirementDiagram-UZGBJVZJ-BwZF1NIK.js +0 -64
- package/canvas-dist/assets/requirementDiagram-UZGBJVZJ-CaT3Frtk.js +0 -64
- package/canvas-dist/assets/requirementDiagram-UZGBJVZJ-Dfoz7R_7.js +0 -64
- package/canvas-dist/assets/requirementDiagram-UZGBJVZJ-DsrX4TT-.js +0 -64
- package/canvas-dist/assets/requirementDiagram-UZGBJVZJ-dmouSXOl.js +0 -64
- package/canvas-dist/assets/sankeyDiagram-TZEHDZUN-BEy-A1Fu.js +0 -10
- package/canvas-dist/assets/sankeyDiagram-TZEHDZUN-BViMBiAQ.js +0 -10
- package/canvas-dist/assets/sankeyDiagram-TZEHDZUN-BqrM-qWN.js +0 -10
- package/canvas-dist/assets/sankeyDiagram-TZEHDZUN-DRkRC9qB.js +0 -10
- package/canvas-dist/assets/sankeyDiagram-TZEHDZUN-DbuzKCtn.js +0 -10
- package/canvas-dist/assets/sankeyDiagram-TZEHDZUN-_aHMKbpw.js +0 -10
- package/canvas-dist/assets/sequenceDiagram-WL72ISMW-B8FOaL2Q.js +0 -145
- package/canvas-dist/assets/sequenceDiagram-WL72ISMW-C02NQwOB.js +0 -145
- package/canvas-dist/assets/sequenceDiagram-WL72ISMW-CgyHivPj.js +0 -145
- package/canvas-dist/assets/sequenceDiagram-WL72ISMW-CzW1WaEm.js +0 -145
- package/canvas-dist/assets/sequenceDiagram-WL72ISMW-DJhHI1pe.js +0 -145
- package/canvas-dist/assets/sequenceDiagram-WL72ISMW-VFkpAeoG.js +0 -145
- package/canvas-dist/assets/stateDiagram-FKZM4ZOC-BSqFX4PJ.js +0 -1
- package/canvas-dist/assets/stateDiagram-FKZM4ZOC-BnXhhxkN.js +0 -1
- package/canvas-dist/assets/stateDiagram-FKZM4ZOC-ClARVrvt.js +0 -1
- package/canvas-dist/assets/stateDiagram-FKZM4ZOC-CuC6xesY.js +0 -1
- package/canvas-dist/assets/stateDiagram-FKZM4ZOC-DcAiGjph.js +0 -1
- package/canvas-dist/assets/stateDiagram-FKZM4ZOC-aBg0hjTp.js +0 -1
- package/canvas-dist/assets/stateDiagram-v2-4FDKWEC3-8fib9ftc.js +0 -1
- package/canvas-dist/assets/stateDiagram-v2-4FDKWEC3-B-DO0ZqO.js +0 -1
- package/canvas-dist/assets/stateDiagram-v2-4FDKWEC3-BksbsE4k.js +0 -1
- package/canvas-dist/assets/stateDiagram-v2-4FDKWEC3-C2DJCNPK.js +0 -1
- package/canvas-dist/assets/stateDiagram-v2-4FDKWEC3-CeA5jba6.js +0 -1
- package/canvas-dist/assets/stateDiagram-v2-4FDKWEC3-zsAyq0tK.js +0 -1
- package/canvas-dist/assets/timeline-definition-IT6M3QCI-BaHdYD2h.js +0 -61
- package/canvas-dist/assets/timeline-definition-IT6M3QCI-Bl2hg8IM.js +0 -61
- package/canvas-dist/assets/timeline-definition-IT6M3QCI-CrVwLiGm.js +0 -61
- package/canvas-dist/assets/timeline-definition-IT6M3QCI-DrXGRjnB.js +0 -61
- package/canvas-dist/assets/timeline-definition-IT6M3QCI-cYAwshf6.js +0 -61
- package/canvas-dist/assets/timeline-definition-IT6M3QCI-flyL0y-3.js +0 -61
- package/canvas-dist/assets/treemap-GDKQZRPO-C4Hg8kJ_.js +0 -162
- package/canvas-dist/assets/treemap-GDKQZRPO-DVY2G9qY.js +0 -162
- package/canvas-dist/assets/treemap-GDKQZRPO-DpLWPA1z.js +0 -162
- package/canvas-dist/assets/treemap-GDKQZRPO-Ds86cUVw.js +0 -162
- package/canvas-dist/assets/treemap-GDKQZRPO-DwmoI6tH.js +0 -162
- package/canvas-dist/assets/treemap-GDKQZRPO-SsGFkgVd.js +0 -162
- package/canvas-dist/assets/xychartDiagram-PRI3JC2R-B9c1iLBf.js +0 -7
- package/canvas-dist/assets/xychartDiagram-PRI3JC2R-BpX6MPWa.js +0 -7
- package/canvas-dist/assets/xychartDiagram-PRI3JC2R-CEgW_j0p.js +0 -7
- package/canvas-dist/assets/xychartDiagram-PRI3JC2R-CSEFGEQX.js +0 -7
- package/canvas-dist/assets/xychartDiagram-PRI3JC2R-CnG4XoMc.js +0 -7
- package/canvas-dist/assets/xychartDiagram-PRI3JC2R-Dftj3Bt3.js +0 -7
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# TypeScript Quiz
|
|
2
|
+
|
|
3
|
+
## Question 1
|
|
4
|
+
|
|
5
|
+
What is the primary benefit of TypeScript over JavaScript?
|
|
6
|
+
|
|
7
|
+
A) Faster runtime performance
|
|
8
|
+
B) Catch type errors at compile time
|
|
9
|
+
C) Smaller bundle size
|
|
10
|
+
D) Built-in testing framework
|
|
11
|
+
|
|
12
|
+
<!-- ANSWER: B -->
|
|
13
|
+
<!-- EXPLANATION: TypeScript's main value is static type checking — it catches type mismatches, typos, and incorrect API usage before the code runs, reducing runtime bugs. -->
|
|
14
|
+
|
|
15
|
+
## Question 2
|
|
16
|
+
|
|
17
|
+
What does `interface User { name: string; email?: string }` mean for `email`?
|
|
18
|
+
|
|
19
|
+
A) email must be present
|
|
20
|
+
B) email is optional — may be omitted
|
|
21
|
+
C) email can be string or undefined
|
|
22
|
+
D) email has a default value
|
|
23
|
+
|
|
24
|
+
<!-- ANSWER: B -->
|
|
25
|
+
<!-- EXPLANATION: The ? makes the property optional. Objects of type User can omit email. If present, it must be a string. -->
|
|
26
|
+
|
|
27
|
+
## Question 3
|
|
28
|
+
|
|
29
|
+
How do you narrow a union type `string | number` to use string methods?
|
|
30
|
+
|
|
31
|
+
A) Use `as string` to cast
|
|
32
|
+
B) Use `typeof value === 'string'` in a conditional
|
|
33
|
+
C) Use `value.toString()` always
|
|
34
|
+
D) TypeScript automatically narrows
|
|
35
|
+
|
|
36
|
+
<!-- ANSWER: B -->
|
|
37
|
+
<!-- EXPLANATION: typeof value === 'string' is a type guard. In the true branch, TypeScript narrows value to string, allowing .toUpperCase() etc. Casting with 'as' bypasses checking. -->
|
|
38
|
+
|
|
39
|
+
## Question 4
|
|
40
|
+
|
|
41
|
+
What does `T extends keyof U` mean in a generic?
|
|
42
|
+
|
|
43
|
+
A) T must be a subtype of U
|
|
44
|
+
B) T must be one of the keys of U
|
|
45
|
+
C) U must have property T
|
|
46
|
+
D) T and U are the same type
|
|
47
|
+
|
|
48
|
+
<!-- ANSWER: B -->
|
|
49
|
+
<!-- EXPLANATION: keyof U produces a union of U's keys. extends here means T is constrained to be one of those keys, enabling safe property access. -->
|
|
50
|
+
|
|
51
|
+
## Question 5
|
|
52
|
+
|
|
53
|
+
What does `Partial<User>` do?
|
|
54
|
+
|
|
55
|
+
A) Makes User extend another type
|
|
56
|
+
B) Makes all properties of User optional
|
|
57
|
+
C) Makes User immutable
|
|
58
|
+
D) Picks the first property of User
|
|
59
|
+
|
|
60
|
+
<!-- ANSWER: B -->
|
|
61
|
+
<!-- EXPLANATION: Partial<T> is a utility type that makes every property of T optional. Useful for update payloads where you might only change some fields. -->
|
|
62
|
+
|
|
63
|
+
## Question 6
|
|
64
|
+
|
|
65
|
+
When would a JavaScript error occur that TypeScript would have caught?
|
|
66
|
+
|
|
67
|
+
A) Never — TS prevents all JS errors
|
|
68
|
+
B) When using `any` or type assertions to bypass checks
|
|
69
|
+
C) Only in Node.js
|
|
70
|
+
D) When the compiler is disabled
|
|
71
|
+
|
|
72
|
+
<!-- ANSWER: B -->
|
|
73
|
+
<!-- EXPLANATION: TypeScript can be bypassed with any, type assertions (as), or @ts-ignore. In those cases, invalid code can reach runtime. -->
|
|
74
|
+
|
|
75
|
+
## Question 7
|
|
76
|
+
|
|
77
|
+
<!-- VISUAL: fill-blank -->
|
|
78
|
+
|
|
79
|
+
Complete the type annotation for a function that returns a Promise of User:
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
async function fetchUser(id: string): ___0___<User> {
|
|
83
|
+
const res = await fetch(`/users/${id}`);
|
|
84
|
+
return res.json();
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
<!-- ANSWER: Promise -->
|
|
89
|
+
<!-- EXPLANATION: Async functions return a Promise. The return type should be Promise<User> to reflect that the function returns a Promise that resolves to a User. -->
|
|
90
|
+
|
|
91
|
+
## Question 8
|
|
92
|
+
|
|
93
|
+
<!-- VISUAL: fill-blank -->
|
|
94
|
+
|
|
95
|
+
Complete the generic function that picks a property from an object:
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
function getProp<T, K ___0___ keyof T>(obj: T, key: K): T[K] {
|
|
99
|
+
return obj[key];
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
<!-- ANSWER: extends -->
|
|
104
|
+
<!-- EXPLANATION: K extends keyof T constrains the generic K to be one of the keys of T. This ensures key is a valid property name and the return type T[K] is correctly inferred. -->
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# TypeScript — Resources
|
|
2
|
+
|
|
3
|
+
## Videos
|
|
4
|
+
|
|
5
|
+
- [TypeScript in 100 Seconds](https://www.youtube.com/watch?v=zQnBQ4tB3ZA) — Fireship. Quick overview.
|
|
6
|
+
- [TypeScript Course](https://www.youtube.com/watch?v=30LWjhZzg50) — freeCodeCamp. Full beginner course.
|
|
7
|
+
- [TypeScript Generics](https://www.youtube.com/watch?v=nViEqpgwxHE) — Fireship. Generics deep dive.
|
|
8
|
+
|
|
9
|
+
## Articles and Readings
|
|
10
|
+
|
|
11
|
+
- [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/intro.html) — Official handbook. Start here.
|
|
12
|
+
- [TypeScript Deep Dive](https://basarat.gitbook.io/typescript/) — Free online book. Comprehensive.
|
|
13
|
+
- [Total TypeScript](https://www.totaltypescript.com/) — Matt Pocock. Advanced patterns and tips.
|
|
14
|
+
|
|
15
|
+
## Books
|
|
16
|
+
|
|
17
|
+
- **Effective TypeScript** by Dan Vanderkam — 62 specific ways to improve your TS code.
|
|
18
|
+
- **Programming TypeScript** by Boris Cherny — From basics to advanced.
|
|
19
|
+
|
|
20
|
+
## Tools and Playgrounds
|
|
21
|
+
|
|
22
|
+
- [TypeScript Playground](https://www.typescriptlang.org/play) — Try TS in the browser, no setup.
|
|
23
|
+
- [TypeScript Error Translator](https://ts-error-translator.vercel.app/) — Decode cryptic TS errors.
|
|
24
|
+
- [ts-toolbelt](https://github.com/millsp/ts-toolbelt) — Advanced utility types library.
|
|
25
|
+
|
|
26
|
+
## Podcasts
|
|
27
|
+
|
|
28
|
+
- [Syntax.fm — TypeScript Episodes](https://syntax.fm/) — Wes Bos & Scott Tolinski cover TS tips, tricks, and migrations.
|
|
29
|
+
- [JS Party — TypeScript](https://changelog.com/jsparty) — Panel discussions on TypeScript adoption and ecosystem.
|
|
30
|
+
- [PodRocket — TypeScript](https://podrocket.logrocket.com/) — LogRocket's podcast with frequent TS-focused episodes.
|
|
31
|
+
|
|
32
|
+
## Interactive and Visual
|
|
33
|
+
|
|
34
|
+
- [Type Challenges](https://github.com/type-challenges/type-challenges) — Collection of TypeScript type-level puzzles from easy to extreme. Practice advanced types.
|
|
35
|
+
- [TypeHero](https://typehero.dev/) — Interactive TypeScript challenges in the browser with instant feedback.
|
|
36
|
+
- [Total TypeScript — Tips](https://www.totaltypescript.com/tips) — Matt Pocock's visual TypeScript tips and patterns.
|
|
37
|
+
|
|
38
|
+
## Courses
|
|
39
|
+
|
|
40
|
+
- [Total TypeScript (free workshops)](https://www.totaltypescript.com/) — Matt Pocock. Free beginner and type transformation workshops.
|
|
41
|
+
- [freeCodeCamp — TypeScript Course](https://www.freecodecamp.org/news/learn-typescript-beginners-guide/) — Free comprehensive introduction.
|
|
42
|
+
- [Execute Program — TypeScript](https://www.executeprogram.com/courses/typescript) — Spaced-repetition-based TypeScript course with interactive exercises.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# TypeScript Walkthrough — Learn by Doing
|
|
2
|
+
|
|
3
|
+
## Step 1: Your First Types
|
|
4
|
+
|
|
5
|
+
Let's add types to a simple function.
|
|
6
|
+
|
|
7
|
+
<!-- hint:code language="typescript" highlight="1,3" -->
|
|
8
|
+
|
|
9
|
+
**Embed:** https://www.typescriptlang.org/play
|
|
10
|
+
|
|
11
|
+
**Task:** Write a function `add(a, b)` that adds two numbers. Add explicit parameter and return types. Call it with numbers and observe the output.
|
|
12
|
+
|
|
13
|
+
**Question:** What happens if you try to call `add("1", "2")`? What does the compiler tell you, and what would JavaScript do at runtime?
|
|
14
|
+
|
|
15
|
+
**Checkpoint:** The user understands that TypeScript rejects invalid argument types at compile time.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Step 2: Interfaces
|
|
20
|
+
|
|
21
|
+
<!-- hint:code language="typescript" highlight="1,4" -->
|
|
22
|
+
|
|
23
|
+
**Task:** Define an interface `Product` with `id`, `name`, and `price`. Create a function `formatProduct(p: Product)` that returns a string like "Product: name ($price)".
|
|
24
|
+
|
|
25
|
+
**Question:** What happens if you pass an object that has extra properties? What about one missing `price`?
|
|
26
|
+
|
|
27
|
+
**Checkpoint:** The user can define and use interfaces, and understands excess property checks and required vs optional fields.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Step 3: Unions and Narrowing
|
|
32
|
+
|
|
33
|
+
**Task:** Write a function `double(x: string | number)` that returns the string repeated twice if it's a string, or the number multiplied by 2 if it's a number. Use `typeof` to narrow.
|
|
34
|
+
|
|
35
|
+
**Question:** Why do we need the `typeof` check? What would TypeScript infer about `x` without it?
|
|
36
|
+
|
|
37
|
+
**Checkpoint:** The user can narrow union types and explain why it's necessary.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Step 4: Generics
|
|
42
|
+
|
|
43
|
+
<!-- hint:card type="concept" title="Generics let TypeScript infer types from usage — T is resolved when you call the function" -->
|
|
44
|
+
|
|
45
|
+
**Task:** Write a generic function `first<T>(arr: T[]): T | undefined` that returns the first element of an array. Test it with number and string arrays.
|
|
46
|
+
|
|
47
|
+
**Question:** How does TypeScript know the return type when you call `first([1, 2, 3])`? Where does `T` get its value?
|
|
48
|
+
|
|
49
|
+
**Checkpoint:** The user understands generic type inference from usage.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Step 5: Generic Constraints
|
|
54
|
+
|
|
55
|
+
**Task:** Write `getProperty<T, K extends keyof T>(obj: T, key: K): T[K]` that safely gets a property. The compiler should ensure `key` is a valid key of `obj`.
|
|
56
|
+
|
|
57
|
+
**Question:** What does `K extends keyof T` mean? Why can't we just use `string` for the key?
|
|
58
|
+
|
|
59
|
+
**Checkpoint:** The user can use `keyof` and constrained generics.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Step 6: Utility Types
|
|
64
|
+
|
|
65
|
+
<!-- hint:celebrate -->
|
|
66
|
+
|
|
67
|
+
**Task:** Given a `User` interface, create a type `UserUpdate` where all fields are optional (using `Partial`). Create a function that accepts `UserUpdate` and merges it into an existing user.
|
|
68
|
+
|
|
69
|
+
**Question:** When would you use `Partial` vs defining a separate interface with optional fields?
|
|
70
|
+
|
|
71
|
+
**Checkpoint:** The user can apply utility types for common patterns.
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# TypeScript Fundamentals — Interactive Workshop Scenarios
|
|
2
|
+
# Each scenario has setup, files, task, validations, and Socratic agent prompts.
|
|
3
|
+
|
|
4
|
+
scenarios:
|
|
5
|
+
- id: type-annotations
|
|
6
|
+
title: "Add Type Annotations to Functions"
|
|
7
|
+
difficulty: beginner
|
|
8
|
+
xp: 20
|
|
9
|
+
setup:
|
|
10
|
+
- "mkdir -p type-annotations && cd type-annotations"
|
|
11
|
+
files:
|
|
12
|
+
- name: greet.ts
|
|
13
|
+
content: |
|
|
14
|
+
function greet(name) {
|
|
15
|
+
return "Hello " + name;
|
|
16
|
+
}
|
|
17
|
+
console.log(greet("world"));
|
|
18
|
+
language: typescript
|
|
19
|
+
readonly: false
|
|
20
|
+
task: "Add proper TypeScript type annotations to the greet function so that name is a string and the return type is explicitly string. Then run the file with npx ts-node greet.ts (or tsc && node greet.js) and verify there are no type errors."
|
|
21
|
+
validations:
|
|
22
|
+
- label: "File contains type annotations"
|
|
23
|
+
check: file-changed
|
|
24
|
+
pattern: "name: string|: string"
|
|
25
|
+
- label: "No type errors when compiled/run"
|
|
26
|
+
check: output-contains
|
|
27
|
+
pattern: "Hello world"
|
|
28
|
+
hints:
|
|
29
|
+
- "TypeScript uses colon syntax for types — try adding : string after the parameter name."
|
|
30
|
+
- "You can also add a return type: function greet(name: string): string"
|
|
31
|
+
- "Run npx ts-node greet.ts to verify — if there are type errors, they will appear before execution."
|
|
32
|
+
agent_prompts:
|
|
33
|
+
on_start: "What do you think happens if someone passes a number to greet? How might types help catch that before the code runs?"
|
|
34
|
+
|
|
35
|
+
- id: interfaces
|
|
36
|
+
title: "Define and Use Interfaces"
|
|
37
|
+
difficulty: beginner
|
|
38
|
+
xp: 25
|
|
39
|
+
setup:
|
|
40
|
+
- "mkdir -p interfaces && cd interfaces"
|
|
41
|
+
files:
|
|
42
|
+
- name: user.ts
|
|
43
|
+
content: |
|
|
44
|
+
const user = {
|
|
45
|
+
id: 1,
|
|
46
|
+
name: "Alice",
|
|
47
|
+
email: "alice@example.com",
|
|
48
|
+
active: true,
|
|
49
|
+
};
|
|
50
|
+
console.log(user.name);
|
|
51
|
+
language: typescript
|
|
52
|
+
readonly: false
|
|
53
|
+
- name: task.ts
|
|
54
|
+
content: |
|
|
55
|
+
function formatUser(u) {
|
|
56
|
+
return u.name + " <" + u.email + ">";
|
|
57
|
+
}
|
|
58
|
+
const u = { id: 1, name: "Bob", email: "bob@example.com" };
|
|
59
|
+
console.log(formatUser(u));
|
|
60
|
+
language: typescript
|
|
61
|
+
readonly: false
|
|
62
|
+
task: "Create a User interface in user.ts with id (number), name (string), email (string), and active (boolean). Apply the interface to the user object. Then update task.ts to use the User interface for the formatUser parameter and ensure both files type-check correctly."
|
|
63
|
+
validations:
|
|
64
|
+
- label: "User interface defined and used"
|
|
65
|
+
check: file-changed
|
|
66
|
+
pattern: "interface User"
|
|
67
|
+
hints:
|
|
68
|
+
- "Interfaces describe the shape of an object. Start with: interface User { id: number; name: string; ... }"
|
|
69
|
+
- "Use the interface as a type: const user: User = { ... }"
|
|
70
|
+
- "For formatUser, type the parameter: function formatUser(u: User) { ... }"
|
|
71
|
+
agent_prompts:
|
|
72
|
+
on_start: "Without types, what could go wrong if formatUser receives an object missing the email field? How would an interface help?"
|
|
73
|
+
|
|
74
|
+
- id: generics
|
|
75
|
+
title: "Refactor to Generic Functions"
|
|
76
|
+
difficulty: intermediate
|
|
77
|
+
xp: 35
|
|
78
|
+
setup:
|
|
79
|
+
- "mkdir -p generics && cd generics"
|
|
80
|
+
files:
|
|
81
|
+
- name: utils.ts
|
|
82
|
+
content: |
|
|
83
|
+
function firstString(arr: string[]): string | undefined {
|
|
84
|
+
return arr[0];
|
|
85
|
+
}
|
|
86
|
+
function firstNumber(arr: number[]): number | undefined {
|
|
87
|
+
return arr[0];
|
|
88
|
+
}
|
|
89
|
+
function firstBool(arr: boolean[]): boolean | undefined {
|
|
90
|
+
return arr[0];
|
|
91
|
+
}
|
|
92
|
+
console.log(firstString(["a", "b"]));
|
|
93
|
+
console.log(firstNumber([1, 2, 3]));
|
|
94
|
+
language: typescript
|
|
95
|
+
readonly: false
|
|
96
|
+
task: "Refactor these three nearly-identical functions into a single generic function first<T> that works for any array type. Ensure the file compiles without errors and produces the same output."
|
|
97
|
+
validations:
|
|
98
|
+
- label: "Generic function replaces duplicates"
|
|
99
|
+
check: file-changed
|
|
100
|
+
pattern: "<T>|generic"
|
|
101
|
+
- label: "No compilation errors"
|
|
102
|
+
check: output-contains
|
|
103
|
+
pattern: "a|1"
|
|
104
|
+
hints:
|
|
105
|
+
- "Generics use angle brackets: function first<T>(arr: T[]): T | undefined"
|
|
106
|
+
- "The type parameter T lets TypeScript infer the return type from the input."
|
|
107
|
+
- "Run npx tsc --noEmit to check for type errors without emitting files."
|
|
108
|
+
agent_prompts:
|
|
109
|
+
on_start: "What do these three functions have in common? What varies? How might you write one function that handles all cases?"
|
|
110
|
+
|
|
111
|
+
- id: type-narrowing
|
|
112
|
+
title: "Use Type Guards and Narrowing"
|
|
113
|
+
difficulty: intermediate
|
|
114
|
+
xp: 35
|
|
115
|
+
setup:
|
|
116
|
+
- "mkdir -p type-narrowing && cd type-narrowing"
|
|
117
|
+
files:
|
|
118
|
+
- name: shapes.ts
|
|
119
|
+
content: |
|
|
120
|
+
type Circle = { kind: "circle"; radius: number };
|
|
121
|
+
type Rectangle = { kind: "rectangle"; width: number; height: number };
|
|
122
|
+
type Shape = Circle | Rectangle;
|
|
123
|
+
|
|
124
|
+
function area(shape: Shape): number {
|
|
125
|
+
if (shape.kind === "circle") {
|
|
126
|
+
return Math.PI * shape.radius * shape.radius;
|
|
127
|
+
}
|
|
128
|
+
return shape.width * shape.height;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const c: Circle = { kind: "circle", radius: 5 };
|
|
132
|
+
const r: Rectangle = { kind: "rectangle", width: 4, height: 6 };
|
|
133
|
+
console.log(area(c), area(r));
|
|
134
|
+
language: typescript
|
|
135
|
+
readonly: false
|
|
136
|
+
task: "The area function already narrows on the kind discriminant. Add a type guard function isCircle(shape: Shape): shape is Circle and use it in a new function describe(shape: Shape) that returns a string like 'Circle with radius 5' or 'Rectangle 4x6'. Ensure no type errors."
|
|
137
|
+
validations:
|
|
138
|
+
- label: "Type guard and describe function added"
|
|
139
|
+
check: file-changed
|
|
140
|
+
pattern: "is Circle|describe"
|
|
141
|
+
hints:
|
|
142
|
+
- "Type guard syntax: function isCircle(shape: Shape): shape is Circle { return shape.kind === 'circle'; }"
|
|
143
|
+
- "Use the guard: if (isCircle(shape)) { /* shape is Circle here */ }"
|
|
144
|
+
- "The describe function can use the guard or a switch on shape.kind."
|
|
145
|
+
agent_prompts:
|
|
146
|
+
on_start: "Inside the first branch, TypeScript knows shape is Circle. How does it know? What would happen if we added a new shape type?"
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# User Story Mapping — From User Goals to Interface
|
|
2
|
+
|
|
3
|
+
<!-- hint:slides topic="User story mapping: backbone and body, walking skeleton, release slicing, and workshop facilitation" slides="5" -->
|
|
4
|
+
|
|
5
|
+
## What Is Story Mapping?
|
|
6
|
+
|
|
7
|
+
User story mapping is a collaborative technique for organizing user stories into a visual map that reflects the user's journey. It helps teams see the big picture, prioritize work, and slice releases that deliver value incrementally. Jeff Patton popularized the method in *User Story Mapping*.
|
|
8
|
+
|
|
9
|
+
## Why It Works
|
|
10
|
+
|
|
11
|
+
- **User-centered** — The map is organized by user activities, not features or technical components.
|
|
12
|
+
- **Visual** — A 2D map (backbone + body) makes scope and sequence obvious.
|
|
13
|
+
- **Release-ready** — Horizontal slices create coherent releases; vertical slices create thin end-to-end flows.
|
|
14
|
+
- **Conversation starter** — The map fuels discussion about goals, constraints, and tradeoffs.
|
|
15
|
+
|
|
16
|
+
## The Backbone vs The Body
|
|
17
|
+
|
|
18
|
+
The map has two main parts:
|
|
19
|
+
|
|
20
|
+
| Part | What It Is | Example (E‑commerce) |
|
|
21
|
+
|------|------------|----------------------|
|
|
22
|
+
| **Backbone** | High-level user activities (left-to-right, top row) | Browse → Add to cart → Check out → Track order |
|
|
23
|
+
| **Body** | User tasks under each activity (stacked below) | Under "Check out": Enter shipping, Choose payment, Review order, Confirm |
|
|
24
|
+
|
|
25
|
+
```mermaid
|
|
26
|
+
flowchart LR
|
|
27
|
+
subgraph Backbone
|
|
28
|
+
A[Browse] --> B[Add to Cart]
|
|
29
|
+
B --> C[Check Out]
|
|
30
|
+
C --> D[Track Order]
|
|
31
|
+
end
|
|
32
|
+
subgraph Body["Body (tasks under each activity)"]
|
|
33
|
+
E[Search / Filter]
|
|
34
|
+
F[View product]
|
|
35
|
+
G[Add to cart]
|
|
36
|
+
H[Enter shipping]
|
|
37
|
+
I[Choose payment]
|
|
38
|
+
J[Confirm]
|
|
39
|
+
end
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Walking the User's Journey
|
|
43
|
+
|
|
44
|
+
To build the map:
|
|
45
|
+
|
|
46
|
+
1. **Identify the user** — Who is this map for? (e.g., new shopper, returning customer)
|
|
47
|
+
2. **List activities** — What do they do at a high level? (Use verbs: browse, compare, buy)
|
|
48
|
+
3. **Add tasks** — Under each activity, break it into specific tasks. "Check out" → Enter address, Select shipping, Enter payment, Review, Confirm.
|
|
49
|
+
4. **Order left-to-right** — Activities and tasks follow the natural sequence of the user's journey.
|
|
50
|
+
5. **Walk the map** — Read it like a story. Does it make sense? What's missing?
|
|
51
|
+
|
|
52
|
+
## Slicing Releases: Walking Skeleton
|
|
53
|
+
|
|
54
|
+
A **walking skeleton** is the thinnest end-to-end path that delivers value. You slice horizontally:
|
|
55
|
+
|
|
56
|
+
- **Release 1 (MVP)** — One path through the map: minimal tasks to complete the journey.
|
|
57
|
+
- **Release 2** — Add the next most important tasks or variations.
|
|
58
|
+
- **Release 3+** — Expand functionality, edge cases, optimizations.
|
|
59
|
+
|
|
60
|
+
```mermaid
|
|
61
|
+
flowchart TD
|
|
62
|
+
subgraph Map["Story Map"]
|
|
63
|
+
B1[Browse - basic]
|
|
64
|
+
B2[Add to cart]
|
|
65
|
+
C1[Check out - minimal]
|
|
66
|
+
C2[Payment - one option]
|
|
67
|
+
end
|
|
68
|
+
subgraph R1["Release 1: Walking Skeleton"]
|
|
69
|
+
R1A[Browse] --> R1B[Add]
|
|
70
|
+
R1B --> R1C[Checkout]
|
|
71
|
+
end
|
|
72
|
+
subgraph R2["Release 2"]
|
|
73
|
+
R2A[More browse]
|
|
74
|
+
R2B[Multiple payment]
|
|
75
|
+
end
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## From Map to MVP
|
|
79
|
+
|
|
80
|
+
1. **Identify the outcome** — What does the user accomplish? (e.g., "Purchase a product")
|
|
81
|
+
2. **Find the critical path** — The minimum tasks needed to reach that outcome.
|
|
82
|
+
3. **Slice Release 1** — Those tasks become your MVP. Everything else is "later."
|
|
83
|
+
4. **Write acceptance criteria** — For each story in the slice, define "done."
|
|
84
|
+
|
|
85
|
+
## Story Mapping Workshops
|
|
86
|
+
|
|
87
|
+
**How to run one:**
|
|
88
|
+
|
|
89
|
+
1. **Prep** — Define the user and outcome. Bring sticky notes (digital or physical).
|
|
90
|
+
2. **Activities** — As a group, brainstorm activities. Place them left-to-right.
|
|
91
|
+
3. **Tasks** — Under each activity, add tasks. Encourage "that's too big—break it down."
|
|
92
|
+
4. **Prioritize** — Vote or discuss. Move the most important tasks to the top of each column.
|
|
93
|
+
5. **Slice** — Draw a line: above = Release 1, below = later.
|
|
94
|
+
6. **Commit** — Capture the map and release boundaries. Treat it as a living artifact.
|
|
95
|
+
|
|
96
|
+
**Tip:** Include developers, designers, and product. The conversation matters more than the map.
|
|
97
|
+
|
|
98
|
+
## Connecting Stories to Acceptance Criteria
|
|
99
|
+
|
|
100
|
+
Each task on the map can become one or more user stories:
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
As a [user], I want to [task] so that [outcome].
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Acceptance criteria answer: "How do we know it's done?"
|
|
107
|
+
|
|
108
|
+
- **Given** [context], **When** [action], **Then** [expected result]
|
|
109
|
+
- Or: a short checklist of conditions that must be true
|
|
110
|
+
|
|
111
|
+
## Common Mistakes
|
|
112
|
+
|
|
113
|
+
| Mistake | Fix |
|
|
114
|
+
|---------|-----|
|
|
115
|
+
| **Too granular too early** | Start with activities and a few tasks. Add detail when slicing. |
|
|
116
|
+
| **Forgetting the user goal** | Always tie the map to a specific user and outcome. |
|
|
117
|
+
| **Activities = features** | Activities are user actions (e.g., "Compare products"), not system features. |
|
|
118
|
+
| **Skipping the walk** | Read the map as a story. Gaps and odd ordering will appear. |
|
|
119
|
+
| **One map for everyone** | Different users have different journeys. Create separate maps if needed. |
|
|
120
|
+
|
|
121
|
+
## Summary
|
|
122
|
+
|
|
123
|
+
User story mapping turns user goals into a visual journey: backbone (activities) + body (tasks). Slice horizontally for releases; start with a walking skeleton. Run workshops, walk the map, and connect tasks to user stories with acceptance criteria. The map is a living artifact—update it as you learn.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# User Story Mapping Exercises
|
|
2
|
+
|
|
3
|
+
## Exercise 1: Build a Map from Scratch
|
|
4
|
+
|
|
5
|
+
**Task:** Create a complete story map for "Plan a weekend trip" (user: leisure traveler). Include: backbone (4–5 activities), body (2–4 tasks per activity), and a walking skeleton release line.
|
|
6
|
+
|
|
7
|
+
**Validation:**
|
|
8
|
+
- [ ] Activities are user actions (verbs), not features
|
|
9
|
+
- [ ] Tasks are specific enough to implement
|
|
10
|
+
- [ ] Left-to-right order reflects the natural journey
|
|
11
|
+
- [ ] Walking skeleton includes the minimum path to "trip planned"
|
|
12
|
+
|
|
13
|
+
**Hints:**
|
|
14
|
+
1. Example activities: Discover destinations → Compare options → Book → Prepare
|
|
15
|
+
2. "Book" might include: Choose dates, Select accommodation, Enter payment, Confirm
|
|
16
|
+
3. Walking skeleton = one path through; variations and extras go below the line
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Exercise 2: Slice Multiple Releases
|
|
21
|
+
|
|
22
|
+
**Task:** Using your "Plan a weekend trip" map (or any map you've built), define three releases: MVP, Release 2, Release 3. For each, list the new tasks and the user outcome that release enables.
|
|
23
|
+
|
|
24
|
+
**Validation:**
|
|
25
|
+
- [ ] Each release has a clear outcome (e.g., "MVP: Book a basic trip")
|
|
26
|
+
- [ ] Release 2 builds on Release 1; Release 3 builds on Release 2
|
|
27
|
+
- [ ] No release includes tasks that depend on later releases
|
|
28
|
+
- [ ] You can explain why each task landed in its release
|
|
29
|
+
|
|
30
|
+
**Hints:**
|
|
31
|
+
1. MVP = core happy path only
|
|
32
|
+
2. Release 2 might add: multiple payment options, cancellation, itinerary export
|
|
33
|
+
3. Release 3 might add: recommendations, social sharing, loyalty rewards
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Exercise 3: Convert Map to User Stories
|
|
38
|
+
|
|
39
|
+
**Task:** Take the Release 1 slice from Exercise 1. Write user stories for each task. Add acceptance criteria using "Given / When / Then" or a checklist format.
|
|
40
|
+
|
|
41
|
+
**Validation:**
|
|
42
|
+
- [ ] Each task maps to at least one user story
|
|
43
|
+
- [ ] Stories follow "As a [user], I want to [action] so that [outcome]"
|
|
44
|
+
- [ ] Acceptance criteria are testable
|
|
45
|
+
- [ ] Stories are ordered by journey sequence
|
|
46
|
+
|
|
47
|
+
**Hints:**
|
|
48
|
+
1. One task can become multiple stories if it's complex
|
|
49
|
+
2. Acceptance criteria: "Given I'm on the booking page, When I enter valid card details, Then the booking confirms"
|
|
50
|
+
3. Keep criteria focused—3–5 per story max
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Exercise 4: Spot the Mistakes
|
|
55
|
+
|
|
56
|
+
**Task:** Review this map and identify at least three problems:
|
|
57
|
+
|
|
58
|
+
> Activities: Login, Dashboard, Settings, API Integration, Database optimization
|
|
59
|
+
|
|
60
|
+
> Tasks under "Login": Build OAuth, Hash passwords, Cache sessions, Add 2FA
|
|
61
|
+
|
|
62
|
+
**Validation:**
|
|
63
|
+
- [ ] At least three issues identified
|
|
64
|
+
- [ ] Each issue has a suggested fix
|
|
65
|
+
- [ ] The corrected map would better reflect a user journey
|
|
66
|
+
|
|
67
|
+
**Hints:**
|
|
68
|
+
1. "API Integration" and "Database optimization" are technical, not user activities
|
|
69
|
+
2. Tasks should be user-facing; "Hash passwords" is implementation
|
|
70
|
+
3. "Dashboard" might be a place, not an activity—what does the user *do* there?
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Exercise 5: Facilitate a Remote Workshop
|
|
75
|
+
|
|
76
|
+
**Task:** Run a 20-minute remote story mapping session using a tool (Miro, FigJam, or Google Slides). Invite 2 colleagues. Build a map for a feature you're considering. Record the session or take screenshots.
|
|
77
|
+
|
|
78
|
+
**Validation:**
|
|
79
|
+
- [ ] Map is collaboratively built (not pre-made)
|
|
80
|
+
- [ ] Backbone and body are present
|
|
81
|
+
- [ ] At least one release slice is drawn
|
|
82
|
+
- [ ] Participants contributed to the structure
|
|
83
|
+
|
|
84
|
+
**Hints:**
|
|
85
|
+
1. Share the user and outcome upfront
|
|
86
|
+
2. Use sticky-note equivalents; color-code activities vs. tasks
|
|
87
|
+
3. Use a timer to keep the session focused
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
slug: user-story-mapping
|
|
2
|
+
title: "User Story Mapping -- From User Goals to Interface"
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
description: "Transform user goals into a visual map and prioritized releases."
|
|
5
|
+
category: ux-design
|
|
6
|
+
tags: [user-stories, story-mapping, ux, user-flows, product-design, agile]
|
|
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: []
|
|
22
|
+
related: [writing-prds, design-critique, accessibility-fundamentals]
|
|
23
|
+
|
|
24
|
+
triggers:
|
|
25
|
+
- "What is user story mapping?"
|
|
26
|
+
- "How do I map user journeys?"
|
|
27
|
+
- "How do I break features into user stories?"
|
|
28
|
+
- "How do I prioritize user stories?"
|
|
29
|
+
|
|
30
|
+
visuals:
|
|
31
|
+
diagrams: [diagram-mermaid, diagram-flow]
|
|
32
|
+
quiz-types: [quiz-drag-order, quiz-matching]
|
|
33
|
+
slides: true
|
|
34
|
+
|
|
35
|
+
sources:
|
|
36
|
+
- url: "https://www.oreilly.com/library/view/user-story-mapping/9781491904909/"
|
|
37
|
+
label: "User Story Mapping by Jeff Patton"
|
|
38
|
+
type: book
|
|
39
|
+
- url: "https://www.nngroup.com"
|
|
40
|
+
label: "Nielsen Norman Group"
|
|
41
|
+
type: docs
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# User Story Mapping — Quick Reference
|
|
2
|
+
|
|
3
|
+
## Backbone vs Body
|
|
4
|
+
|
|
5
|
+
| Part | What It Is | Example |
|
|
6
|
+
|------|------------|---------|
|
|
7
|
+
| **Backbone** | High-level activities, left-to-right (top row) | Browse → Add to cart → Check out → Track |
|
|
8
|
+
| **Body** | Tasks under each activity (stacked below) | Under "Check out": Enter shipping, Choose payment, Confirm |
|
|
9
|
+
|
|
10
|
+
## Building the Map
|
|
11
|
+
|
|
12
|
+
1. **Identify user** — Who is this for?
|
|
13
|
+
2. **List activities** — Verbs, left-to-right
|
|
14
|
+
3. **Add tasks** — Under each activity
|
|
15
|
+
4. **Order** — Natural user journey sequence
|
|
16
|
+
5. **Walk the map** — Read as a story; find gaps
|
|
17
|
+
|
|
18
|
+
## Slice Releases
|
|
19
|
+
|
|
20
|
+
| Slice | What It Means |
|
|
21
|
+
|-------|---------------|
|
|
22
|
+
| **Release 1** | Above the line—walking skeleton (MVP) |
|
|
23
|
+
| **Release 2+** | Below the line—later iterations |
|
|
24
|
+
|
|
25
|
+
**Rule:** Slice horizontally. Most important tasks at top of each column.
|
|
26
|
+
|
|
27
|
+
## Walking Skeleton
|
|
28
|
+
|
|
29
|
+
The thinnest end-to-end path that delivers user value. Minimum tasks to complete the journey.
|
|
30
|
+
|
|
31
|
+
## User Story Format
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
As a [user], I want to [task] so that [outcome].
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Acceptance Criteria (Given/When/Then)
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
Given [context], When [action], Then [expected result]
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Workshop Checklist
|
|
44
|
+
|
|
45
|
+
- [ ] Define user and outcome upfront
|
|
46
|
+
- [ ] Activities = user actions (not features or screens)
|
|
47
|
+
- [ ] Include developers, designers, product
|
|
48
|
+
- [ ] Walk the map to validate
|
|
49
|
+
- [ ] Vote or discuss to prioritize tasks
|
|
50
|
+
- [ ] Draw the line: above = Release 1
|
|
51
|
+
|
|
52
|
+
## Common Mistakes
|
|
53
|
+
|
|
54
|
+
| Mistake | Fix |
|
|
55
|
+
|---------|-----|
|
|
56
|
+
| Too granular too early | Start with activities + few tasks; add detail when slicing |
|
|
57
|
+
| Forgetting user goal | Tie map to specific user and outcome |
|
|
58
|
+
| Activities = features | Activities are user actions (e.g., "Compare products") |
|
|
59
|
+
| Skipping the walk | Read map left-to-right; gaps will appear |
|
|
60
|
+
| One map for everyone | Different users → different maps |
|
|
61
|
+
|
|
62
|
+
## Map → Stories
|
|
63
|
+
|
|
64
|
+
Each task can become one or more user stories. Add acceptance criteria. Treat the map as a living artifact—update as you learn.
|