@powerhousedao/academy 0.1.0-dev.0
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/.vscode/settings.json +3 -0
- package/CHANGELOG.md +9 -0
- package/Dockerfile +31 -0
- package/ProcFile +1 -0
- package/README.md +43 -0
- package/babel.config.js +3 -0
- package/blog/BeyondCommunication-ABlueprintForDevelopment.md +88 -0
- package/blog/TheChallengeOfChange.md +86 -0
- package/blog/images/Iteration.png +0 -0
- package/blog/images/RAD.png +0 -0
- package/docs/academy/01-GetStarted/00-GetStarted.mdx +181 -0
- package/docs/academy/01-GetStarted/01_InstallDemoPackage.md +38 -0
- package/docs/academy/01-GetStarted/02-ToDoList/01-CreateNewPowerhouseProject.md +97 -0
- package/docs/academy/01-GetStarted/02-ToDoList/02-DefineToDoListDocumentModel.md +86 -0
- package/docs/academy/01-GetStarted/02-ToDoList/03-ImplementOperationReducers.md +201 -0
- package/docs/academy/01-GetStarted/02-ToDoList/04-BuildToDoListEditor.md +494 -0
- package/docs/academy/01-GetStarted/02-ToDoList/_category_.json +8 -0
- package/docs/academy/01-GetStarted/02-ToDoList/images/DocumentModelHeader.png +0 -0
- package/docs/academy/01-GetStarted/02-ToDoList/images/DocumentModelOperations.png +0 -0
- package/docs/academy/01-GetStarted/02-ToDoList/images/OpenDocumentModelEditor.gif +0 -0
- package/docs/academy/01-GetStarted/02-ToDoList/images/completeEditor.png +0 -0
- package/docs/academy/01-GetStarted/02-ToDoList/images/connectApp.gif +0 -0
- package/docs/academy/01-GetStarted/02-ToDoList/images/form.png +0 -0
- package/docs/academy/01-GetStarted/02-ToDoList/images/mytodolist.gif +0 -0
- package/docs/academy/01-GetStarted/02-ToDoList/images/reducers.png +0 -0
- package/docs/academy/01-GetStarted/02-ToDoList/images/vscode.png +0 -0
- package/docs/academy/01-GetStarted/styles.module.css +99 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/00-BuilderTools.md +234 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/01-SetupBuilderEnvironment.md +247 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/04-UtilitiesAndTips.md +79 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/01-SetupBuilderEnvironment.md +216 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/02-CreateNewPowerhouseProject.md +78 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/03-DefineChatroomDocumentModel.md +139 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/04-ImplementOperationReducers.md +364 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/05-ImplementChatroomEditor.md +194 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/06-LaunchALocalReactor.md +15 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/_category_.json +8 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/image-1.png +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/image-2.png +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/image-3.png +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/image-4.png +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/image-5.png +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/image.png +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/images/ChatRoomConnectApp.gif +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/images/ChatRoomTest.gif +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/images/completeEditor.png +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/images/form.png +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/images/reducers.png +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/images/vscode.png +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/_category_.json +8 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-StandardDocumentModelWorkflow.md +229 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/01-BuildingBeautifulDocumentEditors.md +109 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/02-ConfiguringDrives.md +51 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/03-BuildingADriveExplorer.md +174 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/07-DocumentTools/01-OperationHistory.md +67 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/07-DocumentTools/02-RevisionHistoryTimeline.md +132 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/07-DocumentTools/_category_.json +7 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/07-DocumentTools/images/committer-address-popup.png +0 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/07-DocumentTools/images/revision-hash-popup.png +0 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/07-DocumentTools/images/revision-history-list.png +0 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/07-DocumentTools/images/signature-details-popup.png +0 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/_category_.json +8 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/images/CreateDrive.png +0 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/images/mytodolist.gif +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/01-ReadingAndWritingThroughTheAPI.mdx +121 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/02-GraphQLAtPowerhouse.md +156 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/03-WorkingWithSubgraphs/02-GraphQLAndSubgraphs.mdx +119 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/03-WorkingWithSubgraphs/03-WorkingWithSubgraphs.md +312 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/03-WorkingWithSubgraphs/_category_.json +8 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/04-analytics-processor.md +342 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/01-SetupBuilderEnvironment.md +215 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/02-CreateNewPowerhouseProject.md +55 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/03-GenerateAnAnalyticsProcessor.md +173 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/04-UpdateAnalyticsProcessor.md +223 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/_category_.json +8 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/images/Create-SPV.gif +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/images/Create-a-new-asset.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/images/Create-a-transaction.gif +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/images/Transaction-table.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/images/create-a-new-RWA-document.gif +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/images/granularity.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/GraphQL References/QueryingADocumentWithGraphQL.md +244 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/GraphQL References/rwa-reports/listener-raw.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/GraphQL References/rwa-reports/raw-reports1.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/GraphQL References/rwa-reports/raw-reports2.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/GraphQL References/rwa-reports/rwaRegister.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/apse.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/best-practices.md +60 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/filter.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/filteroptions.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/graphql/index.md +166 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/graphql/integration.md +75 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/dbs.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/high-level.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/indexeddb.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/libs-core.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/libs.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/lod.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/logo.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/navbar.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/overview-1.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/overview-2.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/overview-3.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/overview-4.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/overview-5.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/overview-6.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/paths-1.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/paths-2.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/intro.md +149 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/typescript/benchmarks.md +27 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/typescript/browser.md +77 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/typescript/compatibility.md +14 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/typescript/index.md +230 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/typescript/memory.md +72 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/typescript/pg.md +63 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/typescript/schema.md +14 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/typescript/utilities.md +102 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/use-cases/index.md +7 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/use-cases/maker.md +652 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/use-cases/processors.md +3 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/_category_.json +8 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/images/OperationHistory.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/images/OperationsQuery.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/images/QueryDocumentID.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/images/SwitchboardButton.png +0 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/00-IntegrateInAFront-End +3 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/01-IntroducingFusion +18 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/02-IntroductionToPackages.md +79 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/02-PublishYourProject.md +230 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/03-RunOnACloudServer.md +279 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/03-SetupEnvironment.md +436 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/04-GraphQLNamespacing +44 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/05-LaunchYourBackend.md +3 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/06-LaunchYourFrontend.md +3 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/_category_.json +8 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/images/SSHConnection.png +0 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/images/homedesign.png +0 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/images/keyconcepts.png +0 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/images/tutorialschema.png +0 -0
- package/docs/academy/02-AdvancedTutorial/06-Authorization/Authorization.md +100 -0
- package/docs/academy/02-AdvancedTutorial/_category_.json +7 -0
- package/docs/academy/03-APIReferences/00-PowerhouseCLI.md +1 -0
- package/docs/academy/03-APIReferences/_category_.json +7 -0
- package/docs/academy/04-ComponentLibrary/01-PowerhouseDesignSystem.md +94 -0
- package/docs/academy/04-ComponentLibrary/02-BuildingWithScalars.md +54 -0
- package/docs/academy/04-ComponentLibrary/03-Scalar-Components/01-phid-field.mdx +72 -0
- package/docs/academy/04-ComponentLibrary/03-Scalar-Components/02-input-field.mdx +0 -0
- package/docs/academy/04-ComponentLibrary/04-Complex-Components/01-sidebar.mdx +36 -0
- package/docs/academy/04-ComponentLibrary/05-Layout-Components/01-test-toupdate.mdx +61 -0
- package/docs/academy/04-ComponentLibrary/06-Fragments/01-test-toupdate.mdx +61 -0
- package/docs/academy/04-ComponentLibrary/_category_.json +8 -0
- package/docs/academy/05-Architecture/00-PowerhouseArchitecture.md +50 -0
- package/docs/academy/05-Architecture/01-WorkingWithTheReactor.md +48 -0
- package/docs/academy/05-Architecture/02-ReferencingMonorepoPackages +65 -0
- package/docs/academy/05-Architecture/04-MovingBeyondCRUD +61 -0
- package/docs/academy/05-Architecture/05-DocumentModelTheory/01-WhatIsADocumentModel.md +188 -0
- package/docs/academy/05-Architecture/05-DocumentModelTheory/02-DAOandDocumentsModelsQ+A.md +177 -0
- package/docs/academy/05-Architecture/05-DocumentModelTheory/02-domain-modeling.md +103 -0
- package/docs/academy/05-Architecture/05-DocumentModelTheory/03-BenefitsOfDocumentModels.md +95 -0
- package/docs/academy/05-Architecture/05-DocumentModelTheory/05-best-practices.md +257 -0
- package/docs/academy/05-Architecture/05-DocumentModelTheory/_category_.json +8 -0
- package/docs/academy/05-Architecture/05-DocumentModelTheory/three-data-layers.png +0 -0
- package/docs/academy/05-Architecture/_category_.json +7 -0
- package/docs/academy/05-Architecture/images/image.png +0 -0
- package/docs/academy/06-Cookbook.md +905 -0
- package/docs/academy/07-Glossary.md +50 -0
- package/docs/bookofpowerhouse/01-Overview.md +29 -0
- package/docs/bookofpowerhouse/02-GeneralFrameworkAndPhilosophy.md +15 -0
- package/docs/bookofpowerhouse/03-PowerhouseSoftwareArchitecture.md +33 -0
- package/docs/bookofpowerhouse/04-DevelopmentApproaches.md +36 -0
- package/docs/bookofpowerhouse/05-SNOsandANewModelForOSSandPublicGoods.md +73 -0
- package/docs/bookofpowerhouse/06-SNOsInActionAndPlatformEconomies.md +17 -0
- package/docs/renown/01-intro.md +18 -0
- package/docs/renown/02-renown-login-flow.md +60 -0
- package/docusaurus +0 -0
- package/docusaurus.config.ts +170 -0
- package/package.json +50 -0
- package/powerhouse-docs@0.0.0 +0 -0
- package/sidebars.ts +33 -0
- package/src/components/HomepageFeatures/index.tsx +250 -0
- package/src/components/HomepageFeatures/styles.module.css +267 -0
- package/src/css/custom.css +450 -0
- package/src/pages/index.module.css +37 -0
- package/src/pages/index.tsx +42 -0
- package/src/pages/markdown-page.md +7 -0
- package/static/.nojekyll +0 -0
- package/static/fonts/FranieBold.otf +0 -0
- package/static/fonts/FranieRegular.otf +0 -0
- package/static/img/Powerhouse Website Drive.png +0 -0
- package/static/img/Powerhouse Website Storage Layer (1).png +0 -0
- package/static/img/Powerhouse Website Storage Layer.png +0 -0
- package/static/img/Powerhouse-main-light.svg +13 -0
- package/static/img/Powerhouse-main.svg +13 -0
- package/static/img/Renown Intro Diagram.png +0 -0
- package/static/img/Union.svg +3 -0
- package/static/img/academy/icons/Advanced.svg +4 -0
- package/static/img/academy/icons/Book.svg +5 -0
- package/static/img/academy/icons/Cookbook.svg +3 -0
- package/static/img/academy/icons/Create.svg +3 -0
- package/static/img/academy/icons/Data.svg +3 -0
- package/static/img/academy/icons/Editor.svg +3 -0
- package/static/img/academy/icons/Flash.svg +3 -0
- package/static/img/academy/icons/Launch.svg +3 -0
- package/static/img/academy-icon.png +0 -0
- package/static/img/connect-icon.png +0 -0
- package/static/img/connect.png +0 -0
- package/static/img/docusaurus-social-card.jpg +0 -0
- package/static/img/docusaurus.png +0 -0
- package/static/img/empty-background.png +0 -0
- package/static/img/favicon.ico +0 -0
- package/static/img/fusion-icon.png +0 -0
- package/static/img/fusion.png +0 -0
- package/static/img/ph-icon-light.svg +3 -0
- package/static/img/powerhouse-layer.png +0 -0
- package/static/img/powerhouse-storage-layer.png +0 -0
- package/static/img/reactor.png +0 -0
- package/static/img/renown-icon.png +0 -0
- package/static/img/renown.png +0 -0
- package/static/img/switchboard-icon.png +0 -0
- package/static/img/switchboard.png +0 -0
- package/static/img/undraw_docusaurus_mountain.svg +171 -0
- package/static/img/undraw_docusaurus_react.svg +170 -0
- package/static/img/undraw_docusaurus_tree.svg +40 -0
- package/static/img/video-placeholder.svg +16 -0
- package/static.json +7 -0
- package/tsconfig.json +7 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Revision History Timeline
|
|
2
|
+
|
|
3
|
+
The timeline feature enables users to view document history and navigate through different revisions of a document. This guide explains how to implement and customize the timeline functionality in your Powerhouse application.
|
|
4
|
+
|
|
5
|
+
## Enabling the Timeline Feature
|
|
6
|
+
|
|
7
|
+
To enable the timeline feature in your document editor, you need to set `timelineEnabled: true` in your editor module configuration:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// editors/to-do-list/index.ts
|
|
11
|
+
export const module: EditorModule<ToDoDocument> = {
|
|
12
|
+
Component: Editor as unknown as FC<EditorProps<ToDoDocument> & Record<string, unknown>>,
|
|
13
|
+
documentTypes: ["powerhouse/todo"],
|
|
14
|
+
config: {
|
|
15
|
+
id: "editor-id",
|
|
16
|
+
disableExternalControls: true,
|
|
17
|
+
documentToolbarEnabled: true,
|
|
18
|
+
showSwitchboardLink: true,
|
|
19
|
+
timelineEnabled: true, // Enable timeline feature
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
This setting enables the timeline button in the document toolbar.
|
|
25
|
+
|
|
26
|
+
## Implementation Options
|
|
27
|
+
|
|
28
|
+
### Default Drive Explorer
|
|
29
|
+
|
|
30
|
+
When using the default drive explorer with `ph connect`, the timeline functionality is handled automatically:
|
|
31
|
+
|
|
32
|
+
- Document analytics are collected and passed to the document toolbar
|
|
33
|
+
- The timeline button appears in the toolbar when enabled
|
|
34
|
+
- Users can click on timeline items to view document revisions
|
|
35
|
+
|
|
36
|
+
### Custom Drive Explorer
|
|
37
|
+
|
|
38
|
+
For custom drive explorers, you need to handle timeline items fetching and user interaction manually. Here's how:
|
|
39
|
+
|
|
40
|
+
1. First, import the necessary utilities from the Powerhouse common package:
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { useTimelineItems, getRevisionFromDate } from "@powerhousedao/common";
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
2. Fetch timeline items using the `useTimelineItems` hook:
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
// In your EditorContainer.tsx
|
|
50
|
+
const timelineItems = useTimelineItems(documentId);
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
3. Track the selected timeline item in state:
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
const [selectedTimelineItem, setSelectedTimelineItem] = useState<TimelineItem | null>(null);
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
4. Pass the timeline items to the DocumentToolbar and handle item selection:
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
<DocumentToolbar
|
|
63
|
+
timelineButtonVisible={editorModule.config.timelineEnabled}
|
|
64
|
+
timelineItems={timelineItems.data}
|
|
65
|
+
onTimelineItemClick={setSelectedTimelineItem}
|
|
66
|
+
// ... other props
|
|
67
|
+
/>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
> **Note**: The `timelineButtonVisible` prop should be set based on the `timelineEnabled` setting in the editor module's configuration. This ensures the timeline button is only shown when the feature is enabled for that specific document type.
|
|
71
|
+
|
|
72
|
+
5. Pass the required context values to your editor component:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
<EditorComponent
|
|
76
|
+
context={{
|
|
77
|
+
...context,
|
|
78
|
+
readMode: !!selectedTimelineItem,
|
|
79
|
+
selectedTimelineRevision: getRevisionFromDate(
|
|
80
|
+
selectedTimelineItem?.startDate,
|
|
81
|
+
selectedTimelineItem?.endDate,
|
|
82
|
+
document.operations.global,
|
|
83
|
+
),
|
|
84
|
+
}}
|
|
85
|
+
// ... other props
|
|
86
|
+
/>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Handling Timeline Revisions in Document Editor
|
|
90
|
+
|
|
91
|
+
In your document editor (e.g., `editors/to-do-list/editor.tsx`), you need to handle the timeline context props:
|
|
92
|
+
|
|
93
|
+
1. Extract timeline-related properties from the context:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
const { readMode = false, selectedTimelineRevision, getDocumentRevision } = context;
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
2. Fetch the document at the selected revision when in read mode:
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
const [readModeDocument, setReadModeDocument] = useState<ToDoDocument | null>(null);
|
|
103
|
+
|
|
104
|
+
useEffect(() => {
|
|
105
|
+
const getReadModeDocument = async () => {
|
|
106
|
+
if (getDocumentRevision && readMode && typeof selectedTimelineRevision === 'number') {
|
|
107
|
+
const document = await getDocumentRevision({ revisions: { global: selectedTimelineRevision } });
|
|
108
|
+
setReadModeDocument(document);
|
|
109
|
+
} else if (!readMode) {
|
|
110
|
+
setReadModeDocument(null);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
getReadModeDocument();
|
|
114
|
+
}, [getDocumentRevision, readMode, selectedTimelineRevision]);
|
|
115
|
+
|
|
116
|
+
// Use the appropriate document based on mode
|
|
117
|
+
const document = readModeDocument || writeModeDocument;
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
3. Adapt your UI to reflect read mode:
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
{readMode && (
|
|
124
|
+
<div className="text-gray-500 text-md text-center">(🔒 Read Mode)</div>
|
|
125
|
+
)}
|
|
126
|
+
|
|
127
|
+
{!readMode && (
|
|
128
|
+
// Edit controls here
|
|
129
|
+
)}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
This implementation allows users to navigate through document history while preventing edits to historical revisions.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/docs/academy/02-AdvancedTutorial/04-WorkWithData/01-ReadingAndWritingThroughTheAPI.mdx
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Read & Write through the API
|
|
2
|
+
|
|
3
|
+
## Introduction to Switchboard
|
|
4
|
+
|
|
5
|
+
**Switchboard** is the API interface that allows developers and data engineers to get access to the data, that is being collected through the use of document models in Connect & Fusion.
|
|
6
|
+
After structurally capturing the desired data of your formalised business processes the data can be used to build insightful experiences in external websites, drive widgets or create specific reports and dashboard in fusion.
|
|
7
|
+
**Since your document models have been defined with a GraphQL schema, you can use the same objects and fields in your queries and mutations to retrieve or write data from and to your document models.**
|
|
8
|
+
|
|
9
|
+
<details>
|
|
10
|
+
<summary>Get your Switchboard API token (if required)</summary>
|
|
11
|
+
|
|
12
|
+
Your API requests are authenticated using API keys or tokens. Any request that doesn't include an API key will return an error. You can generate an API token from your Switchboard instance at any time [by logging in with your Ethereum address here](https://apps.powerhouse.io/develop/powerhouse/switchboard/user).
|
|
13
|
+
|
|
14
|
+
</details>
|
|
15
|
+
|
|
16
|
+
## Querying a document with the GraphQL API
|
|
17
|
+
|
|
18
|
+
### Starting the reactor locally
|
|
19
|
+
|
|
20
|
+
In this documentation we'll show how to use a **GraphQL** query to query a document model. We'll **continue on the ToDoList example** from our [introduction tutorial](/docs/academy/GetStarted/ToDoList/DefineToDoListDocumentModel) , but the process can be applied to any other document model.
|
|
21
|
+
To make our document model available in the Apollo Studio Sandbox we'll need to store it on a remote [Reactor](/docs/academy/Architecture/WorkingWithTheReactor).
|
|
22
|
+
|
|
23
|
+
:::info
|
|
24
|
+
**Powerhouse Reactors** are the nodes in the network that store documents, resolve conflicts and rerun operations to verify document event histories.
|
|
25
|
+
Reactors can be configured for local storage, centralized cloud storage or on a decentralized storage network.
|
|
26
|
+
|
|
27
|
+
A reactor allows you to store multiple documents, but also host **drives** with different organisational purposes, users, access rights and more.
|
|
28
|
+
:::
|
|
29
|
+
|
|
30
|
+
Just like we can run Connect locally in studio mode we can run a remote node or a Reactor locally.
|
|
31
|
+
Use the following commands:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
ph reactor
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
To start both Connect and a Reactor locally at the same time in a Powerhouse project you can use the following command:
|
|
38
|
+
```bash
|
|
39
|
+
ph dev
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
It will return a url to access the Reactor.
|
|
43
|
+
```bash
|
|
44
|
+
[Reactor]: ➜ Reactor: http://localhost:4001/d/powerhouse
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Adding a remote drive or reactor to Connect:
|
|
48
|
+
|
|
49
|
+
If the remote drive or Reactor isn't present yet in connect you can add it by clicking the (+) button in the Connect drive navigation
|
|
50
|
+
and using the localhost url to add a new drive with it's underlying reactor. Usually http://localhost:4001/d/powerhouse
|
|
51
|
+
|
|
52
|
+
Get access to an **organisations drive** instances by adding their drive to your Connect Drive navigation tree view with the help of the correct drive url.
|
|
53
|
+
click the (+) to add a public drive. To add a new drive you'll have to know the correct public URL of the drive.
|
|
54
|
+
|
|
55
|
+
## Querying the state of a document
|
|
56
|
+
|
|
57
|
+
Now that we have our remote reactor and/or drive running we can store our document model on it.
|
|
58
|
+
Let's quickly create a new **todo list document** to test the process.
|
|
59
|
+
|
|
60
|
+
Add to following todo's to your list:
|
|
61
|
+
- [ ] Sign up for Powerhouse
|
|
62
|
+
- [ ] Do the work
|
|
63
|
+
- [ ] Deliver the work
|
|
64
|
+
- [ ] Send the invoice
|
|
65
|
+
- [ ] Get paid
|
|
66
|
+
|
|
67
|
+
Now that we have some data in our document model we can query it through the GraphQL API.
|
|
68
|
+
|
|
69
|
+
### 1. The complete state of the document:
|
|
70
|
+
|
|
71
|
+
Whenever you want to start a query from a document within connect you can open up switchboard by looking for the Switchboard logo in the top right hand corner of the document editor interface.
|
|
72
|
+
This will prepopulate the Apollo Studio Sandbox with the correct **DocumentID** for your document model. This feature will not be available for documents stored on local drives.
|
|
73
|
+
|
|
74
|
+

|
|
75
|
+
|
|
76
|
+
The documentation on the left hand side of the Apollo Sandbox will show you all of the different fields that are available to query.
|
|
77
|
+
|
|
78
|
+

|
|
79
|
+
|
|
80
|
+
Alternatively we can just use our reactor url and endpoint to figure out the document id.
|
|
81
|
+
We can find out what the id of our document is by querying the drive for it's documents.
|
|
82
|
+
Since we only have one document in our drive it will return the id of our todo list document.
|
|
83
|
+
|
|
84
|
+
This example query is structured to request a document by its unique identifier (id).
|
|
85
|
+
It extracts common fields such as **id**, **name**, **documentType**, **revision**, **created**, and **lastModified**.
|
|
86
|
+
|
|
87
|
+
In the above example we queried for the content of the operations. Let's compare the results with the document operation history.
|
|
88
|
+
Side by side you can see the document content and the operation history.
|
|
89
|
+
|
|
90
|
+
Below is the operation history of the todo list document. As you can see the operations are logged in the order they were executed.
|
|
91
|
+
As you can see there is a 'Delete' operation in the history on revision 5 as we forgot to add 'Send the invoice' to our list.
|
|
92
|
+

|
|
93
|
+
|
|
94
|
+
Now let's query the content of the document using Apollo Studio Sandbox. The left sidebar shows the schema documentation, where you can explore all available fields and types for your document model.
|
|
95
|
+
|
|
96
|
+
For our TodoList document, let's construct a query that fetches the operations with the help of a nested operations field
|
|
97
|
+
|
|
98
|
+
```graphql
|
|
99
|
+
query {
|
|
100
|
+
document(id: "...") {
|
|
101
|
+
name
|
|
102
|
+
documentType
|
|
103
|
+
revision
|
|
104
|
+
created
|
|
105
|
+
lastModified
|
|
106
|
+
... on TodoList {
|
|
107
|
+
operations {
|
|
108
|
+
type
|
|
109
|
+
id
|
|
110
|
+
inputText
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
This query will return all operations performed on the document, including ADD_TODO_ITEM and DELETE_TODO_ITEM operations, allowing us to see the complete history of changes.
|
|
118
|
+
|
|
119
|
+
## Writing to a document
|
|
120
|
+
|
|
121
|
+
Now that we know how to query the state of a document we can start to write to it.
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# GraphQL at Powerhouse
|
|
2
|
+
|
|
3
|
+
In this section, we will cover **the core concepts of GraphQL with examples applied to the Powerhouse ecosystem**. More specifically, GraphQL is used as:
|
|
4
|
+
- The **schema definition language (SDL)** for defining our document models and thereby self-documenting the API to the data model. It allows developers to define the structure and relationships of data in a strongly-typed format.
|
|
5
|
+
- As the **query language in subgraphs**, which allow different services to expose and query structured data dynamically. Jump to the section [GraphQL and Subgraphs](/docs/academy/AdvancedTutorial/WorkWithData/WorkingWithSubgraphs/GraphQLAndSubgraphs) to learn more about this.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Why GraphQL?
|
|
9
|
+
|
|
10
|
+
- **Precision**: Instead of over-fetching or under-fetching data, GraphQL enables you to specify the precise data requirements in your query.
|
|
11
|
+
- **Single Endpoint**: With GraphQL, you can access all the data you need through one endpoint, reducing the number of network requests.
|
|
12
|
+
- **Dynamic Queries**: Its introspective nature allows developers to explore the API's schema dynamically, which streamlines development and documentation.
|
|
13
|
+
|
|
14
|
+
## GraphQL: Core Concepts
|
|
15
|
+
|
|
16
|
+
### Schema
|
|
17
|
+
The schema defines the structure of a GraphQL API. It acts as a contract between the client and server, detailing:
|
|
18
|
+
|
|
19
|
+
- **Data Types**: The various types of data that can be queried.
|
|
20
|
+
For example the contributor type and the project type
|
|
21
|
+
- **Fields**: The available fields on each type.
|
|
22
|
+
For example the contributor type has a field 'name' and the project type has a field 'title'
|
|
23
|
+
- **Relationships**: How different types relate to each other.
|
|
24
|
+
For example the contributor type has a relationship with the project type
|
|
25
|
+
|
|
26
|
+
```graphql title="Example of a Powerhouse Contributor schema in GraphQL"
|
|
27
|
+
type Contributor {
|
|
28
|
+
id: ID!
|
|
29
|
+
name: String!
|
|
30
|
+
reputationScore: Float
|
|
31
|
+
projects: [Project] # The Contributor type has a field 'projects' that returns an array of Project objects
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
type Project {
|
|
35
|
+
id: ID!
|
|
36
|
+
title: String!
|
|
37
|
+
status: String
|
|
38
|
+
budget: Float
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
type Query {
|
|
42
|
+
getContributor(id: ID!): Contributor
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
With the following query someone can request the contributor with the id 123
|
|
47
|
+
|
|
48
|
+
```graphql title="Example of a query to get a contributor"
|
|
49
|
+
query {
|
|
50
|
+
getContributor(id: "123") {
|
|
51
|
+
name
|
|
52
|
+
reputationScore
|
|
53
|
+
projects { # Accessing the related projects
|
|
54
|
+
title
|
|
55
|
+
status
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
### Fields & Arguments
|
|
64
|
+
- **Field**: A specific piece of data you can request from an object. When you build a query, you select the fields you want to retrieve.
|
|
65
|
+
- **Argument**: Key-value pairs that can be attached to fields to customize and refine the query. Some fields require arguments to work correctly, especially when dealing with mutations.
|
|
66
|
+
|
|
67
|
+
Powerhouse uses invoices as part of its decentralized operations. With GraphQL, an invoice query might look like this:
|
|
68
|
+
Here, contributorId and status are arguments that filter the results to return only paid invoices for a specific contributor.
|
|
69
|
+
|
|
70
|
+
```graphql title="Fetching an Invoice with Filtering"
|
|
71
|
+
query {
|
|
72
|
+
getInvoices(contributorId: "456", status: "PAID") {
|
|
73
|
+
id
|
|
74
|
+
amount
|
|
75
|
+
currency
|
|
76
|
+
dueDate
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
___
|
|
81
|
+
|
|
82
|
+
### Introspection
|
|
83
|
+
GraphQL APIs are self-documenting. Through introspection, you can query the API to retrieve details about its schema, including:
|
|
84
|
+
|
|
85
|
+
- The list of **available types and fields**.
|
|
86
|
+
- The **relationships** between those types. This capability is particularly useful for developing dynamic client applications and auto-generating documentation.
|
|
87
|
+
|
|
88
|
+
Developers might want to see what data structures are available. This makes it easy to explore document models and read models in Powerhouse without needing to consult extensive external documentation.
|
|
89
|
+
|
|
90
|
+
```graphql title="Discovering Available Queries"
|
|
91
|
+
{
|
|
92
|
+
__schema {
|
|
93
|
+
types {
|
|
94
|
+
name
|
|
95
|
+
fields {
|
|
96
|
+
name
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
### Connections, Edges, and Nodes
|
|
105
|
+
When dealing with lists of data, GraphQL employs a pattern that includes:
|
|
106
|
+
|
|
107
|
+
- **Connection**: A structure that represents a list of related objects.
|
|
108
|
+
- **Edge**: Represents the link between individual nodes (objects) in a connection. Each edge contains:
|
|
109
|
+
- A node field (the actual object).
|
|
110
|
+
- A cursor for pagination.
|
|
111
|
+
- **Node**: The individual object in the connection. When querying nodes, you continue selecting subfields until all the data resolves to scalar values.
|
|
112
|
+
|
|
113
|
+
To efficiently fetch invoices in Powerhouse, a paginated query could look like this.
|
|
114
|
+
This allows Powerhouse Switchboard to efficiently handle large datasets and return results incrementally
|
|
115
|
+
|
|
116
|
+
```graphql title="Paginated List of Invoices"
|
|
117
|
+
query {
|
|
118
|
+
invoices(first: 10, after: "cursor123") {
|
|
119
|
+
edges {
|
|
120
|
+
node {
|
|
121
|
+
id
|
|
122
|
+
amount
|
|
123
|
+
dueDate
|
|
124
|
+
}
|
|
125
|
+
cursor
|
|
126
|
+
}
|
|
127
|
+
pageInfo {
|
|
128
|
+
hasNextPage
|
|
129
|
+
endCursor
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
### Mutations
|
|
138
|
+
- While queries retrieve data, **mutations modify data**. In Powerhouse, a contributor might need to submit an invoice after completing a task. A GraphQL mutation for this could be:
|
|
139
|
+
|
|
140
|
+
```graphql title="Submitting an Invoice"
|
|
141
|
+
mutation {
|
|
142
|
+
submitInvoice(input: {
|
|
143
|
+
contributorId: "123"
|
|
144
|
+
amount: 500.00
|
|
145
|
+
currency: "USD"
|
|
146
|
+
dueDate: "2024-03-01"
|
|
147
|
+
}) {
|
|
148
|
+
id
|
|
149
|
+
status
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
## Summary
|
|
156
|
+
GraphQL offers a streamlined and efficient approach to data retrieval, particularly useful when you need granular control over your API interactions. By defining a robust schema, using precise fields and arguments, and leveraging introspection, GraphQL minimizes unnecessary data transfers. If you want to learn more about GraphQL, there is the following link to the official documentation: [Introduction to GraphQL](https://graphql.org/learn/).
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# GraphQL and Subgraphs
|
|
2
|
+
|
|
3
|
+
GraphQL plays a fundamental role in defining document model data schemas, handling data access patterns, and enabling event-driven workflows within the Powerhouse ecosystem.
|
|
4
|
+
This document provides an intro to graphQL and how it is used at Powerhouse when dealing with subgraphs
|
|
5
|
+
|
|
6
|
+
More specifically, GraphQL is used as:
|
|
7
|
+
- The **schema definition language (SDL)** for defining our document models and thereby self-documenting the API to the data model. It allows developers to define the structure and relationships of data in a strongly-typed format.
|
|
8
|
+
- As the **query language in subgraphs**, which allow different services to expose and query structured data dynamically.
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
## Powerhouse's use of GraphQL Subgraphs
|
|
12
|
+
Powerhouse structures its data into subgraphs, which are modular GraphQL services that connect to the Reactor, Powerhouse's core data infrastructure, or Operational Data Stores fueled by data from a processor.
|
|
13
|
+
|
|
14
|
+
### Fetching data from the Reactor
|
|
15
|
+
|
|
16
|
+
Powerhouse uses GraphQL to expose system-level data, such as drives, users, and operational records.
|
|
17
|
+
Example: The **System Subgraph** allows querying of drives, stored files and folders.
|
|
18
|
+
|
|
19
|
+
### Operational Data Stores
|
|
20
|
+
|
|
21
|
+
Custom subgraphs can be created to store and retrieve operational data in real time.
|
|
22
|
+
Example: A subgraph can track file uploads and expose this data via GraphQL queries. ????
|
|
23
|
+
|
|
24
|
+
??
|
|
25
|
+
|
|
26
|
+
```graphql
|
|
27
|
+
type File {
|
|
28
|
+
id: ID!
|
|
29
|
+
name: String!
|
|
30
|
+
size: Int!
|
|
31
|
+
createdAt: DateTime!
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
type Query {
|
|
35
|
+
getFile(id: ID!): File
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
This schema ensures that every File entity has an ID, name, size, and timestamp.
|
|
39
|
+
|
|
40
|
+
??
|
|
41
|
+
|
|
42
|
+
In Powerhouse, each subgraph has its own SDL, ensuring modularity and flexibility while working within the ecosystem.
|
|
43
|
+
|
|
44
|
+
## CQRS Breakdown
|
|
45
|
+
|
|
46
|
+
Powerhouse uses CQRS to separate write operations (commands) from read operations (queries).
|
|
47
|
+
This improves system scalability and flexibility.
|
|
48
|
+
- GraphQL Queries handle read operations, retrieving structured data efficiently.
|
|
49
|
+
- GraphQL Mutations handle write operations, modifying the state in a controlled manner.
|
|
50
|
+
|
|
51
|
+
Powerhouse's subgraphs act as the read layer, while processors handle write operations into operational data stores. This prevents conflicts between querying and modifying data.
|
|
52
|
+
|
|
53
|
+
| Layer | Role | GraphQL Usage | Implementation |
|
|
54
|
+
| --- | --- | --- | --- |
|
|
55
|
+
| Write Model (Commands) | Handles state changes (adding, modifying, deleting) | GraphQL Mutations | Processor |
|
|
56
|
+
| Read Model (Queries) | Optimized for fetching/reading/retrieving data | GraphQL Queries | Subgraph |
|
|
57
|
+
|
|
58
|
+
### Read & Write Separation
|
|
59
|
+
**Read Model (Query)**
|
|
60
|
+
|
|
61
|
+
- Optimized for data retrieval
|
|
62
|
+
- Structured using GraphQL Queries
|
|
63
|
+
- Aggregates and exposes data via a subgraph
|
|
64
|
+
- Pulls data from Operational Data Stores, Analytics Stores, and Reactor
|
|
65
|
+
- Subgraphs do not directly modify the data—they only expose pre-processed information
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
```graphql title="Example of a Powerhouse Contributor schema in GraphQL"
|
|
70
|
+
query {
|
|
71
|
+
getFile(id: "123") {
|
|
72
|
+
name
|
|
73
|
+
size
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Write Model (Mutation)**
|
|
79
|
+
- Handles state changes (adding, modifying, deleting)
|
|
80
|
+
- Structured using GraphQL Mutations
|
|
81
|
+
- Writes data to Operational Data Stores
|
|
82
|
+
|
|
83
|
+
```graphql title="Example of a Powerhouse Contributor schema in GraphQL"
|
|
84
|
+
mutation {
|
|
85
|
+
createFile(name: "document.pdf", size: 1024) {
|
|
86
|
+
id
|
|
87
|
+
name
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### GraphQL & Event-Driven Architecture (EDA)
|
|
93
|
+
Event-Driven Architecture (EDA) enables asynchronous processing where events trigger actions. Powerhouse uses GraphQL to expose real-time event data from its Reactor and Operational Data Stores.
|
|
94
|
+
|
|
95
|
+
How GraphQL Fits into EDA
|
|
96
|
+
- **Real-Time Data Exposure** – Subgraphs fetch event-based data updates.
|
|
97
|
+
- **Event Subscription Mechanism** – Powerhouse is working towards integrating GraphQL Subscriptions for real-time updates.
|
|
98
|
+
- **Efficient Decoupling** – Events are stored in an operational datastore, and GraphQL queries retrieve structured results.
|
|
99
|
+
|
|
100
|
+
#### Example: Powerhouse's Event Flow
|
|
101
|
+
1. Processor detects an event (e.g., file upload).
|
|
102
|
+
2. Writes event data to the Operational Data Store.
|
|
103
|
+
3. Subgraph exposes the updated data via GraphQL.
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
## GraphQL Subscriptions
|
|
107
|
+
Although Powerhouse currently uses queries and mutations, GraphQL Subscriptions could allow real-time streaming of event-based data.
|
|
108
|
+
|
|
109
|
+
#### Example (future implementation):
|
|
110
|
+
|
|
111
|
+
```graphql
|
|
112
|
+
subscription {
|
|
113
|
+
fileUploaded {
|
|
114
|
+
id
|
|
115
|
+
name
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
This would enable clients to listen for new file uploads without polling.
|