@powerhousedao/academy 5.1.0-dev.4 → 5.1.0-dev.6
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/CHANGELOG.md +20 -0
- package/blog/BeyondCommunication-ABlueprintForDevelopment.md +2 -1
- package/blog/TheChallengeOfChange.md +1 -0
- package/docs/academy/01-GetStarted/00-ExploreDemoPackage.mdx +2 -2
- package/docs/academy/02-MasteryTrack/01-BuilderEnvironment/03-BuilderTools.md +2 -2
- package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/02-SpecifyTheStateSchema.md +75 -44
- package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/03-SpecifyDocumentOperations.md +28 -22
- package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/04-UseTheDocumentModelGenerator.md +28 -31
- package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/05-ImplementDocumentReducers.md +211 -206
- package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/06-ImplementDocumentModelTests.md +176 -62
- package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/07-ExampleToDoListRepository.md +21 -0
- package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/01-BuildingDocumentEditors.md +306 -319
- package/docs/academy/03-ExampleUsecases/VetraPackageLibrary/VetraPackageLibrary.md +7 -0
- package/docs/academy/03-ExampleUsecases/VetraPackageLibrary/_category_.json +9 -0
- package/docs/academy/04-APIReferences/renown-sdk/01-Authentication.md +1 -3
- package/docs/academy/04-APIReferences/renown-sdk/02-APIReference.md +1 -3
- package/docusaurus.config.ts +8 -3
- package/package.json +1 -1
- package/sidebars.ts +27 -9
- package/src/css/custom.css +0 -19
- package/static/img/Vetra-logo-dark.svg +11 -0
- package/static/img/vetra-logo-light.svg +11 -0
- package/docs/academy/00-EthereumArgentinaHackathon.md +0 -207
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
## 5.1.0-dev.6 (2025-12-04)
|
|
2
|
+
|
|
3
|
+
### 🩹 Fixes
|
|
4
|
+
|
|
5
|
+
- **renown:** build issues ([1893c35a0](https://github.com/powerhouse-inc/powerhouse/commit/1893c35a0))
|
|
6
|
+
|
|
7
|
+
### ❤️ Thank You
|
|
8
|
+
|
|
9
|
+
- Frank
|
|
10
|
+
|
|
11
|
+
## 5.1.0-dev.5 (2025-12-04)
|
|
12
|
+
|
|
13
|
+
### 🚀 Features
|
|
14
|
+
|
|
15
|
+
- connect crypto signer and verifier ([918fb1fab](https://github.com/powerhouse-inc/powerhouse/commit/918fb1fab))
|
|
16
|
+
|
|
17
|
+
### ❤️ Thank You
|
|
18
|
+
|
|
19
|
+
- Benjamin Jordan (@thegoldenmule)
|
|
20
|
+
|
|
1
21
|
## 5.1.0-dev.4 (2025-12-03)
|
|
2
22
|
|
|
3
23
|
### 🚀 Features
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Beyond Communication - A Blueprint for Development
|
|
3
|
-
description: GraphQL Schema
|
|
3
|
+
description: GraphQL Schema's as a common language for software design
|
|
4
4
|
slug: Graphql-schema-as-a-common-language
|
|
5
|
+
date: 2024-12-02
|
|
5
6
|
authors:
|
|
6
7
|
- name: Call me T.
|
|
7
8
|
title: Product Manager at Powerhouse
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## Let's get started
|
|
4
4
|
|
|
5
|
-
To give you a quick idea of how the Powerhouse
|
|
5
|
+
To give you a quick idea of how the Powerhouse Vetra builder platform operates on document models and packages, why don't you try installing a package?
|
|
6
6
|
We will show you how to install the Powerhouse command-line tool `ph-cmd` and then use it to install a pre-built demo package containing a document model, an editor, and a drive app.
|
|
7
7
|
|
|
8
8
|
## Step 1: Install the Powerhouse CLI
|
|
9
9
|
|
|
10
10
|
You will use the Powerhouse CLI to launch a local environment with a "To-do List Demo Package" installed.
|
|
11
|
-
This is also the package that you'll recreate during the tutorials and gets you familiar with Powerhouse.
|
|
11
|
+
This is also the package that you'll recreate during the tutorials and gets you familiar with Powerhouse Vetra.
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
14
|
pnpm install -g ph-cmd
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Vetra builder tooling
|
|
2
2
|
|
|
3
|
-
This page provides an overview of all the builder tooling offered
|
|
3
|
+
This page provides an overview of all the builder tooling offered in the Vetra ecosystem by Powerhouse.
|
|
4
4
|
This list will be maintained and updated as our toolkit grows.
|
|
5
5
|
|
|
6
6
|
## Powerhouse command line interface
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
# Specify the state schema
|
|
2
2
|
|
|
3
|
-
The state schema is the backbone of your document model. It defines the structure, data types, and relationships of the information your document will hold. In Powerhouse, we use the GraphQL Schema Definition Language (SDL) to define this schema. A well-defined state schema is crucial for ensuring data integrity, consistency, and for enabling powerful querying and manipulation capabilities.
|
|
3
|
+
The state schema is the backbone of your document model. It defines the structure, data types, and relationships of the information your document will hold. In Powerhouse, we use the **GraphQL Schema Definition Language (SDL)** to define this schema. A well-defined state schema is crucial for ensuring data integrity, consistency, and for enabling powerful querying and manipulation capabilities.
|
|
4
4
|
|
|
5
5
|
## Core concepts
|
|
6
6
|
|
|
7
7
|
### Types
|
|
8
8
|
|
|
9
|
-
At the heart of GraphQL SDL are **types**. Types define the shape of your data. You can define custom object types that represent the entities in your document. For example, in a `
|
|
9
|
+
At the heart of GraphQL SDL are **types**. Types define the shape of your data. You can define custom object types that represent the entities in your document. For example, in a `TodoList` document, you might have a `TodoListState` type and a `TodoItem` type.
|
|
10
10
|
|
|
11
|
-
- **`
|
|
12
|
-
- **`
|
|
11
|
+
- **`TodoListState`**: This could be the root type representing the overall state of the to-do list. It might contain a list of `TodoItem` objects.
|
|
12
|
+
- **`TodoItem`**: This type would represent an individual to-do item, with properties like an `id`, `text` (the task description), and `checked` (a boolean indicating if the task is completed).
|
|
13
13
|
|
|
14
14
|
### Fields
|
|
15
15
|
|
|
16
|
-
Each type has **fields**, which represent the properties of that type. Each field has a name and a type. For instance, the `
|
|
16
|
+
Each type has **fields**, which represent the properties of that type. Each field has a name and a type. For instance, the `TodoItem` type would have an `id` field of type `OID!`, a `text` field of type `String!`, and a `checked` field of type `Boolean!`.
|
|
17
17
|
|
|
18
18
|
### Scalars
|
|
19
19
|
|
|
@@ -27,32 +27,61 @@ GraphQL has a set of built-in **scalar types**:
|
|
|
27
27
|
|
|
28
28
|
In addition to these standard types, the Powerhouse Document-Engineering system introduces custom scalars that are linked to reusable front-end components. These scalars are tailored for the web3 ecosystem and will be explored in the Component Library section of the documentation.
|
|
29
29
|
|
|
30
|
+
:::tip Custom Scalar: OID
|
|
31
|
+
Powerhouse provides the `OID` (Object ID) scalar type, which is a custom scalar specifically designed for unique identifiers in document models. It provides automatic ID generation capabilities when used with the `generateId()` function from the document-model core library.
|
|
32
|
+
:::
|
|
33
|
+
|
|
30
34
|
### Lists and non-null
|
|
31
35
|
|
|
32
36
|
You can modify types using lists and non-null indicators:
|
|
33
37
|
|
|
34
|
-
- **Lists**: To indicate that a field will return a list of a certain type, you wrap the type in square brackets, e.g., `[
|
|
35
|
-
- **Non-Null**: To indicate that a field cannot be null, you add an exclamation mark `!` after the type name, e.g., `String!`. This means that the `text` field of a `
|
|
38
|
+
- **Lists**: To indicate that a field will return a list of a certain type, you wrap the type in square brackets, e.g., `[TodoItem!]!`. This means the field `items` in `TodoListState` will be a list of `TodoItem` objects.
|
|
39
|
+
- **Non-Null**: To indicate that a field cannot be null, you add an exclamation mark `!` after the type name, e.g., `String!`. This means that the `text` field of a `TodoItem` must always have a value. The outer `!` in `[TodoItem!]!` means the list itself cannot be null (it must be at least an empty list), and the inner `!` on `TodoItem!` means that every item within that list must also be non-null.
|
|
40
|
+
|
|
41
|
+
## Example: TodoList state schema
|
|
36
42
|
|
|
37
|
-
|
|
43
|
+
Let's revisit the `TodoList` example from the "Define the TodoList document specification" tutorial in Get Started.
|
|
38
44
|
|
|
39
|
-
|
|
40
|
-
|
|
45
|
+
### Basic schema (matching Get Started tutorial)
|
|
46
|
+
|
|
47
|
+
This is the same schema you built in the Get Started tutorial:
|
|
41
48
|
|
|
42
49
|
```graphql
|
|
43
|
-
# The state of our
|
|
44
|
-
type
|
|
45
|
-
items: [
|
|
50
|
+
# The state of our TodoList
|
|
51
|
+
type TodoListState {
|
|
52
|
+
items: [TodoItem!]!
|
|
46
53
|
}
|
|
47
54
|
|
|
48
55
|
# A single to-do item
|
|
49
|
-
type
|
|
50
|
-
id:
|
|
56
|
+
type TodoItem {
|
|
57
|
+
id: OID!
|
|
51
58
|
text: String!
|
|
52
59
|
checked: Boolean!
|
|
53
60
|
}
|
|
54
|
-
|
|
55
|
-
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Advanced schema (with statistics tracking)
|
|
64
|
+
|
|
65
|
+
:::info Advanced Feature
|
|
66
|
+
In this Mastery Track, we'll extend the basic schema with a `stats` field to demonstrate how you can add computed statistics to your document model. This is an **optional enhancement** that builds on the foundation from Get Started.
|
|
67
|
+
:::
|
|
68
|
+
|
|
69
|
+
```graphql
|
|
70
|
+
# The state of our TodoList (advanced version with stats)
|
|
71
|
+
type TodoListState {
|
|
72
|
+
items: [TodoItem!]!
|
|
73
|
+
stats: TodoListStats!
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
# A single to-do item
|
|
77
|
+
type TodoItem {
|
|
78
|
+
id: OID!
|
|
79
|
+
text: String!
|
|
80
|
+
checked: Boolean!
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
# The statistics on our to-do's (advanced feature)
|
|
84
|
+
type TodoListStats {
|
|
56
85
|
total: Int!
|
|
57
86
|
checked: Int!
|
|
58
87
|
unchecked: Int!
|
|
@@ -61,18 +90,19 @@ type ToDoListStats {
|
|
|
61
90
|
|
|
62
91
|
### Breakdown:
|
|
63
92
|
|
|
64
|
-
- **`
|
|
65
|
-
- `items: [
|
|
66
|
-
- `[
|
|
67
|
-
- `
|
|
68
|
-
- The final `!` after `[
|
|
93
|
+
- **`TodoListState` type**:
|
|
94
|
+
- `items: [TodoItem!]!`: This field defines that our `TodoListState` contains a list called `items`.
|
|
95
|
+
- `[TodoItem!]`: This signifies that `items` is a list of `TodoItem` objects.
|
|
96
|
+
- `TodoItem!`: The `!` after `TodoItem` means that no item in the list can be null. Each entry must be a valid `TodoItem`.
|
|
97
|
+
- The final `!` after `[TodoItem!]` means that the `items` list itself cannot be null. It can be an empty list `[]`, but it cannot be absent.
|
|
98
|
+
- `stats: TodoListStats!` *(advanced)*: Holds aggregated statistics about the to-do items.
|
|
69
99
|
|
|
70
|
-
- **`
|
|
71
|
-
- `id:
|
|
100
|
+
- **`TodoItem` type**:
|
|
101
|
+
- `id: OID!`: Each `TodoItem` has a unique identifier using Powerhouse's custom `OID` scalar. This is crucial for referencing specific items, for example, when updating or deleting them.
|
|
72
102
|
- `text: String!`: The textual description of the to-do item. It cannot be null, ensuring every to-do has a description.
|
|
73
103
|
- `checked: Boolean!`: Indicates whether the to-do item is completed. It defaults to a boolean value (true or false) and cannot be null.
|
|
74
104
|
|
|
75
|
-
- **`
|
|
105
|
+
- **`TodoListStats` type** *(advanced)*: This type holds the summary statistics for the to-do list.
|
|
76
106
|
- `total: Int!`: The total count of all to-do items. This field must be an integer and cannot be null.
|
|
77
107
|
- `checked: Int!`: The number of to-do items that are marked as completed. This must be an integer and cannot be null.
|
|
78
108
|
- `unchecked: Int!`: The number of to-do items that are still pending. This also must be an integer and cannot be null.
|
|
@@ -83,17 +113,17 @@ type ToDoListStats {
|
|
|
83
113
|
2. **Clarity and Explicitness**: Name your types and fields clearly and descriptively. This makes the schema easier to understand and maintain.
|
|
84
114
|
3. **Use Non-Null Wisely**: Enforce data integrity by using non-null (`!`) for fields that must always have a value. However, be mindful not to over-constrain if a field can genuinely be optional.
|
|
85
115
|
4. **Normalize vs. Denormalize**:
|
|
86
|
-
- **Normalization**: Similar to relational databases, you can normalize your data by having distinct types and linking them via IDs. This can reduce data redundancy. For example, if you had `User` and `
|
|
87
|
-
- **Denormalization**: Sometimes, for performance or simplicity, you might embed data directly. For instance, if user information associated with a to-do item was very simple and only used in that context, you might embed user fields directly in `
|
|
116
|
+
- **Normalization**: Similar to relational databases, you can normalize your data by having distinct types and linking them via IDs. This can reduce data redundancy. For example, if you had `User` and `TodoItem` and wanted to assign tasks, you might have an `assigneeId` field in `TodoItem` that links to a `User`'s `id`.
|
|
117
|
+
- **Denormalization**: Sometimes, for performance or simplicity, you might embed data directly. For instance, if user information associated with a to-do item was very simple and only used in that context, you might embed user fields directly in `TodoItem`.
|
|
88
118
|
- The choice depends on your specific use case, query patterns, and how data is updated.
|
|
89
|
-
5. **Consider Future Needs**: While you shouldn't over-engineer, think a little about potential future enhancements. For example, adding a `createdAt: String` or `dueDate: String` field to `
|
|
90
|
-
6. **Root State Type**: It's a common pattern to have a single root type for your document state (e.g., `
|
|
119
|
+
5. **Consider Future Needs**: While you shouldn't over-engineer, think a little about potential future enhancements. For example, adding a `createdAt: String` or `dueDate: String` field to `TodoItem` might be useful later.
|
|
120
|
+
6. **Root State Type**: It's a common pattern to have a single root type for your document state (e.g., `TodoListState`). This provides a clear entry point for accessing all document data.
|
|
91
121
|
|
|
92
122
|
By carefully defining your state schema, you lay a solid foundation for your Powerhouse document model, making it robust, maintainable, and easy to work with. The schema dictates not only how data is stored but also how it can be queried and mutated through operations, which will be covered in the next section.
|
|
93
123
|
|
|
94
124
|
## Practical implementation: defining the state schema in Connect
|
|
95
125
|
|
|
96
|
-
Now that you understand the concepts behind the state schema, let's put it into practice. This section will guide you through creating a document model specification for the
|
|
126
|
+
Now that you understand the concepts behind the state schema, let's put it into practice. This section will guide you through creating a document model specification for the TodoList example discussed above.
|
|
97
127
|
|
|
98
128
|
<details>
|
|
99
129
|
<summary>Tutorial: The state schema specification</summary>
|
|
@@ -110,28 +140,29 @@ Now that you understand the concepts behind the state schema, let's put it into
|
|
|
110
140
|
- At the bottom of the page in the 'New Document' section, click the `DocumentModel` button to create a new document model specification.
|
|
111
141
|
|
|
112
142
|
2. **Define Document Metadata**:
|
|
113
|
-
- **Name**: Give your document model a descriptive name
|
|
114
|
-
- **Document Type**: In the 'Document Type' field, enter a unique identifier for this document type: `powerhouse/
|
|
143
|
+
- **Name**: Give your document model a descriptive name: `TodoList`. **Pay close attention to capitalization, as it influences our code generation.**
|
|
144
|
+
- **Document Type**: In the 'Document Type' field, enter a unique identifier for this document type: `powerhouse/todo-list`.
|
|
115
145
|
|
|
116
146
|
3. **Specify the State Schema**:
|
|
117
147
|
- In the code editor provided, you'll see a template for a GraphQL schema.
|
|
118
|
-
- Replace the entire content of the editor with the advanced `
|
|
148
|
+
- Replace the entire content of the editor with the advanced `TodoList` schema we've designed in this chapter:
|
|
119
149
|
|
|
120
150
|
```graphql
|
|
121
|
-
# The state of our
|
|
122
|
-
type
|
|
123
|
-
items: [
|
|
124
|
-
stats:
|
|
151
|
+
# The state of our TodoList (advanced version with stats)
|
|
152
|
+
type TodoListState {
|
|
153
|
+
items: [TodoItem!]!
|
|
154
|
+
stats: TodoListStats!
|
|
125
155
|
}
|
|
126
156
|
|
|
127
157
|
# A single to-do item
|
|
128
|
-
type
|
|
129
|
-
id:
|
|
158
|
+
type TodoItem {
|
|
159
|
+
id: OID!
|
|
130
160
|
text: String!
|
|
131
161
|
checked: Boolean!
|
|
132
162
|
}
|
|
133
|
-
|
|
134
|
-
|
|
163
|
+
|
|
164
|
+
# The statistics on our to-do's (advanced feature)
|
|
165
|
+
type TodoListStats {
|
|
135
166
|
total: Int!
|
|
136
167
|
checked: Int!
|
|
137
168
|
unchecked: Int!
|
|
@@ -140,12 +171,12 @@ Now that you understand the concepts behind the state schema, let's put it into
|
|
|
140
171
|
|
|
141
172
|
4. **Sync Schema and View Initial State**:
|
|
142
173
|
- After pasting the schema, click the **'Sync with schema'** button.
|
|
143
|
-
- This action processes your schema and generates an initial JSON state for your document model based on the `
|
|
174
|
+
- This action processes your schema and generates an initial JSON state for your document model based on the `TodoListState` type. You can view this initial state, which helps you verify that your schema is structured correctly.
|
|
144
175
|
|
|
145
176
|
For now, you can ignore the "Modules & Operations" section. We will define and implement the operations that modify this state in the upcoming sections of this Mastery Track.
|
|
146
177
|
|
|
147
|
-
By completing these steps, you have successfully specified the data structure for the advanced
|
|
178
|
+
By completing these steps, you have successfully specified the data structure for the advanced TodoList document model. The next step is to define the operations that will allow users to interact with and change this state.
|
|
148
179
|
|
|
149
180
|
</details>
|
|
150
181
|
|
|
151
|
-
For a complete, working example, you can always have a look at the [Example
|
|
182
|
+
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.
|
package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/03-SpecifyDocumentOperations.md
CHANGED
|
@@ -6,7 +6,7 @@ In the previous section, we defined the state schema for our document model. Now
|
|
|
6
6
|
|
|
7
7
|
In Powerhouse, document models adhere to event sourcing principles. This means that every change to a document's state is the result of a sequence of operations (or events). Instead of directly mutating the state, you define specific, named operations that describe the intended change.
|
|
8
8
|
|
|
9
|
-
For example, in our `
|
|
9
|
+
For example, in our `TodoList` document model, operations might include:
|
|
10
10
|
|
|
11
11
|
- `ADD_TODO_ITEM`: To add a new task.
|
|
12
12
|
- `UPDATE_TODO_ITEM`: To modify an existing task (e.g., change its text or mark it as completed).
|
|
@@ -16,35 +16,38 @@ Each operation acts as a command that, when applied, transitions the document fr
|
|
|
16
16
|
|
|
17
17
|
## Connecting operations to the schema
|
|
18
18
|
|
|
19
|
-
In the "Define
|
|
19
|
+
In the "Define TodoList Document Model" chapter in the "Get Started" guide, we used GraphQL `input` types to define the structure of the data required for each operation. Let's revisit that:
|
|
20
20
|
|
|
21
21
|
```graphql
|
|
22
22
|
# Defines a GraphQL input type for adding a new to-do item
|
|
23
23
|
input AddTodoItemInput {
|
|
24
|
-
id: ID!
|
|
25
24
|
text: String!
|
|
26
25
|
}
|
|
27
26
|
|
|
28
27
|
# Defines a GraphQL input type for updating a to-do item
|
|
29
28
|
input UpdateTodoItemInput {
|
|
30
|
-
id:
|
|
29
|
+
id: OID!
|
|
31
30
|
text: String
|
|
32
31
|
checked: Boolean
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
# Defines a GraphQL input type for deleting a to-do item
|
|
36
35
|
input DeleteTodoItemInput {
|
|
37
|
-
id:
|
|
36
|
+
id: OID!
|
|
38
37
|
}
|
|
39
38
|
```
|
|
40
39
|
|
|
41
40
|
These `input` types are not just abstract definitions; they are the **specifications for our document operations**.
|
|
42
41
|
|
|
43
|
-
- **`AddTodoItemInput`** specifies that to execute an `ADD_TODO_ITEM` operation, we need
|
|
42
|
+
- **`AddTodoItemInput`** specifies that to execute an `ADD_TODO_ITEM` operation, we only need the `text` for the new item. The `id` is automatically generated by the reducer using Powerhouse's `generateId()` function.
|
|
44
43
|
- **`UpdateTodoItemInput`** specifies that for an `UPDATE_TODO_ITEM` operation, we need the `id` of the item to update, and optionally new `text` or a `checked` status.
|
|
45
44
|
- **`DeleteTodoItemInput`** specifies that a `DELETE_TODO_ITEM` operation requires the `id` of the item to be removed.
|
|
46
45
|
|
|
47
|
-
|
|
46
|
+
:::tip ID Generation
|
|
47
|
+
Notice that `AddTodoItemInput` only requires `text` — not an `id`. This is because the ID is generated automatically in the reducer using `generateId()` from `document-model/core`. This ensures unique, consistent IDs and follows the pattern used in the [todo-demo repository](https://github.com/powerhouse-inc/todo-demo).
|
|
48
|
+
:::
|
|
49
|
+
|
|
50
|
+
The Powerhouse Connect application uses these GraphQL input types when you define operations within a module (e.g., the `todos` module with operations `ADD_TODO_ITEM`, `UPDATE_TODO_ITEM`, `DELETE_TODO_ITEM`).
|
|
48
51
|
|
|
49
52
|
## Designing effective document operations
|
|
50
53
|
|
|
@@ -56,7 +59,7 @@ Operations should be granular enough to represent distinct user intentions or lo
|
|
|
56
59
|
|
|
57
60
|
- **Too coarse:** An operation like `MODIFY_TODOLIST` that takes a whole new list of items would be too broad. It would be hard to track specific changes and could lead to complex reducer logic.
|
|
58
61
|
- **Too fine:** While possible, having separate operations like `SET_TODO_ITEM_TEXT` and `SET_TODO_ITEM_CHECKED_STATUS` might be overly verbose if these are often updated together. `UPDATE_TODO_ITEM` with optional fields offers a good balance.
|
|
59
|
-
- **Just right:** The `ADD_TODO_ITEM`, `UPDATE_TODO_ITEM`, and `DELETE_TODO_ITEM` operations for our `
|
|
62
|
+
- **Just right:** The `ADD_TODO_ITEM`, `UPDATE_TODO_ITEM`, and `DELETE_TODO_ITEM` operations for our `TodoList` are good examples. They represent clear, atomic changes.
|
|
60
63
|
|
|
61
64
|
### 2. Naming conventions
|
|
62
65
|
|
|
@@ -90,25 +93,25 @@ While not specified in the operation definition itself, remember that the _imple
|
|
|
90
93
|
|
|
91
94
|
Specifying your document operations is the bridge between defining your data structure (the state schema) and implementing the logic that changes that data (the reducers).
|
|
92
95
|
|
|
93
|
-
1. **You define the state schema** (e.g., `
|
|
96
|
+
1. **You define the state schema** (e.g., `TodoListState`, `TodoItem`).
|
|
94
97
|
2. **You specify the operations** that can alter this state, along with their required input data (e.g., `ADD_TODO_ITEM` with `AddTodoItemInput`).
|
|
95
98
|
3. **Next, you will implement reducers** for each specified operation. Each reducer will take the current state and an operation's input, and produce a new state.
|
|
96
99
|
|
|
97
100
|
The generated code from `ph generate` (as seen in `03-ImplementOperationReducers.md`) will create a structure for your reducers based on the operations you specified in the Connect application (which, in turn, were based on your GraphQL input types).
|
|
98
101
|
|
|
99
|
-
For example, the `
|
|
102
|
+
For example, the `TodoListTodosOperations` type generated by Powerhouse will expect methods corresponding to `addTodoItemOperation`, `updateTodoItemOperation`, and `deleteTodoItemOperation`.
|
|
100
103
|
|
|
101
104
|
```typescript
|
|
102
|
-
import {
|
|
105
|
+
import type { TodoListTodosOperations } from "../../gen/todos/operations.js";
|
|
103
106
|
|
|
104
|
-
export const
|
|
105
|
-
addTodoItemOperation(state, action
|
|
107
|
+
export const todoListTodosOperations: TodoListTodosOperations = {
|
|
108
|
+
addTodoItemOperation(state, action) {
|
|
106
109
|
// Implementation uses action.input which matches AddTodoItemInput
|
|
107
110
|
},
|
|
108
|
-
updateTodoItemOperation(state, action
|
|
111
|
+
updateTodoItemOperation(state, action) {
|
|
109
112
|
// Implementation uses action.input which matches UpdateTodoItemInput
|
|
110
113
|
},
|
|
111
|
-
deleteTodoItemOperation(state, action
|
|
114
|
+
deleteTodoItemOperation(state, action) {
|
|
112
115
|
// Implementation uses action.input which matches DeleteTodoItemInput
|
|
113
116
|
},
|
|
114
117
|
};
|
|
@@ -116,16 +119,16 @@ export const reducer: ToDoListToDoListOperations = {
|
|
|
116
119
|
|
|
117
120
|
## Practical implementation: Defining operations in Connect
|
|
118
121
|
|
|
119
|
-
Now that you understand the theory, let's walk through the practical steps of defining these operations for our `
|
|
122
|
+
Now that you understand the theory, let's walk through the practical steps of defining these operations for our `TodoList` document model within the Powerhouse Connect application.
|
|
120
123
|
|
|
121
124
|
<details>
|
|
122
|
-
<summary>Tutorial: Specifying
|
|
125
|
+
<summary>Tutorial: Specifying TodoList operations</summary>
|
|
123
126
|
|
|
124
|
-
Assuming you have already defined the state schema for the `
|
|
127
|
+
Assuming you have already defined the state schema for the `TodoList` as covered in the previous section, follow these steps to add the operations:
|
|
125
128
|
|
|
126
129
|
1. **Create a Module for Operations:**
|
|
127
130
|
Below the schema editor in Connect, find the input field labeled `Add module`. Modules help organize your operations.
|
|
128
|
-
- Type `
|
|
131
|
+
- Type `todos` into the field and press Enter.
|
|
129
132
|
|
|
130
133
|
2. **Add the `ADD_TODO_ITEM` Operation:**
|
|
131
134
|
A new field, `Add operation`, will appear under your new module.
|
|
@@ -135,11 +138,14 @@ Assuming you have already defined the state schema for the `To-do List` as cover
|
|
|
135
138
|
```graphql
|
|
136
139
|
# Defines a GraphQL input type for adding a new to-do item
|
|
137
140
|
input AddTodoItemInput {
|
|
138
|
-
id: ID!
|
|
139
141
|
text: String!
|
|
140
142
|
}
|
|
141
143
|
```
|
|
142
144
|
|
|
145
|
+
:::info
|
|
146
|
+
Notice we don't include `id` in the input — the reducer will generate it automatically using `generateId()` from `document-model/core`.
|
|
147
|
+
:::
|
|
148
|
+
|
|
143
149
|
3. **Add the `UPDATE_TODO_ITEM` Operation:**
|
|
144
150
|
- In the `Add operation` field again, type `UPDATE_TODO_ITEM` and press Enter.
|
|
145
151
|
- Paste the corresponding `input` definition into its editor:
|
|
@@ -147,7 +153,7 @@ Assuming you have already defined the state schema for the `To-do List` as cover
|
|
|
147
153
|
```graphql
|
|
148
154
|
# Defines a GraphQL input type for updating a to-do item
|
|
149
155
|
input UpdateTodoItemInput {
|
|
150
|
-
id:
|
|
156
|
+
id: OID!
|
|
151
157
|
text: String
|
|
152
158
|
checked: Boolean
|
|
153
159
|
}
|
|
@@ -160,7 +166,7 @@ Assuming you have already defined the state schema for the `To-do List` as cover
|
|
|
160
166
|
```graphql
|
|
161
167
|
# Defines a GraphQL input type for deleting a to-do item
|
|
162
168
|
input DeleteTodoItemInput {
|
|
163
|
-
id:
|
|
169
|
+
id: OID!
|
|
164
170
|
}
|
|
165
171
|
```
|
|
166
172
|
|
package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/04-UseTheDocumentModelGenerator.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Use the document model generator
|
|
2
2
|
|
|
3
|
-
In the Powerhouse Document Model development workflow, after specifying your document model's state schema and operations within the Connect application and exporting it as a `.
|
|
3
|
+
In the Powerhouse Document Model development workflow, after specifying your document model's state schema and operations within the Connect application and exporting it as a `.phd` file, the next crucial step is to translate this specification into a tangible codebase. This is where the Powerhouse Document Model Generator comes into play.
|
|
4
4
|
|
|
5
|
-
The Document Model Generator is a powerful command-line tool (`ph generate`) that processes your exported `.
|
|
5
|
+
The Document Model Generator is a powerful command-line tool (`ph generate`) that processes your exported `.phd` file and scaffolds the necessary directory structure and foundational code for your document model. It automates the creation of boilerplate code, ensuring consistency, type safety, and adherence to Powerhouse conventions, thereby significantly accelerating the development process.
|
|
6
6
|
|
|
7
7
|
This document provides a deep dive into using the Document Model Generator, understanding its output, and appreciating its role in the broader context of document model creation.
|
|
8
8
|
|
|
@@ -11,20 +11,20 @@ This document provides a deep dive into using the Document Model Generator, unde
|
|
|
11
11
|
Before you can use the Document Model Generator, ensure you have the following:
|
|
12
12
|
|
|
13
13
|
1. **Powerhouse CLI (`ph-cmd`) Installed:** The generator is part of the Powerhouse CLI. If you haven't installed it, refer to the [Builder Tools documentation](/academy/MasteryTrack/BuilderEnvironment/BuilderTools#installing-the-powerhouse-cli).
|
|
14
|
-
2. **Document Model Specification File (`.
|
|
14
|
+
2. **Document Model Specification File (`.phd`):** You must have already defined your document model in Connect and exported it. This file (e.g., `TodoList.phd`) contains the GraphQL schema for your document's state and operations. This process is typically covered in a preceding step, such as "Define TodoList Document Model."
|
|
15
15
|
|
|
16
16
|
## The command
|
|
17
17
|
|
|
18
18
|
The core command to invoke the Document Model Generator is:
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
ph generate <YourModelName.
|
|
21
|
+
ph generate <YourModelName.phd>
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
Replace `<YourModelName.
|
|
24
|
+
Replace `<YourModelName.phd>` with the actual filename of your exported document model specification. For instance, if your exported file is named `TodoList.phd`, the command would be:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
ph generate
|
|
27
|
+
ph generate TodoList.phd
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
When executed, this command reads and parses the specification file and generates a set of files and directories within your Powerhouse project.
|
|
@@ -34,12 +34,12 @@ When executed, this command reads and parses the specification file and generate
|
|
|
34
34
|
Running `ph generate` triggers a series of actions that lay the groundwork for your document model's implementation. Let's explore the typical output structure and the significance of each generated component.
|
|
35
35
|
|
|
36
36
|
The generator creates a new directory specific to your document model, usually located at:
|
|
37
|
-
`document-models/<
|
|
37
|
+
`document-models/<your-model-name>/`
|
|
38
38
|
|
|
39
|
-
For example, using `
|
|
39
|
+
For example, using `TodoList.phd` would result in a directory structure under `document-models/todo-list/`. Inside this directory, you will find:
|
|
40
40
|
|
|
41
|
-
1. **`
|
|
42
|
-
- **Purpose:** This file is a JSON representation of your document model specification, derived directly from the `.
|
|
41
|
+
1. **`todo-list.json` (or similar JSON representation):**
|
|
42
|
+
- **Purpose:** This file is a JSON representation of your document model specification, derived directly from the `.phd` file. It contains the parsed schema, operation definitions, document type, and other metadata.
|
|
43
43
|
- **Significance:** It serves as the canonical, machine-readable definition of your model within the project, which other tools or processes might reference.
|
|
44
44
|
|
|
45
45
|
2. **`schema.graphql`:**
|
|
@@ -50,12 +50,12 @@ For example, using `Invoice.phdm.zip` would result in a directory structure unde
|
|
|
50
50
|
This directory is pivotal as it houses all the code automatically generated by the tool. **You should generally avoid manually editing files within the `gen/` directory**, as they will be overwritten if you regenerate the model.
|
|
51
51
|
Key files within `gen/` include:
|
|
52
52
|
- **`types.ts`:**
|
|
53
|
-
- **Purpose:** Contains TypeScript interfaces and type definitions derived from your GraphQL schema. This includes types for your document's state (e.g., `
|
|
53
|
+
- **Purpose:** Contains TypeScript interfaces and type definitions derived from your GraphQL schema. This includes types for your document's state (e.g., `TodoListState`), any complex types used within the state (e.g., `TodoItem`), and types for the inputs of each defined operation (e.g., `AddTodoItemInput`).
|
|
54
54
|
- **Significance:** This is the cornerstone of type safety in your document model implementation. By using these generated types, you ensure that your reducer logic and any client-side interactions adhere to the defined data structures, catching errors at compile-time rather than runtime.
|
|
55
55
|
|
|
56
|
-
- **`
|
|
56
|
+
- **`creators.ts` (or `actions.ts`):**
|
|
57
57
|
- **Purpose:** This file exports "action creator" functions for each operation defined in your schema. These functions take the input parameters for an operation and return a correctly structured action object that can be processed by the reducer system.
|
|
58
|
-
- **Significance:** Action creators simplify the process of creating and dispatching operations, reduce the likelihood of errors in action formatting, and improve code readability. For example, instead of manually constructing an action object like `{ type: "
|
|
58
|
+
- **Significance:** Action creators simplify the process of creating and dispatching operations, reduce the likelihood of errors in action formatting, and improve code readability. For example, instead of manually constructing an action object like `{ type: "ADD_TODO_ITEM", input: { ... } }`, you'd use a function like `addTodoItem({ text: 'Buy groceries' })`.
|
|
59
59
|
|
|
60
60
|
- **`utils.ts`:**
|
|
61
61
|
- **Purpose:** Often includes utility functions related to your document model. A common utility is a function to create an empty or initial instance of your document (e.g., `utils.createDocument()`). This is based on the default values and structure defined in your state schema.
|
|
@@ -68,14 +68,11 @@ For example, using `Invoice.phdm.zip` would result in a directory structure unde
|
|
|
68
68
|
4. **The `src/` Directory (Source Code for Your Implementation):**
|
|
69
69
|
This directory is where you, the developer, will write the custom logic for your document model. Unlike the `gen/` directory, files here are meant to be manually edited.
|
|
70
70
|
- **`reducers/`:**
|
|
71
|
-
- **`
|
|
71
|
+
- **`todos.ts`:** This is the most important file you'll work with after generation. It's where you implement the **reducer functions** for each operation. The generator usually creates a skeleton file with function stubs for each operation, which you then fill in with the actual state transition logic.
|
|
72
72
|
- **Significance:** This is the heart of your document model's behavior, defining how the state changes in response to each operation. The next step in the Mastery Track will typically focus on implementing these reducers.
|
|
73
|
-
- **`
|
|
74
|
-
- **`
|
|
73
|
+
- **`tests/`:**
|
|
74
|
+
- **`todos.test.ts`:** A placeholder or basic test file is often generated here, encouraging you to write unit tests for your reducer logic.
|
|
75
75
|
- **Significance:** Emphasizes the importance of testing your document model's core logic to ensure correctness and reliability.
|
|
76
|
-
- **`utils/` (optional):**
|
|
77
|
-
- **Purpose:** You can create this directory for any custom utility functions specific to your document model's implementation that don't fit directly into the reducers.
|
|
78
|
-
- **Significance:** Helps in organizing shared logic or complex computations that might be used across multiple reducers or other parts of your model's ecosystem.
|
|
79
76
|
|
|
80
77
|
## Benefits of using the document model generator
|
|
81
78
|
|
|
@@ -88,39 +85,39 @@ Leveraging the `ph generate` command offers numerous advantages:
|
|
|
88
85
|
5. **Alignment with Powerhouse Ecosystem:** The generated code is designed to integrate seamlessly with other parts of the Powerhouse ecosystem, such as the reducer execution engine and UI components.
|
|
89
86
|
6. **Single Source of Truth:** Ensures that your codebase (especially types and action creators) stays synchronized with the document model specification defined in Connect. If the specification changes, regenerating the model will update these components accordingly.
|
|
90
87
|
|
|
91
|
-
## Practical implementation: Generating the `
|
|
88
|
+
## Practical implementation: Generating the `TodoList` model
|
|
92
89
|
|
|
93
|
-
Now that you understand what the Document Model Generator does, let's walk through the practical steps of using it with our `
|
|
90
|
+
Now that you understand what the Document Model Generator does, let's walk through the practical steps of using it with our `TodoList` example.
|
|
94
91
|
|
|
95
92
|
<details>
|
|
96
|
-
<summary>Tutorial: Generating the
|
|
93
|
+
<summary>Tutorial: Generating the TodoList document model</summary>
|
|
97
94
|
|
|
98
|
-
This tutorial assumes you have completed the previous steps in this Mastery Track, where you defined the state schema and operations for the `
|
|
95
|
+
This tutorial assumes you have completed the previous steps in this Mastery Track, where you defined the state schema and operations for the `TodoList` model in Connect and exported it.
|
|
99
96
|
|
|
100
97
|
### Prerequisites
|
|
101
98
|
|
|
102
|
-
- **`
|
|
99
|
+
- **`TodoList.phd` file**: You must have the document model specification file exported from Connect. If you do not have this file, please revisit the previous sections on specifying the state schema and operations.
|
|
103
100
|
|
|
104
101
|
### Steps
|
|
105
102
|
|
|
106
103
|
1. **Place the Specification File in Your Project**:
|
|
107
104
|
- Navigate to the root directory of your Powerhouse project.
|
|
108
|
-
- Move or copy your `
|
|
105
|
+
- Move or copy your `TodoList.phd` file into this directory.
|
|
109
106
|
|
|
110
107
|
2. **Run the Generator Command**:
|
|
111
108
|
- Open your terminal in the root directory of your Powerhouse project.
|
|
112
109
|
- Execute the `ph generate` command, pointing to your specification file:
|
|
113
110
|
|
|
114
111
|
```bash
|
|
115
|
-
ph generate
|
|
112
|
+
ph generate TodoList.phd
|
|
116
113
|
```
|
|
117
114
|
|
|
118
115
|
3. **Explore the Generated Files**:
|
|
119
|
-
- After the command completes successfully, you will find a new directory: `document-models/
|
|
116
|
+
- After the command completes successfully, you will find a new directory: `document-models/todo-list/`.
|
|
120
117
|
- Take a moment to explore its contents, which will match the structure described earlier in this document:
|
|
121
|
-
- `
|
|
122
|
-
- `gen/`: Type-safe, generated code including `types.ts`, `
|
|
123
|
-
- `src/`: The skeleton for your implementation, most importantly `src/reducers/
|
|
118
|
+
- `todo-list.json` and `schema.graphql`: The definition of your model.
|
|
119
|
+
- `gen/`: Type-safe, generated code including `types.ts`, `creators.ts`, etc.
|
|
120
|
+
- `src/`: The skeleton for your implementation, most importantly `src/reducers/todos.ts`, which will contain empty functions for `addTodoItemOperation`, `updateTodoItemOperation`, and `deleteTodoItemOperation`, ready for you to implement.
|
|
124
121
|
|
|
125
122
|
With these files generated, you have successfully scaffolded your document model. The project is now set up for you to implement the core business logic.
|
|
126
123
|
|
|
@@ -128,7 +125,7 @@ With these files generated, you have successfully scaffolded your document model
|
|
|
128
125
|
|
|
129
126
|
## Next steps
|
|
130
127
|
|
|
131
|
-
Once the Document Model Generator has successfully scaffolded your project, the immediate next step is to implement the logic for each operation within the generated reducer files (e.g., `document-models/
|
|
128
|
+
Once the Document Model Generator has successfully scaffolded your project, the immediate next step is to implement the logic for each operation within the generated reducer files (e.g., `document-models/todo-list/src/reducers/todos.ts`). This involves taking the current state and the action input, and returning the new state of the document.
|
|
132
129
|
|
|
133
130
|
Subsequently, you will write unit tests for these reducers to ensure they behave as expected under various conditions. This iterative process of defining, generating, implementing, and testing forms the core loop of document model development in Powerhouse.
|
|
134
131
|
|