@powerhousedao/academy 5.1.0-dev.1 → 5.1.0-dev.11

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.
Files changed (75) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/blog/BeyondCommunication-ABlueprintForDevelopment.md +2 -1
  3. package/blog/TheChallengeOfChange.md +1 -0
  4. package/docs/academy/01-GetStarted/00-ExploreDemoPackage.mdx +24 -27
  5. package/docs/academy/01-GetStarted/01-CreateNewPowerhouseProject.md +118 -9
  6. package/docs/academy/01-GetStarted/02-DefineToDoListDocumentModel.md +110 -28
  7. package/docs/academy/01-GetStarted/03-ImplementOperationReducers.md +191 -145
  8. package/docs/academy/01-GetStarted/04-WriteDocumentModelTests.md +378 -0
  9. package/docs/academy/01-GetStarted/05-BuildToDoListEditor.md +560 -0
  10. package/docs/academy/01-GetStarted/_04-BuildToDoListEditor +1 -1
  11. package/docs/academy/02-MasteryTrack/01-BuilderEnvironment/03-BuilderTools.md +2 -2
  12. package/docs/academy/{01-GetStarted → 02-MasteryTrack/01-BuilderEnvironment}/05-VetraStudio.md +48 -6
  13. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/02-SpecifyTheStateSchema.md +75 -44
  14. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/03-SpecifyDocumentOperations.md +28 -22
  15. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/04-UseTheDocumentModelGenerator.md +28 -31
  16. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/05-ImplementDocumentReducers.md +211 -206
  17. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/06-ImplementDocumentModelTests.md +176 -62
  18. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/07-ExampleToDoListRepository.md +21 -0
  19. package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/01-BuildingDocumentEditors.md +309 -319
  20. package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/06-DocumentTools/00-DocumentToolbar.mdx +4 -0
  21. package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/06-DocumentTools/01-OperationHistory.md +4 -0
  22. package/docs/academy/02-MasteryTrack/05-Launch/04-ConfigureEnvironment.md +1 -1
  23. package/docs/academy/03-ExampleUsecases/Chatroom/02-CreateNewPowerhouseProject.md +111 -35
  24. package/docs/academy/03-ExampleUsecases/Chatroom/03-DefineChatroomDocumentModel.md +255 -76
  25. package/docs/academy/03-ExampleUsecases/Chatroom/04-ImplementOperationReducers.md +281 -160
  26. package/docs/academy/03-ExampleUsecases/Chatroom/05-ImplementChatroomEditor.md +188 -35
  27. package/docs/academy/03-ExampleUsecases/Chatroom/06-LaunchALocalReactor.md +95 -7
  28. package/docs/academy/03-ExampleUsecases/Chatroom/_category_.json +1 -1
  29. package/docs/academy/03-ExampleUsecases/TodoList/00-GetTheStarterCode.md +24 -0
  30. package/docs/academy/03-ExampleUsecases/TodoList/01-GenerateTodoListDocumentModel.md +211 -0
  31. package/docs/academy/03-ExampleUsecases/TodoList/02-ImplementTodoListDocumentModelReducerOperationHandlers.md +171 -0
  32. package/docs/academy/03-ExampleUsecases/TodoList/03-AddTestsForTodoListActions.md +462 -0
  33. package/docs/academy/03-ExampleUsecases/TodoList/04-GenerateTodoListDocumentEditor.md +45 -0
  34. package/docs/academy/03-ExampleUsecases/TodoList/05-ImplementTodoListDocumentEditorUIComponents.md +422 -0
  35. package/docs/academy/03-ExampleUsecases/TodoList/06-GenerateTodoDriveExplorer.md +61 -0
  36. package/docs/academy/03-ExampleUsecases/TodoList/07-AddSharedComponentForShowingTodoListStats.md +384 -0
  37. package/docs/academy/03-ExampleUsecases/TodoList/_category_.json +8 -0
  38. package/docs/academy/03-ExampleUsecases/VetraPackageLibrary/VetraPackageLibrary.md +7 -0
  39. package/docs/academy/03-ExampleUsecases/VetraPackageLibrary/_category_.json +9 -0
  40. package/docs/academy/04-APIReferences/00-PowerhouseCLI.md +6 -2
  41. package/docs/academy/04-APIReferences/01-ReactHooks.md +2 -2
  42. package/docs/academy/04-APIReferences/06-VetraRemoteDrive.md +160 -0
  43. package/docs/academy/04-APIReferences/renown-sdk/00-Overview.md +316 -0
  44. package/docs/academy/04-APIReferences/renown-sdk/01-Authentication.md +672 -0
  45. package/docs/academy/04-APIReferences/renown-sdk/02-APIReference.md +957 -0
  46. package/docs/academy/04-APIReferences/renown-sdk/_category_.json +8 -0
  47. package/docs/academy/05-Architecture/00-PowerhouseArchitecture.md +7 -39
  48. package/docs/academy/06-ComponentLibrary/00-DocumentEngineering.md +72 -24
  49. package/docs/academy/08-Glossary.md +7 -0
  50. package/docs/academy/10-TodoListTutorial/02-ImplementTodoListDocumentModelReducerOperationHandlers.md +171 -0
  51. package/docs/academy/10-TodoListTutorial/03-AddTestsForTodoListActions.md +462 -0
  52. package/docs/academy/10-TodoListTutorial/05-ImplementTodoListDocumentEditorUIComponents.md +422 -0
  53. package/docs/academy/10-TodoListTutorial/07-AddSharedComponentForShowingTodoListStats.md +370 -0
  54. package/docusaurus.config.ts +28 -3
  55. package/package.json +1 -1
  56. package/sidebars.ts +49 -12
  57. package/src/css/custom.css +26 -18
  58. package/static/img/Vetra-logo-dark.svg +11 -0
  59. package/static/img/vetra-logo-light.svg +11 -0
  60. package/docs/academy/00-EthereumArgentinaHackathon.md +0 -207
  61. package/docs/academy/01-GetStarted/04-BuildToDoListEditor.md +0 -218
  62. package/docs/academy/01-GetStarted/06-ReactorMCP.md +0 -58
  63. package/docs/academy/05-Architecture/02-ReferencingMonorepoPackages +0 -65
  64. package/docs/academy/05-Architecture/04-MovingBeyondCRUD +0 -61
  65. /package/docs/academy/{01-GetStarted → 02-MasteryTrack/01-BuilderEnvironment}/images/Modules.png +0 -0
  66. /package/docs/academy/{01-GetStarted → 02-MasteryTrack/01-BuilderEnvironment}/images/VetraStudioDrive.png +0 -0
  67. /package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/06-DocumentTools/{02-RevisionHistoryTimeline → 02-RevisionHistoryTimeline/360/237/232/247"} +0 -0
  68. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{01-WhatIsADocumentModel → 360/237/232/247 /01-WhatIsADocumentModel"} +0 -0
  69. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{02-DAOandDocumentsModelsQ+A → 360/237/232/247 /02-DAOandDocumentsModelsQ+A"} +0 -0
  70. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{02-domain-modeling → 360/237/232/247 /02-domain-modeling"} +0 -0
  71. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{03-BenefitsOfDocumentModels → 360/237/232/247 /03-BenefitsOfDocumentModels"} +0 -0
  72. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{04-UtilitiesAndTips → 360/237/232/247 /04-UtilitiesAndTips"} +0 -0
  73. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{05-best-practices → 360/237/232/247 /05-best-practices"} +0 -0
  74. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{_category_.json → 360/237/232/247 /_category_.json"} +0 -0
  75. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{three-data-layers.png → 360/237/232/247 /three-data-layers.png"} +0 -0
@@ -6,100 +6,214 @@ In the previous chapter, we implemented the core reducer logic for our document
6
6
 
7
7
  Testing is not an afterthought; it's an integral part of the development lifecycle, especially in systems like Powerhouse where data integrity and predictable state transitions are paramount. Well-crafted tests serve as a safety net, allowing you to refactor and extend your document model with confidence.
8
8
 
9
- This document provides a practical, hands-on tutorial for testing the `To-do List` document model reducers you have just built.
9
+ This document provides a practical, hands-on tutorial for testing the `TodoList` document model reducers you have just built.
10
10
 
11
- ## Practical implementation: Writing and running the To-do List tests
11
+ ## Practical implementation: Writing and running the TodoList tests
12
12
 
13
- This tutorial assumes you have implemented the `To-do List` reducers as described in the previous chapter and that the code generator has created a test file skeleton at `document-models/to-do-list/src/reducers/tests/to-do-list.test.ts`.
13
+ This tutorial assumes you have implemented the `TodoList` reducers as described in the previous chapter and that the code generator has created a test file skeleton at `document-models/todo-list/src/tests/todos.test.ts`.
14
14
 
15
15
  <details>
16
- <summary>Tutorial: Implementing and running the `To-do List` reducer tests</summary>
16
+ <summary>Tutorial: Implementing and running the TodoList reducer tests</summary>
17
17
 
18
18
  ### 1. Implement the reducer tests
19
19
 
20
- With the reducer logic in place, it's critical to test it. Navigate to the generated test file at `document-models/to-do-list/src/reducers/tests/to-do-list.test.ts` and replace its contents with the following test suite.
20
+ With the reducer logic in place, it's critical to test it. Navigate to the generated test file at `document-models/todo-list/src/tests/todos.test.ts` and replace its contents with comprehensive tests.
21
21
 
22
- This suite tests each operation, verifying not only that the `items` array is correct, but also that our `stats` object is updated as expected and that the operation itself is recorded properly in the document's history.
22
+ This suite tests each operation, verifying not only that the `items` array is correct, but also that the operation itself is recorded properly in the document's history.
23
23
 
24
- ```typescript
25
- import utils from "../../gen/utils.js";
26
- import { reducer } from "../../gen/reducer.js";
27
- import * as creators from "../../gen/creators.js";
28
- import { ToDoListDocument } from "../../gen/types.js";
29
-
30
- describe("Todolist Operations", () => {
31
- let document: ToDoListDocument;
32
-
33
- beforeEach(() => {
34
- // REMARKS: We start with a fresh, empty document for each test.
35
- // The `createDocument` utility initializes the state with an empty 'items' array
36
- // and a 'stats' object with all counts set to 0.
37
- document = utils.createDocument();
38
- });
24
+ **Basic tests (matching Get Started):**
39
25
 
26
+ ```typescript
27
+ import { describe, it, expect } from "vitest";
28
+ import { generateMock } from "@powerhousedao/codegen";
29
+ import type {
30
+ AddTodoItemInput,
31
+ DeleteTodoItemInput,
32
+ UpdateTodoItemInput,
33
+ } from "todo-tutorial/document-models/todo-list";
34
+ import {
35
+ reducer,
36
+ utils,
37
+ isTodoListDocument,
38
+ addTodoItem,
39
+ AddTodoItemInputSchema,
40
+ updateTodoItem,
41
+ UpdateTodoItemInputSchema,
42
+ deleteTodoItem,
43
+ DeleteTodoItemInputSchema,
44
+ TodoItemSchema,
45
+ } from "todo-tutorial/document-models/todo-list";
46
+
47
+ describe("Todos Operations", () => {
40
48
  it("should handle addTodoItem operation", () => {
41
- const input = { id: "1", text: "Buy milk" };
49
+ const document = utils.createDocument();
50
+ const input: AddTodoItemInput = generateMock(AddTodoItemInputSchema());
42
51
 
43
- // REMARKS: We apply the 'addTodoItem' operation.
44
- const updatedDocument = reducer(document, creators.addTodoItem(input));
52
+ const updatedDocument = reducer(document, addTodoItem(input));
53
+ expect(isTodoListDocument(updatedDocument)).toBe(true);
45
54
 
46
- // REMARKS: We verify the operation was recorded in the document's history.
47
- // Powerhouse records every operation in an array.
55
+ // Verify the operation was recorded
48
56
  expect(updatedDocument.operations.global).toHaveLength(1);
49
- expect(updatedDocument.operations.global[0].type).toBe("ADD_TODO_ITEM");
50
- // REMARKS: We also check that the input data and index are recorded correctly.
51
- expect(updatedDocument.operations.global[0].input).toStrictEqual(input);
57
+ expect(updatedDocument.operations.global[0].action.type).toBe("ADD_TODO_ITEM");
58
+ expect(updatedDocument.operations.global[0].action.input).toStrictEqual(input);
52
59
  expect(updatedDocument.operations.global[0].index).toEqual(0);
60
+ });
61
+
62
+ it("should handle updateTodoItem operation to update text", () => {
63
+ const mockItem = generateMock(TodoItemSchema());
64
+ const input: UpdateTodoItemInput = generateMock(UpdateTodoItemInputSchema());
65
+ input.id = mockItem.id;
66
+ const newText = "new text";
67
+ input.text = newText;
68
+ input.checked = undefined;
69
+
70
+ const document = utils.createDocument({
71
+ global: {
72
+ items: [mockItem],
73
+ },
74
+ });
75
+
76
+ const updatedDocument = reducer(document, updateTodoItem(input));
77
+ expect(isTodoListDocument(updatedDocument)).toBe(true);
78
+
79
+ // Verify the operation was recorded
80
+ expect(updatedDocument.operations.global).toHaveLength(1);
81
+ expect(updatedDocument.operations.global[0].action.type).toBe("UPDATE_TODO_ITEM");
82
+
83
+ // Verify the state was updated correctly
84
+ const updatedItem = updatedDocument.state.global.items.find(
85
+ (item) => item.id === input.id,
86
+ );
87
+ expect(updatedItem?.text).toBe(newText);
88
+ expect(updatedItem?.checked).toBe(mockItem.checked);
89
+ });
90
+
91
+ it("should handle updateTodoItem operation to update checked", () => {
92
+ const mockItem = generateMock(TodoItemSchema());
93
+ const input: UpdateTodoItemInput = generateMock(UpdateTodoItemInputSchema());
94
+ input.id = mockItem.id;
95
+ const newChecked = !mockItem.checked;
96
+ input.checked = newChecked;
97
+ input.text = undefined;
98
+
99
+ const document = utils.createDocument({
100
+ global: {
101
+ items: [mockItem],
102
+ },
103
+ });
104
+
105
+ const updatedDocument = reducer(document, updateTodoItem(input));
106
+ expect(isTodoListDocument(updatedDocument)).toBe(true);
107
+
108
+ const updatedItem = updatedDocument.state.global.items.find(
109
+ (item) => item.id === input.id,
110
+ );
111
+ expect(updatedItem?.text).toBe(mockItem.text);
112
+ expect(updatedItem?.checked).toBe(newChecked);
113
+ });
114
+
115
+ it("should handle deleteTodoItem operation", () => {
116
+ const mockItem = generateMock(TodoItemSchema());
117
+ const document = utils.createDocument({
118
+ global: {
119
+ items: [mockItem],
120
+ },
121
+ });
122
+
123
+ const input: DeleteTodoItemInput = generateMock(DeleteTodoItemInputSchema());
124
+ input.id = mockItem.id;
125
+
126
+ const updatedDocument = reducer(document, deleteTodoItem(input));
127
+ expect(isTodoListDocument(updatedDocument)).toBe(true);
128
+
129
+ // Verify the operation was recorded
130
+ expect(updatedDocument.operations.global).toHaveLength(1);
131
+ expect(updatedDocument.operations.global[0].action.type).toBe("DELETE_TODO_ITEM");
132
+
133
+ // Verify the item was removed from state
134
+ const updatedItems = updatedDocument.state.global.items;
135
+ expect(updatedItems).toHaveLength(0);
136
+ });
137
+ });
138
+ ```
139
+
140
+ **Advanced tests (with stats verification):**
141
+
142
+ :::info Advanced Feature
143
+ If you implemented the advanced version with statistics tracking, add these additional tests to verify the stats are updated correctly.
144
+ :::
145
+
146
+ ```typescript
147
+ describe("Todos Operations with Stats", () => {
148
+ it("should update stats when adding a todo item", () => {
149
+ const document = utils.createDocument();
150
+ const input = { text: "Buy milk" };
151
+
152
+ const updatedDocument = reducer(document, addTodoItem(input));
53
153
 
54
- // REMARKS: Finally, we verify the state was updated according to our reducer logic.
55
154
  expect(updatedDocument.state.global.items).toHaveLength(1);
56
155
  expect(updatedDocument.state.global.stats.total).toBe(1);
57
156
  expect(updatedDocument.state.global.stats.unchecked).toBe(1);
157
+ expect(updatedDocument.state.global.stats.checked).toBe(0);
58
158
  });
59
159
 
60
- it("should handle updateTodoItem operation", () => {
61
- // REMARKS: For an update, we first need to add an item.
62
- const addInput = { id: "1", text: "Buy milk" };
63
- const updateInput = { id: "1", checked: true }; // We'll test checking the item.
64
-
65
- // REMARKS: Operations are applied sequentially to build up document state.
66
- const createdDocument = reducer(document, creators.addTodoItem(addInput));
160
+ it("should update stats when checking a todo item", () => {
161
+ const document = utils.createDocument();
162
+
163
+ // Add an item first
164
+ const addedDocument = reducer(document, addTodoItem({ text: "Buy milk" }));
165
+ const itemId = addedDocument.state.global.items[0].id;
166
+
167
+ // Now check it
67
168
  const updatedDocument = reducer(
68
- createdDocument,
69
- creators.updateTodoItem(updateInput),
169
+ addedDocument,
170
+ updateTodoItem({ id: itemId, checked: true })
70
171
  );
71
172
 
72
- // REMARKS: Now we should have 2 operations in the history.
73
- expect(updatedDocument.operations.global).toHaveLength(2);
74
- expect(updatedDocument.operations.global[1].type).toBe("UPDATE_TODO_ITEM");
75
- expect(updatedDocument.operations.global[1].input).toStrictEqual(
76
- updateInput,
77
- );
78
-
79
- // REMARKS: We check that the state reflects the update, including our stats.
80
- expect(updatedDocument.state.global.items[0].checked).toBe(true);
81
173
  expect(updatedDocument.state.global.stats.total).toBe(1);
82
174
  expect(updatedDocument.state.global.stats.unchecked).toBe(0);
83
175
  expect(updatedDocument.state.global.stats.checked).toBe(1);
84
176
  });
85
177
 
86
- it("should handle deleteTodoItem operation", () => {
87
- const addInput = { id: "1", text: "Buy milk" };
88
- const deleteInput = { id: "1" };
89
-
90
- const createdDocument = reducer(document, creators.addTodoItem(addInput));
178
+ it("should update stats when deleting an unchecked todo item", () => {
179
+ const document = utils.createDocument();
180
+
181
+ // Add an item
182
+ const addedDocument = reducer(document, addTodoItem({ text: "Buy milk" }));
183
+ const itemId = addedDocument.state.global.items[0].id;
184
+
185
+ // Delete it
91
186
  const updatedDocument = reducer(
92
- createdDocument,
93
- creators.deleteTodoItem(deleteInput),
187
+ addedDocument,
188
+ deleteTodoItem({ id: itemId })
94
189
  );
95
190
 
96
- // REMARKS: After deletion, we still have 2 operations in history,
97
- // but the items array is now empty and the stats are back to zero.
98
- expect(updatedDocument.operations.global).toHaveLength(2);
99
- expect(updatedDocument.operations.global[1].type).toBe("DELETE_TODO_ITEM");
100
191
  expect(updatedDocument.state.global.items).toHaveLength(0);
101
192
  expect(updatedDocument.state.global.stats.total).toBe(0);
102
193
  expect(updatedDocument.state.global.stats.unchecked).toBe(0);
194
+ expect(updatedDocument.state.global.stats.checked).toBe(0);
195
+ });
196
+
197
+ it("should update stats when deleting a checked todo item", () => {
198
+ const document = utils.createDocument();
199
+
200
+ // Add and check an item
201
+ const addedDocument = reducer(document, addTodoItem({ text: "Buy milk" }));
202
+ const itemId = addedDocument.state.global.items[0].id;
203
+ const checkedDocument = reducer(
204
+ addedDocument,
205
+ updateTodoItem({ id: itemId, checked: true })
206
+ );
207
+
208
+ // Delete it
209
+ const updatedDocument = reducer(
210
+ checkedDocument,
211
+ deleteTodoItem({ id: itemId })
212
+ );
213
+
214
+ expect(updatedDocument.state.global.items).toHaveLength(0);
215
+ expect(updatedDocument.state.global.stats.total).toBe(0);
216
+ expect(updatedDocument.state.global.stats.checked).toBe(0);
103
217
  });
104
218
  });
105
219
  ```
@@ -118,7 +232,7 @@ Or with npm:
118
232
  npm test
119
233
  ```
120
234
 
121
- If all tests pass, you have successfully verified the core logic of your `To-do List` document model. This ensures that the reducers you wrote behave exactly as expected.
235
+ If all tests pass, you have successfully verified the core logic of your `TodoList` document model. This ensures that the reducers you wrote behave exactly as expected.
122
236
 
123
237
  </details>
124
238
 
@@ -149,6 +263,6 @@ By following the tutorial and applying these best practices, you can build a str
149
263
 
150
264
  ## Up next
151
265
 
152
- In the next chapter of the Mastery Track - Building User Experiences you will learn how to implement an [editor](/academy/MasteryTrack/BuildingUserExperiences/BuildingDocumentEditors) for your document model so you can see a simple user interface for the **To-do List** document model in action.
266
+ In the next chapter of the Mastery Track - Building User Experiences you will learn how to implement an [editor](/academy/MasteryTrack/BuildingUserExperiences/BuildingDocumentEditors) for your document model so you can see a simple user interface for the **TodoList** document model in action.
153
267
 
154
- For a complete, working example, you can always have a look at the [Example To-do List Repository](/academy/MasteryTrack/DocumentModelCreation/ExampleToDoListRepository) which contains the full implementation of the concepts discussed in this Mastery Track.
268
+ For a complete, working example, you can always have a look at the [Example TodoList Repository](/academy/MasteryTrack/DocumentModelCreation/ExampleToDoListRepository) which contains the full implementation of the concepts discussed in this Mastery Track.
@@ -14,6 +14,13 @@ There are several ways to explore this package:
14
14
  The Todo-demo and repository are your main reference points during the Mastery Track.
15
15
  Follow the steps in the "Mastery Track – Document Model Creation" chapters to build along with the examples.
16
16
 
17
+ Key patterns used in the repository:
18
+ - **Naming convention**: `TodoList`, `TodoItem`, `TodoListState` (one word, PascalCase)
19
+ - **Document type**: `powerhouse/todo-list`
20
+ - **Module name**: `todos`
21
+ - **ID generation**: Uses `generateId()` from `document-model/core` in the reducer
22
+ - **Hooks**: Uses `useSelectedTodoListDocument` for state management in the editor
23
+
17
24
  ### Option 2: Clone and run the code locally
18
25
 
19
26
  The package includes:
@@ -27,6 +34,9 @@ The package includes:
27
34
  You can clone the repository and run Connect Studio to see all the code in action:
28
35
 
29
36
  ```bash
37
+ git clone https://github.com/powerhouse-inc/todo-demo
38
+ cd todo-demo
39
+ pnpm install
30
40
  ph connect
31
41
  ```
32
42
 
@@ -37,3 +47,14 @@ Alternatively, you can install this package in a Powerhouse project or in your d
37
47
  ```bash
38
48
  ph install @powerhousedao/todo-demo
39
49
  ```
50
+
51
+ ## Comparing Get Started vs Mastery Track
52
+
53
+ | Aspect | Get Started | Mastery Track (Advanced) |
54
+ |--------|-------------|--------------------------|
55
+ | Schema | Basic `items` array only | Includes `stats` object for tracking |
56
+ | Reducer complexity | Simple CRUD operations | Includes statistics updates |
57
+ | Editor | Component-based with hooks | Same approach + stats display |
58
+ | Tests | Basic operation tests | Includes stats verification tests |
59
+
60
+ Both approaches use the same naming conventions and patterns — the Mastery Track simply extends the foundation with additional features to demonstrate more advanced concepts.