-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement facets zome / DNA as a mix-in module #1
Comments
@fosterlynn I think we'll need to give some consideration to facet updates. I figure we will probably also want a |
@LeosPrograms I can recommend the Neighbourhoods sensemaker as a good template to follow for setting up this new repository. Latest on this branch (or There is also code for creating & testing any JavaScript client libraries but I don't think we will need those here, will probably do direct GraphQL bindings in hREA. Or maybe in the Carbon Farm app. Need to have a think about upstream but my sense is that implementations standardising different non-VF extensions is fine; Bonfire are doing it with all the social extensions. |
For indexing helpers I can also recommend the helper libs in hREA, which aren't published to crates.io but you can still use them with
etc. There is only one example of a string-based index in the codebase: Agent types. See the index definition zome (paying attention to the |
Possibly more kind is to add a
Hmmm. Yes. I think my opinion is that we support updates, and trust the user to not change the meaning. Other opinions welcome. [EDIT: Changed my mind, see below.]
Just one FacetValue per Facet per record. [EDIT} |
If we need updates then I would also recommend following the pattern used in the hREA zomes, via import of
|
Actually, updates can wait, they aren't a priority for this release. In a pinch, they can remove, delete, re-add everything. And there won't be a lot of data for a while. [edit: changed my mind, let's do updates] |
Updated the proposed API to reflect the addition of |
Also have been reflecting that these types of modules are fine - #1 (comment) ...but for something like this it might be much simpler and more efficient to manage your own link structures rather than trying to use generic record management libraries like |
As we worked on the UI, I changed my mind back, and we included updates. 😓 If anyone disagrees, let's revisit. It just seemed too annoying and confusing to make people delete and add. |
A side-note to @LeosPrograms that there are some scripts in VF GraphQL which you might be able to steal from in order to reduce boilerplate (and not have to redeclare all your GraphQL types in TypeScript manually). See graphql-codegen on NPM, this config file and this package script. Easy enough to configure & run before build, and then you can just commit it like a metadata file after altering the schema defs. |
Initial spec now updated to match latest conversations. @fosterlynn please let us know if there still feels to be any discrepancy in our understanding of the problem space. (And apologies to @LeosPrograms for any unnecessary refactoring needed.) One final question RE spec I have now is for reverse queries to load lists of assigned records. Do we need |
No pagination needed for any of the facet data. There will never be very much data. I don't know if you need a FacetValueAssignment.record union. I suppose if you are going to use just one class for the assignment, you will need that. [EDIT: But doesn't that sort of negate the point of putting the assignment into the facet zome?] P.S. Please take a look at the model for all naming, although I just thought of one improvement, which I'll make soon there: |
Possible GraphQL API revision to consider: You could likely remove |
@fosterlynn I think in this you're essentially saying that facets display is a priority ("show me all the declared Facets for this Organization"), facets querying is not in scope yet ("find me all the Organizations who are Farmers"). |
Facets querying is in scope from the map search. But @happysalada has said that he doesn't need to use the actual fields for that, the users can type any text from anywhere in the returned data and it will work. I'll let him explain that. On the other hand, if we are writing a general purpose facets module, we can consider allowing for the "find me all the Organizations who are Farmers" query. Let's discuss. Then repeating from chat, here are the main ways the UI will want facets loaded are:
The other one I can think of is for initial creation of the Facets and FacetValues, but 1. can work for that, to show what already exists. And that won't be used very often. |
Do you mean Organization.facetValues and ResourceSpecification.facetValues? And just to make sure, you are understanding that Organization to FacetValue is a M:M, right, irrespective of revisions? |
here is the search function (it might need a bit of an update, but it was working last year).
basically go through each object and do string matching. So as long as the agents have the facets included, then search should work. |
I mean, in terms of the datatypes actually being linked I do (or
Correct. |
I don't think so, I think we should say what we mean, and |
Getting to this request!
Let's clean this up to use the terms we are using, I don't actually know what this means.
We shouldn't allow deletion of a FacetValue if there are stored FacetValueAssociations that reference it. The user can go remove or change the association first if needed. Also, we should get rid of the term "option" and say what it is in the model. And I would prefer we use FacetValueAssociation, not FacetAssociation, which would mean something else. Also in the param names, get names, wherever it occurs. Actually, I see later on you did use FacetValueAssociation. Let's use that everywhere!
I don't see that we need facet or facet group as parameters for any known use cases. Am I missing something? Best to keep it simpler, especially for this round of development, imo. Especially we don't need facet group, that will follow naturally, and a record will be only related to facet values part of one group. Also note that some apps won't need FacetGroup at all, it should be optional in a generic facet model that can be used outside of Carbon Farm Network.
On the above,
The above should include
I don't think we want this.
This confuses me. Either the FacetValueAssignment needs to include the record reference or it is not a type, it is a property. Or is I'll add another comment later to continue my review, need a bit more time to think about all the reference names you are using. |
Possibly OT, but just to make sure we're clear: "Farmer" is a role in the network, not done with facets. (In the non-hacked model, these roles involve 2 agents.) |
We should develop this module in isolation and genericise for applicability to any Holochain apps.
(For reference, see also draft specification here.)
Design constraints to consider:
FacetValues
should be associate-able to any string-based record identifier. This enables modules like hREA (which uses a custom fully-qualified UUID format) to leverage facets alongside standard Holochain zomes (which often use a rawUint8Array
to represent anEntryHash
) and any application-specific non-Holochain data encodeable to a string format (eg. web URLs).FacetValues
should be validated against pre-allowed options perFacet
.Facet
option data needs to be indexed for efficient retrieval byrecord_type
.API sketch below (please edit / suggest), where
*_eh
indicates a field referencing some otherEntryHash
;EntryHash
for managing updates andActionHash
for managing deletions; andExternResult
struct not included in any of the below definitions, though they are mostly Rust-compatible.GraphQL mutations to implement as zome API endpoints in
extension-resolvers.ts
:putFacetGroup(GroupSaveParams { name, note }: GroupSaveParams)
(in our case,name
="Agent"
or"ResourceSpecification"
)deleteFacetGroup(ActionHash)
to remove an erroneously declaredFacetGroup
putFacet(FacetSaveParams { facet_group_eh, name, note }: FacetSaveParams)
FacetGroups
are treated as distinct, and can only be queried independently.)deleteFacet(ActionHash)
putFacetValue(FacetValueSaveParams { facet_eh, value, note }: FacetValueSaveParams)
wherefacet_eh: EntryHash
of relatedFacet
note
is just a "meta-descriptor" field for more information about the meaning of thevalue
deleteFacetValue(ActionHash)
to remove a previously allowed option for aFacet
in case of error or change.FacetAssociations
(below) so that UIs can decide whether to display the redacted reference on other records.associateFacetValue(FacetAssociationParams { identifier: String, facet_value_eh: EntryHash }: FacetAssociationParams)
whereidentifier
is any string referencing an external record; andfacet_value_eh
references anEntryHash
returned byputFacetValue
andgetFacetValues
as aFacetValue.id
deassociateFacetValue(ActionHash)
GraphQL query APIs & sub-record resolvers to implement in
extension-resolvers.ts
:getFacetGroups() -> Vec<FacetGroup>
getFacetsForGroup(FacetGroupLoadParams { facet_group_eh: EntryHash }: FacetGroupLoadParams) -> Vec<Facet>
getFacetValues(ValuesLoadParams { facet_eh }: ValuesLoadParams) -> Vec<FacetValue>
getAssociatedFacets(AssociationQueryParams { identifier, facet_ehs, facet_group_ehs }: AssociationQueryParams) -> Vec<FacetValue>
wherefacet_eh
andfacet_group_eh
are both optionalFacetValues
for the recordidentifier
.facet_ehs
andfacet_group_ehs
GraphQL zome API methods we could optionally implement:
getAllFacetValues() -> HashMap<EntryHash, HashMap<EntryHash, FacetValue>>
but I think honestly depending on the way you wire up the GraphQL this should be a non-critical convenience method.getFacetGroups()
gives you a root to start from and you can then simply hang calls togetFacetsForGroup
off aFacetGroup.facets
resolver and go from there.GraphQL type field resolvers will need to be implemented in order to wire up a complete solution that lets us traverse "downward" from all
FacetGroups
to possibleFacetValues
; as well as "upward" fromOrganization
andResourceSpecification
records back to associatedFacetValues
etc. Here is a quick spec to match with the above:Note the
id
andrevisionId
fields in each record to populate with string-encodedEntryHash
andActionHash
from the zome APIs.FacetValueAssignment.id
is not defined since this metadata is unimportant to that record type (it's only retrieved via filtering onidentifier
andfacet_value_eh
).I'm also making the call in this API design to do away with pagination and Relay data structures. I don't think we really need it- there are unlikely going to be hundreds of
FacetGroups
in most applications, let alone this smaller-scale bioregional textile network.The text was updated successfully, but these errors were encountered: