Conversation
…hannels Convert person, resource, and governance services from Promise-based class methods to Effect<T, DomainError> plain-object services using wrapZomeCallWithErrorFactory. No raw try/catch blocks remain. - PersonService: all 13 methods return E.Effect<T, PersonError> - ResourceService: all 12 methods return E.Effect<T, ResourceError> - GovernanceService: all 16 methods return E.Effect<T, GovernanceError> Part of #7 (Effect-TS 7-layer architecture)
Replace direct singleton imports with proper Effect DI: Services (Context.Tag + Layer.effect): - PersonServiceTag/Live/Resolved with HolochainClientServiceTag dep - ResourceServiceTag/Live/Resolved with HolochainClientServiceTag dep - GovernanceServiceTag/Live/Resolved with HolochainClientServiceTag dep HolochainClientService: - Add HolochainClientServiceTag + HolochainClientServiceLive (Layer.succeed wrapping the existing singleton) Stores (E.gen factory + E.provide + E.runSync): - PersonStore: E.gen yields PersonServiceTag; instance via pipe(createPersonStore(), E.provide(PersonServiceResolved), E.runSync) - ResourceStore: same pattern with ResourceServiceResolved - GovernanceStore: same pattern with GovernanceServiceResolved All store methods remain async; withLoadingState from store-helpers manages isLoading/errorMessage rune state. Part of #7 (Effect-TS 7-layer architecture)
…ation status - Add 8 missing GOVERNANCE_CONTEXTS constants (UPDATE_COMMITMENT, GET_COMMITMENTS_BY_PROVIDER, GET_COMMITMENTS_BY_RECEIVER, GET_EVENTS_BY_TYPE, GET_EVENTS_IN_TIME_RANGE, GET_RESOURCE_FLOW, CREATE_DISPUTE, VOTE_ON_DISPUTE) to error-contexts.ts - Update governance.service.ts to use the correct context for each method (was reusing GET_COMMITMENT, GET_EVENTS_BY_AGENT, GET_PENDING_COMMITMENTS, CREATE_COMMITMENT, EVALUATE_STATE_TRANSITION across unrelated operations) - Remove duplicate JSDoc block from holochain.service.svelte.ts - Mark Effect-TS service layer (#7) as complete in IMPLEMENTATION_STATUS.md
…lidateGovernanceRules context - governance.store: fetchMyCommitmentsAsProvider/Receiver now delegate to fetchCommitmentsByProvider/Receiver so the commitmentsByProvider/Receiver maps stay in sync (regression introduced during Effect refactor) - governance.store: fetchMyEconomicEvents now delegates to fetchEventsByAgent so the eventsByAgent map stays in sync - resource.store: fetchMyResources now delegates to fetchResourcesByCustodian so the resourcesByCustodian map stays in sync - Add VALIDATE_GOVERNANCE_RULES context constant and use it in validateGovernanceRules instead of EVALUATE_STATE_TRANSITION
…error contexts - clearError() in all 3 stores: remove unconditional isLoading = false; only clear errorMessage to avoid cancelling active loading indicators mid-flight - fetchMyCommitmentsAsProvider/Receiver, fetchMyEconomicEvents, fetchMyResources: use run() (withLoadingState) directly against the service instead of delegating to the raw E.runPromiseExit helpers; also update the cache maps so behaviour is identical to the internal helpers - resource.service.ts: add 4 specific RESOURCE_CONTEXTS constants (UPDATE_RESOURCE_QUANTITY, SEARCH_RESOURCES_BY_SPECIFICATION, GET_RESOURCE_HISTORY, ARCHIVE_ECONOMIC_RESOURCE) and wire them in place of the previously mismatched generic entries
… arrays - Add comment above fetchCommitmentsByProvider/fetchCommitmentsByReceiver/fetchEventsByAgent clarifying these are intentional background cache-refresh helpers that do not manage isLoading/errorMessage; direct callers should use fetchMy* methods for loading state - Add TODO comments on allCommitments, allEconomicEvents, allEconomicResources noting they are never populated; to be wired or removed before UI layer connects
| | Agent promotion + role validation workflows | 🔄 Partial | | ||
| | Frontend UI components | ❌ Not started | | ||
| | Effect-TS service layer | ❌ Not started | | ||
| | Effect-TS service layer | ✅ Complete (PR #97) | |
There was a problem hiding this comment.
🔴 REVIEW.md violation: DOCUMENTATION_INDEX.md not updated after feature milestone completion
Per REVIEW.md §6 (Documentation Currency), when a feature milestone is completed, both documentation/IMPLEMENTATION_STATUS.md and documentation/DOCUMENTATION_INDEX.md must be updated. This PR marks the Effect-TS service layer as ✅ Complete at documentation/IMPLEMENTATION_STATUS.md:181 and documentation/IMPLEMENTATION_STATUS.md:244, but documentation/DOCUMENTATION_INDEX.md was not modified. The REVIEW.md mapping table explicitly states: "Feature milestone completed (phase advancement) → documentation/IMPLEMENTATION_STATUS.md, documentation/DOCUMENTATION_INDEX.md".
Prompt for agents
The PR marks 'Effect-TS service layer' as complete in IMPLEMENTATION_STATUS.md (line 181 and line 244), but per REVIEW.md rule 6, documentation/DOCUMENTATION_INDEX.md must also be updated when a feature milestone is completed. Open documentation/DOCUMENTATION_INDEX.md and add or update the entry for the Effect-TS service layer to reflect its completion in PR #97. The exact location in DOCUMENTATION_INDEX.md depends on how the file is structured — look for any section referencing the UI service layer, frontend architecture, or issue #7.
Was this helpful? React with 👍 or 👎 to provide feedback.
Intent
Wire the Effect-TS infrastructure (errors, schemas, utilities) already in place to the actual services and stores. Before this PR, all three zome services used raw Promise-based class methods with try/catch, and all three stores used a 4-state string enum for loading state. The Effect layers (wrapZomeCallWithErrorFactory, withLoadingState, store-helpers) were implemented but not consumed.
Changes
HolochainClientService: adds
HolochainClientServiceTag(Context.Tag) andHolochainClientServiceLive(Layer.succeed wrapping the singleton) — the DI entry point that services depend on.Zome services (person, resource, governance): converted from Promise-based class methods to the R&O Context.Tag/Layer pattern:
E.Effect<T, DomainError>ServiceTag extends Context.TagServiceLive: Layer.effect(Tag, E.gen(function* () { const client = yield* HolochainClientServiceTag; ... }))ServiceResolvedpre-wires HolochainClientServiceLive for convenient use in storesStores (person, resource, governance): converted from ad-hoc async/try-catch to the R&O factory pattern:
E.Effect<Store, never, ServiceTag>viaE.genyield* ServiceTag, removing all direct service importswithLoadingStatefrom store-helpers; loading state migrated from 4-state enum toboolean isLoading+string|null errorMessagepipe(createStore(), E.provide(ServiceResolved), E.runSync)Decisions
Loading state model change: The previous 4-state string enum (
'idle' | 'loading' | 'success' | 'error') was replaced withboolean isLoading+string|null errorMessage. Rationale: the 4-state model required components to match on strings and carried no additional information beyond what the two booleans express. The Effect error channel already carries typed error information; the store's job is only to surface whether an operation is in-flight (isLoading) and whether the last operation left an error message (errorMessage). This simplifies both the store implementation and consumer components.Error context constants: Added 8 missing constants to
GOVERNANCE_CONTEXTSinerror-contexts.ts(UPDATE_COMMITMENT,GET_COMMITMENTS_BY_PROVIDER,GET_COMMITMENTS_BY_RECEIVER,GET_EVENTS_BY_TYPE,GET_EVENTS_IN_TIME_RANGE,GET_RESOURCE_FLOW,CREATE_DISPUTE,VOTE_ON_DISPUTE) and updated all mismatchedwz()calls in the governance service to use the correct contexts.How to test
bun run --filter ui check # 0 errors, 0 warningsDocumentation
Updated
documentation/IMPLEMENTATION_STATUS.mdto mark the Effect-TS service layer (#7) as complete (was ❌ Not started in both the UI Components list and the Phase 2 progress table).Related
Epic
Partial implementations (what this PR covers from each issue)
error-contexts.tswith 8 missingGOVERNANCE_CONTEXTSconstantsHolochainClientServiceTag+HolochainClientServiceLive; all three zomeServiceTag+ServiceLive+ServiceResolvedConnectionServiceTagwith exponential backoff retry; unit tests per servicewithLoadingState,isLoading/errorMessageuseRoleGuard,usePersonManagement,useRolePromotion); Layer 7 testswithLoadingState,isLoading/errorMessageuseResourceBrowser,useResourceCreation); Layer 7 testswithLoadingState,isLoading/errorMessagecustody-transfer,agent-promotion,resource-validation,economic-process); full store state (validationQueue,pendingRoleRequests); Layer 5 composables; Layer 7 tests