| name | hREA Integration |
| description | This skill should be used when working with hREA GraphQL integration, ValueFlows ontology mapping, proposal/intent creation, prerequisite management, or the pending queue system |
hREA Integration
Patterns for the hREA (Holochain Resource-Event-Agent) GraphQL integration layer that maps local entities to ValueFlows economic ontology.
Key Reference Files
- hREA service:
ui/src/lib/services/hrea.service.ts
- hREA store:
ui/src/lib/stores/hrea.store.svelte.ts
- RequestโProposal mapper:
ui/src/lib/services/mappers/request-proposal.mapper.ts
- OfferโProposal mapper:
ui/src/lib/services/mappers/offer-proposal.mapper.ts
- GraphQL queries:
ui/src/lib/graphql/queries/
- GraphQL mutations:
ui/src/lib/graphql/mutations/
- GraphQL fragments:
ui/src/lib/graphql/fragments/
- hREA types:
ui/src/lib/types/hrea.ts
- hREA store test:
ui/tests/unit/stores/hrea.store.test.ts
Architecture Overview
Local Entities hREA Store (mapping layer) hREA DNA (GraphQL)
โโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโ
UIUser โ createPersonFromUser() โ Agent
UIOrganization โ createOrganizationFromOrg() โ Agent
UIServiceType โ createResourceSpecFromST() โ ResourceSpecification
UIMediumOfExch โ createResourceSpecFromMoE() โ ResourceSpecification
UIRequest โ createProposalFromRequest() โ Proposal + 2 Intents
UIOffer โ createProposalFromOffer() โ Proposal + 2 Intents
The GraphQL layer uses @valueflows/vf-graphql-holochain + Apollo Client with SchemaLink.
Three Prerequisites for Proposals
Proposals require all three prerequisites to exist before creation:
- User agent โ created when user is approved (
handleUserAccepted event)
- Service type resource specs โ created when service type is approved
- Medium of exchange resource specs โ created when MoE is approved
If any prerequisite is missing, the request/offer is queued in pendingRequestQueue / pendingOfferQueue.
Pending Queue Mechanism
RequestโProposal Mapping (Two-Intent Reciprocal Pattern)
Each request/offer creates a Proposal with TWO intents:
Request "I need web development"
โ Proposal: name="Request: I need web development"
โ Intent 1 (primary): action="transfer", provider=requester's agent
resourceConformsTo = service type resource spec
โ Intent 2 (reciprocal): action="transfer", receiver=requester's agent
resourceConformsTo = medium of exchange resource spec
The intent linking uses proposeIntent mutation with reciprocal: false for primary intent and reciprocal: true for payment intent.
Action Hash Reference Format
Mappings between local entities and hREA entities use note fields:
ref:user:<actionHash> โ on Agent.note
ref:organization:<actionHash> โ on Agent.note
ref:serviceType:<actionHash> โ on ResourceSpecification.note
ref:mediumOfExchange:<actionHash> โ on ResourceSpecification.note
Lookup: extractActionHashFromNote(note, entityType) extracts the hash.
Error Handling
- Missing zome functions: hREA DNA may not have
get_all_intents / get_all_proposals โ service uses E.catchAll to return empty arrays
- Prerequisite detection:
createProposalFromRequest / createProposalFromOffer use E.catchAll (not E.tapError) โ queue on failure, return null
- Initialization:
createPerson() calls initialize() internally โ don't call separately
- GraphQL normalization: Responses need
normalizeIntentResponse() / normalizeProposalResponse() because GraphQL returns nested objects
Store State
userAgentMappings: Map<string, string>
organizationAgentMappings: Map<string, string>
serviceTypeResourceSpecMappings: Map<string, string>
mediumOfExchangeResourceSpecMappings: Map<string, string>
requestProposalMappings: Map<string, string>
offerProposalMappings: Map<string, string>
agents: Agent[]
resourceSpecifications: ResourceSpecification[]
proposals: Proposal[]
intents: Intent[]
pendingRequestQueue: Map<string, UIRequest>
pendingOfferQueue: Map<string, UIOffer>
Event-Driven Architecture
The hREA store subscribes to storeEventBus events:
| Event | Handler | hREA Action |
|---|
user:accepted | handleUserAccepted | createPerson() โ retryPendingProposals() |
organization:accepted | handleOrganizationAccepted | createOrganization() โ retryPendingProposals() |
serviceType:approved | handleServiceTypeApproved | createResourceSpec() โ retryPendingProposals() |
mediumOfExchange:approved | handleMediumOfExchangeApproved | createResourceSpec() โ retryPendingProposals() |
request:created | handleRequestCreated | createProposalFromRequest() |
offer:created | handleOfferCreated | createProposalFromOffer() |
Testing hREA
Tests need module mocks for external dependencies:
vi.mock('@valueflows/vf-graphql-holochain', () => ({
createHolochainSchema: vi.fn()
}));
vi.mock('@apollo/client/link/schema', () => ({
SchemaLink: vi.fn()
}));
Note: hrea.service.ts createPerson() calls initialize() internally โ don't call it separately in tests.