h-REA / hREA

A ValueFlows / REA economic network coordination system implemented on Holochain and with supplied Javascript GraphQL libraries
https://docs.hrea.io
Other
142 stars 15 forks source link

conditionally inject 'Person' or 'Organization' `__typename` field based on `agentType` field #327

Closed weswalla closed 2 years ago

weswalla commented 2 years ago

places to do this:

pospi commented 2 years ago

Hmm, I'm actually not sure that is the correct location for it. (But not 100% sure).

I think the ideal is for the backend to drive this, and it will need to do so eventually as we are yet to have a way to read all people independently of reading all organisations.

So- I think we will need this to be handled in the backend in a way that the frontend can infer types from. Those injectTypename helpers are still needed in the frontend, but they will do their thing transparently, based on the data returned from each endpoint. The only place we'll need to inspect the "type" field in the resolvers is in agent and agents, since they can return either type.

In the backend, we will actually want indexes for both. You will need to read the value of the field and create a "self" index (only has one side) based on the data. I think for simplicity's sake I would make it a validation error to update that field once created - you shouldn't be able to convert a Person to an Organization or vice-versa once created. Check out the hdk_semantic_indexes_client_lib macros for "self-referential, local-only indexes" in order to create an index that only lives in the local DNA. Then you can add records into either index based on what type they are- once you have done that you should be able to easily query all agents of either type.

Connoropolous commented 2 years ago

I think for simplicity's sake I would make it a validation error to update that field once created - you shouldn't be able to convert a Person to an Organization or vice-versa once created.

How would we know when to throw a validation error versus just to suppress the proposed changes (which is what I think we currently do). Probably there are lots of circumstances that have been written into the codebase such that it won't error but rather simply not update

Connoropolous commented 2 years ago

Ok so... it sounds like we are going to up-scope this issue a little bit. That's ok.

The goal then is to create two indexes within Agent, one for people and one for organizations

@weswalla if we are going to do this, here's what I've found about this:

Here is an example of a create_index! with only one type instead of two https://github.com/h-REA/hREA/blob/06bc44c1c75739ddfb67c44a5202654f73dc223b/zomes/rea_economic_resource/lib/src/lib.rs#L95

here's the index definition (for contained_in) https://github.com/h-REA/hREA/blob/06bc44c1c75739ddfb67c44a5202654f73dc223b/zomes/rea_economic_resource/zome_idx_observation/src/lib.rs#L28-L31

pegahvaezi commented 2 years ago
 #[index_zome] 
 struct Agent { 
     agent_type: Local<agent, agent_type_internal>, 
     agent_type_internal: Local<agent, agent_type>, 
}
 let e = create_index!(agent(&base_address).agent_type(&agent_type)); 
pegahvaezi commented 2 years ago

also add agent_type to QueryParams

it's value type is String

leave a comment that it's internal https://github.com/h-REA/hREA/blob/c7092a0b886bf1dbee81876f7627bf5783b33355/zomes/rea_agent/rpc/src/lib.rs#L142-L159

pegahvaezi commented 2 years ago

for example, use the same or similar as resolvers use:

https://github.com/h-REA/hREA/blob/7025be075758f4d947364c07aab0aca7cb262f0f/modules/vf-graphql-holochain/resolvers/process.ts#L39

and pass params: https://github.com/h-REA/hREA/blob/7025be075758f4d947364c07aab0aca7cb262f0f/modules/vf-graphql-holochain/resolvers/process.ts#L58

weswalla commented 2 years ago

let e = create_index!(agent(&base_address).agent_type(&agent.agent_type));

gives the following error:

error[E0277]: the trait bound `String: DnaAddressable<holo_hash::hash::HoloHash<holo_hash::hash_type::primitive::Entry>>` is not satisfied
   --> zomes/rea_agent/lib/src/lib.rs:36:13
    |
36  |     let e = create_index!(agent(&base_address).agent_type(&agent.agent_type));
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `DnaAddressable<holo_hash::hash::HoloHash<holo_hash::hash_type::primitive::Entry>>` is not implemented for `String`
    |
note: required by a bound in `hdk_semantic_indexes_client_lib::manage_index`
   --> /Users/wesleyfinck/1_Projects/sprillow/hREA/lib/hdk_semantic_indexes/client/src/lib.rs:240:12
    |
240 |         B: DnaAddressable<EntryHash>,
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `hdk_semantic_indexes_client_lib::manage_index`
    = note: this error originates in the macro `create_index` (in Nightly builds, run with -Z macro-backtrace for more info)

and

error[E0277]: the trait bound `std::string::String: hdk_uuid_types::DnaAddressable<HoloHash<hdk::prelude::holo_hash::hash_type::Entry>>` is not satisfied
  --> zomes/rea_agent/zome_idx_agent/src/lib.rs:24:1
   |
24 | #[index_zome]
   | ^^^^^^^^^^^^^ the trait `hdk_uuid_types::DnaAddressable<HoloHash<hdk::prelude::holo_hash::hash_type::Entry>>` is not implemented for `std::string::String`
   |
note: required by a bound in `hdk_semantic_indexes_zome_lib::query_index`
  --> /Users/wesleyfinck/1_Projects/sprillow/hREA/lib/hdk_semantic_indexes/zome/src/lib.rs:94:12
   |
94 |         A: DnaAddressable<EntryHash>,
   |            ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `hdk_semantic_indexes_zome_lib::query_index`
   = note: this error originates in the attribute macro `index_zome` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `hdk::prelude::Entry: From<std::string::String>` is not satisfied
   --> zomes/rea_agent/zome_idx_agent/src/lib.rs:24:1
    |
24  | #[index_zome]
    | ^^^^^^^^^^^^^ the trait `From<std::string::String>` is not implemented for `hdk::prelude::Entry`
    |
    = help: the following implementations were found:
              <hdk::prelude::Entry as From<HoloHashed<hdk::prelude::Entry>>>
    = note: required because of the requirements on the impl of `Into<hdk::prelude::Entry>` for `std::string::String`
    = note: required because of the requirements on the impl of `std::convert::TryFrom<std::string::String>` for `hdk::prelude::Entry`
note: required by a bound in `hdk_semantic_indexes_zome_lib::query_index`
   --> /Users/wesleyfinck/1_Projects/sprillow/hREA/lib/hdk_semantic_indexes/zome/src/lib.rs:100:16
    |
100 |         Entry: TryFrom<A, Error = E>,
    |                ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `hdk_semantic_indexes_zome_lib::query_index`
    = note: this error originates in the attribute macro `index_zome` (in Nightly builds, run with -Z macro-backtrace for more info)
weswalla commented 2 years ago

@pospi @Connoropolous not quite sure the best way to deal with the trait bound requirements in this situation. Is it even possible for the destination of the create index to be a string, or will we need to create a custom type implementing the required traits?