Reflow OS User Flows
====================

:::warning
:warning: Please, **read** **twice** the [**Economic Value Flows**](https://valueflo.ws/introduction/flows.html) introduction before you **start**.
:::
# Main use case
1. A user can create (or `agent`) `economicResources` (as `inventoriedEconomicResources`) using `createEconomicEvent`. Including properties such as location via `spatialThing`, amount via `Measures`, image via `URI` and maybe type via `conformsTo`
2. A user can create an `intent` from his `inventoriedEconomicResources` by `createOffer` `resourceInventoriedAs` mapping property.
3. A user can create a `proposal` by `proposeIntent` mapping the `intent` using the `publishes` property.
3. A user can request a user to transfer the total or a part of an `inventoriedEconomicResources` that is part of a proposal. At the moment we consider this a manual process that doesn't involve `offers` nor what is given in exchange between the two parties. An `inventoriedEconomicResources` is transferred by `createEconomicEvent` with `action: transfer` with `provider` and `receiver` being the users (or agents) and `resourceInventoriedAs` the resource.
4. A user can perform [3 - `createEconomicEvent`] and obtain a new `economicResources` i.e. we are transferring less than we totally have `economicResources.accountingQuantity > EconomicEvent.resourceQuantity`
5. At the moment a user can't perform `action` (i.e. transform) that can be performed on an `EconomicResources` without a involving a transfer between users.
6. A user can list all his `agent.inventoriedEconomicResources`, `agent.intents` and `agent.economicEvents`
7. TBC
## Other things...
... An instance needs `units` (`createUnit`) or `measure`., `spatialThing` (`createSpatialThing`), `ResourceSpecification` (Specification of a kind of resource, taxonomy), `Process` (An activity that changes inputs into outputs. It could transform or transport economic resource)
## Useful links
https://reflowos.dyne.org/docs/api_tour
https://reflowos.dyne.org/docs/glossary
http://api.reflowproject.eu/api/explore
https://valueflo.ws/introduction/concepts.html
## Roadmap
## Milestones
### 1 - Shared inventories
- [ ] Create an economic resource (through an event)
- [ ] View details of a single resource
- [ ] View all resources associated with a user
- [ ] Search or filter resources
- [ ] Act upon a resource (transfer / consume / use)
- [ ] View resources on a map
- [ ] Start a thread on an economic resource
### 2 - Material passport
- [ ] create an economic event
- [ ] Create an economic resource
- [ ] View all economic events
- [ ] Filter economic events by action
- [ ] Filter economic events by resource
- [ ] Transfer an economic resource from a user to another
- [ ] Return the incoming valueflows of an economic resource
- [ ] Show the history of track/trace
- [ ] Print the material passport with a qrcode that links to a dedicated page with the track history
- [ ] Start a thread on an economic event
- [ ] View/Edit an economic event
- [ ] View/Edit an economic resource
### Optional
- [ ] View/Edit a process
- [ ] Start a thread on a process
- [ ] Create a process
- [ ] Link an economic event to a process, as input or output
## Economic Value Flows
[via valueflows webvowl](http://www.visualdataweb.de/webvowl/#iri=https://raw.githubusercontent.com/valueflows/valueflows/master/release-doc-in-process/all_vf.TTL
)




# A Material Flows example
Towards the **Material Passport**
## Flows
### Giving something
Guillem at Fab Lab Barcelona gives 20Kg of wood scraps to Viktor. He don't know where they came from so he registers them for the first time.
**Input**
```
mutation {
createEconomicEvent (
event: {
note: "Lending 20Kg of wood scraps to Viktor",
action: "transfer",
provider: "01EYJR67EAYVWRW5Z87HNGN16X",
receiver: "01EXKGV554X3ZHQ707WQRPT178",
resourceQuantity: {
hasUnit: "01EVTV5Q0Z5YBBES5EQ4XM43Y2",
hasNumericalValue: 20
}
},
newInventoriedResource: {
name: "20Kg Wood Scraps",
note: "Here a description of the wood scraps",
image: "https://gblobscdn.gitbook.com/assets%2F-M3JlcKYAsodrf6BU0RY%2F-M75jpgIJNeBpEqRbmzx%2F-M76NBRlFKUL_v3p_sba%2FScreen%20Shot%202020-05-12%20at%203.33.44%20pm.png",
currentLocation: "01EX9X4XEXP5EAJRNYQSDW1B23"
}
) {
economicEvent {
id
},
economicResource {
id
}
}
}
```
**Output**
```
{
"data": {
"createEconomicEvent": {
"economicEvent": {
"id": "01F53VBJ0P1NPW9DGQWJ1WZRGX"
},
"economicResource": {
"id": "01F53VBHZXTMJGJP4KNWHDDH21"
}
}
}
}
```
### Looking at something you've been given
Viktor looks at his inventory and sees the wood scraps Guillem just give him
**Input**
```
{
economicResource (id: "01F53VBHZXTMJGJP4KNWHDDH21") {
id
name
note
currentLocation {
id
name
lat
long
}
onhandQuantity {
id,
hasNumericalValue
hasUnit {
id
label
}
}
}
}
```
**Output**
```
{
"data": {
"economicResource": {
"currentLocation": {
"id": "01EX9X4XEXP5EAJRNYQSDW1B23",
"lat": 41.396,
"long": 2.192,
"name": "Fab Lab Barcelona"
},
"id": "01F53VBHZXTMJGJP4KNWHDDH21",
"name": "20Kg Wood Scraps",
"note": "Here a description of the wood scraps",
"onhandQuantity": {
"hasNumericalValue": 20,
"hasUnit": {
"id": "01EVTV5Q0Z5YBBES5EQ4XM43Y2",
"label": "kilo"
},
"id": "01F53VBJ0W3R75CBK1BZTMMFDB"
}
}
}
}
```
### Produce a new thing with something you already have
Viktor decides to produce a sheld out of all the wood scraps
**Input**
```
mutation {
createEconomicEvent (
event: {
note: "I made one shelf with wood scraps",
action: "produce",
resourceInventoriedAs: "01F53VBHZXTMJGJP4KNWHDDH21"
},
newInventoriedResource: {
name: "A nice shelf",
note: "Here a description of the shelf",
image: "https://s3.amazonaws.com/nadeau-website/wp-content/uploads/sites/19/2020/07/PR1128.jpg",
currentLocation: "01EX9X4XEXP5EAJRNYQSDW1B23"
})
{
economicEvent {
id
},
economicResource {
id
}
}
}
```
**Output**
```
{
"data": {
"createEconomicEvent": {
"economicEvent": {
"id": "01F53XDHH822A45FYSVC3PPGWJ"
},
"economicResource": {
"id": "01F53XDHGHWM16GNZZR4NP237W"
}
}
}
}
```
### Give something you have to someone else
Viktor decides to give the shelf he built using the wood scraps back to Guillem
We don't know if he will receive something back (yet)
**Input**
```
mutation {
createEconomicEvent (
event: {
note: "I give back to Guillem the shelf I made with the wood scraps he gived me",
action: "transfer",
resourceInventoriedAs: "01F53XDHGHWM16GNZZR4NP237W",
receiver: "01EXKGV554X3ZHQ707WQRPT178",
provider: "01EYJR67EAYVWRW5Z87HNGN16X"
})
{
economicEvent {
id
},
economicResource {
id
}
}
}
```
**Output**
```
{
"data": {
"createEconomicEvent": {
"economicEvent": {
"id": "01F53XMFTVXRCYMS25P86WNV47"
},
"economicResource": null
}
}
}
```
### Look at your inventory and confirm you have it
**Input**
```
{
economicResourcesFiltered(agent: "01EYJR67EAYVWRW5Z87HNGN16X") {
id
name
image
accountingQuantity {
hasUnit {
id
label
}
hasNumericalValue
}
currentLocation {
lat
long
}
}
}
```
**Output**
```
{
"data": {
"economicResourcesFiltered": [
{
"accountingQuantity": {
"hasNumericalValue": 20,
"hasUnit": {
"id": "01EVTV5Q0Z5YBBES5EQ4XM43Y2",
"label": "kilo"
}
},
"currentLocation": {
"lat": 41.396,
"long": 2.192
},
"id": "01F4VEKYMKKK254AR4W6MXFS9B",
"image": null,
"name": "20Kg Wood Scraps"
},
{
"accountingQuantity": {
"hasNumericalValue": 20,
"hasUnit": {
"id": "01EVTV5Q0Z5YBBES5EQ4XM43Y2",
"label": "kilo"
}
},
"currentLocation": {
"lat": 41.396,
"long": 2.192
},
"id": "01F53VBHZXTMJGJP4KNWHDDH21",
"image": null,
"name": "20Kg Wood Scraps"
},
{
"accountingQuantity": {
"hasNumericalValue": 20,
"hasUnit": {
"id": "01EVTV5Q0Z5YBBES5EQ4XM43Y2",
"label": "kilo"
}
},
"currentLocation": {
"lat": 41.396,
"long": 2.192
},
"id": "01F5DVJF23DSTG1AN0D0H8J4RG",
"image": null,
"name": "20Kg Wood Scraps"
},
{
"accountingQuantity": null,
"currentLocation": {
"lat": 41.396,
"long": 2.192
},
"id": "01F53XDHGHWM16GNZZR4NP237W",
"image": null,
"name": "A nice shelf"
}
]
}
}
```
:::info
**Alternatively**
**Input**
```
{
agent(id: "01EYJR67EAYVWRW5Z87HNGN16X") {
id
inventoriedEconomicResources {
id
name
}
}
}
```
**Output**
```
{
"data": {
"agent": {
"id": "01EYJR67EAYVWRW5Z87HNGN16X",
"inventoriedEconomicResources": [
{
"id": "01F4VEKYMKKK254AR4W6MXFS9B",
"name": "20Kg Wood Scraps"
},
{
"id": "01F53VBHZXTMJGJP4KNWHDDH21",
"name": "20Kg Wood Scraps"
},
{
"id": "01F5DVJF23DSTG1AN0D0H8J4RG",
"name": "20Kg Wood Scraps"
},
{
"id": "01F53XDHGHWM16GNZZR4NP237W",
"name": "A nice shelf"
}
]
}
}
}
```
:::
### Look at the partial material history: Material Passport WIP
We use the `EconomicResource` `ID` as the staring point. We retrive the `EconomicResource` and use the `track` property to populate an array with the `EconomicEvent` that let to the creation of that particular `EconomicResource`.
:::danger
We can't use the `resourceInventoriedAs` property in the `EconomicEvent` to obtain the `EconomicResource` that was used to create the original `EconomicResource` but because currently is only possible to go **one level back** in the chain.
Read more: https://github.com/dyne/ReflowOS/blob/7f0ebdc53e0d972b9a05f912f6dd2339c4493904/docs/api_tour.md#track-back-from-an-economicresource
:::
The following constrains means Material Inventory will be simplified.
For each Resource we should try to display (if they exist):
* *economicResource.name*
* *economicResource.image*
* *economicResource.note* (description)
* *economicResource.onhandQuantity* (with units, etc)
* *economicResource.currentLocation*
* *economicEvent.provider* (name and avatar and link to profile)
* *economicEvent.receiver* (name and avatar and link to profile exept if = me)
* *economicEvent.action* (type of event with full explanation)
* *economicEvent.note* (what the event was about)
:::success
...any other properties are welcome!
:::
:::info
if `economicEvent.resourceInventoriedAs.id` is different than `economicResouce.id` then we can display the especific properties of that new `economicResource`
:::
**Input**
```
{
economicResource (id: "01F53XDHGHWM16GNZZR4NP237W") {
id
name
track {
id
note
resourceQuantity {
id
hasUnit {
id
}
hasNumericalValue
}
provider {
id
name
}
receiver {
id
name
}
}
note
currentLocation {
id
name
lat
long
}
onhandQuantity {
id,
hasNumericalValue
hasUnit {
id
label
}
}
}
}
```
**Output**
```
{
"data": {
"economicResource": {
"currentLocation": {
"id": "01EX9X4XEXP5EAJRNYQSDW1B23",
"lat": 41.396,
"long": 2.192,
"name": "Fab Lab Barcelona"
},
"id": "01F53XDHGHWM16GNZZR4NP237W",
"name": "A nice shelf",
"note": "Here a description of the shelf",
"onhandQuantity": null,
"track": [
{
"id": "01F53XMFTVXRCYMS25P86WNV47",
"note": "I give back to Guillem the shelf I made with the wood scraps he gived me",
"provider": {
"id": "01EYJR67EAYVWRW5Z87HNGN16X",
"name": "Guillem Camprodon"
},
"receiver": {
"id": "01EXKGV554X3ZHQ707WQRPT178",
"name": "Viktor Smari11"
},
"resourceQuantity": null
}
]
}
}
}
```
### :warning: [PENDING ISSUES] Look at the full material history: Material Passport
:::danger
Not ready. Please, use instead the [section above](#Look-at-the-partial-material-history-Material-Passport-WIP).
:::
We use the `EconomicResource` `ID` as the staring point. We retrive the `EconomicResource` and use the `track` property to populate an array with the `EconomicEvent` that let to the creation of that particular `EconomicResource`. We use the `resourceInventoriedAs` property in the `EconomicEvent` to obtain the `EconomicResource` that was used to create the original `EconomicResource`.
Performing the same action repetively in to the obtained `EconomicResource` _i.e. looking at the `track` property and looking at the corresponding `EconomicEvent`_ we can obtain all the events and resources that were involve on the creation of a single resource, that's what we call the **Material Passport**.

:::warning
Extra Notice :warning:
* Notice we can perform that action by performing multiple recurrent queries but it should be also possible to get the full tree in a single query as we could nest `EconomicResource(s)` to `EconomicEvent(s)` via the `track` property and then `EconomicEvent(s)` back to `EconomicResource(s)` via the `resourceInventoriedAs` property. However, I suggest the first option.
* Notice, also, the `track` property in any `EconomicResource` is an array in order multiple events can lead to the same `EconomicResource`. However, at the current stage we can skip the others and always get the first item `[0]`.
:::
**Input**
```
{
economicResource (id: "01F53XDHGHWM16GNZZR4NP237W") {
id
name
track {
id
note
resourceInventoriedAs {
id
name
}
resourceQuantity {
id
hasUnit {
id
}
hasNumericalValue
}
provider {
id
name
}
receiver {
id
name
}
}
note
currentLocation {
id
name
lat
long
}
onhandQuantity {
id,
hasNumericalValue
hasUnit {
id
label
}
}
}
}
```
**Output**
```
{
"data": {
"economicResource": {
"currentLocation": {
"id": "01EX9X4XEXP5EAJRNYQSDW1B23",
"lat": 41.396,
"long": 2.192,
"name": "Fab Lab Barcelona"
},
"id": "01F53XDHGHWM16GNZZR4NP237W",
"name": "A nice shelf",
"note": "Here a description of the shelf",
"onhandQuantity": null,
"track": [
{
"id": "01F53XMFTVXRCYMS25P86WNV47",
"note": "I give back to Guillem the shelf I made with the wood scraps he gived me",
"provider": {
"id": "01EYJR67EAYVWRW5Z87HNGN16X",
"name": "Guillem Camprodon"
},
"receiver": {
"id": "01EXKGV554X3ZHQ707WQRPT178",
"name": "Viktor Smari11"
},
"resourceInventoriedAs": {
"id": "01F53XDHGHWM16GNZZR4NP237W",
"name": "A nice shelf"
},
"resourceQuantity": null
}
]
}
}
}
```
## Actions
Multiple verbs or actions can be used in `economicEvents` to create and modify `economicResources`.
:::danger
**IMPORTANT CONSIDERATIONS for ACTIONS** :rocket:
1. Some `actions` require to reference an existing `economicResources` where the `economicEvents` will perform the action, this is done via `resourceInventoriedAs`. The `provider` needs to own the existing `economicResource`.
2. Some `actions` require a new `economicResources` is created as part of the `economicEvents`
3. Some `actions` only allow to alter one specific property of the `economicResources` such as `location`
4. Some `actions` require to define the quantity used by the `economicEvents` and this can't exceed the one available at the `economicResources`.
:::
### Actions: dependencies and capabilities
| Action | Accounting affect | Onhand affect | I/O | Changes existence | Pairs with | |
|---------------------|-------------------|---------------|-----------|-------------------|------------|---|
| produce | Increment | Increment | Output | Yes | N/A | |
| consume | Decrement | Decrement | Input | Yes | N/A | |
| use | No effect(1) | No effect(1) | Input | No | N/A | |
| work | No effect(1) | No effect(1) | Input | N/A | N/A | |
| cite | No effect | No effect | Input | No | N/A | |
| pickup | No effect | No effect | Input | No | dropoff | |
| dropoff | No effect | No effect | Output | No | pickup | |
| accept | No effect | Decrement | Input | No | modify | |
| modify | No effect | Increment | Output | No | accept | |
| deliver-service | No effect | No effect | Output(3) | No | N/A | |
| transfer-custody | No effect | Decr+Incr(2) | N/A | No | N/A | |
| transfer-all-rights | Decr+Incr(2) | No effect | N/A | No | N/A | |
| transfer | Decr+Incr(2) | Decr+Incr(2) | N/A | No | N/A | |
| move | Decr+Incr(2) | Decr+Incr(2) | N/A | No | N/A | |
| raise | Increment | Increment | N/A | No | N/A | |
We have defined a core set of actions, but expect that this will be extended with some others. If extended, they should be defined as part of this or another formal vocabulary so that all can use them and assume the same meaning.
1. The actions `use` and `work` are time-based actions, either with or without an explicit schedule. If the schedule is documented as part of the economic resource, then those economic events could decrement that schedule, although not the "current quantity" of the resource.
2. The actions `transfer` and `move` can optionally define a second identified resource on the receiver side.
3. The action `deliver-service` can sometimes also be an input to another process, at the same time as it is an output from a process. This is because services imply delivery as they are created.
[Source](https://valueflo.ws/introduction/flows.html)
### Implemented Actions
We will start by implementing only the following 3 actions:
* **Consume**
* Requires an existing resource
* Can't consume more than what the original resource has
* Creates a new resource as part of the event
* **Transfer**
* Does not requires an existing resource (optional)
* Requires a provider and a receiver
* Does not create a new resource as part of the event
* **Produce**
* Does not requires an existing resource (optional)
* Requires a new resource to be created or an existing one
* Does not requires a second party, a receiver
## Components
Necessary components to perform the flow (TBC)
### Units
1. Create and edit a unit of measurement
createUnit with properties label (string) and symbol (string)
2. Display all the available units in a dropdown
```
{
unitsPages {
edges {
id
symbol
label
}
}
}
```
3. Assign a unit to an Economic Resource via an Economic Event
3. Assign `unit` to an `economicEvent`
### Spatial Thing
1. Create and edit an Spatial Thing
Display a map component allowing a user to locate a marker and retrieve lat and lng
Assign a name to the location
2. Display all the available Spatial Things in a dropdown
```
{
spatialThingsPages {
edges {
id
name
lat
long
}
}
}
```
3. Assign `spatialThing` to an `economicEvent`
### Receiver
1. Select a receiver by allowing to filter available agents based on `name`.
```
{
agents {
id
name
agentType
}
}
```
2. Display agentType to distinguish `persons` from `organizations`.
3. Assign `receiver` to an `economicEvent`
### Action
1. Select an action via a dropdown
```
{
actions {
id
onhandEffect,
label,
note,
resourceEffect,
pairsWith,
inputOutput
}
}
```
2. Assign action to an `economicEvent`
### Economic Resources
1. List the economicResources owned by me
```
{
economicResourcesFiltered(agent: "01EXKGV554X3ZHQ707WQRPT178") {
id,
note
}
}
```
2. Assign resource to an `economicEvent`
# Timelines and activities
## Retrieving last activities for a user
**Input**
```
{
user(userId: "01EYJR67EAYVWRW5Z87HNGN16X") {
id,
inbox {
edges {
id,
verb,
isLocal,
isPublic,
context {
__typename
}
}
}
}
}
```
**Output**
```
{
"data": {
"user": {
"id": "01EYJR67EAYVWRW5Z87HNGN16X",
"inbox": {
"edges": [
{
"context": {
"__typename": "Comment"
},
"id": "01F44BB7E1HCDFJ5NZRMMRV6D9",
"isLocal": true,
"isPublic": true,
"verb": "CREATED"
},
{
"context": {
"__typename": "Comment"
},
"id": "01F3833S686E6SJ6W1BWAG9CFY",
"isLocal": true,
"isPublic": true,
"verb": "CREATED"
},
{
"context": {
"__typename": "Resource"
},
"id": "01F2K7VKAVQTDHAGAHX2B6W3D0",
"isLocal": true,
"isPublic": true,
"verb": "CREATED"
}
]
}
}
}
}
```
## Retrieving an specific activity