refactor: split oversized mock API into focused domain modules (Closes #383) - #397
Merged
Lakes41 merged 1 commit intoAug 20, 2026
Merged
Conversation
…Adamantine-guild#383) Organize the ~1,800-line lib/api/mock.ts into focused modules under lib/api/mock/ (state, session, core, members, analytics, webhooks, approvals, social, moderation, governance, controls, scenarios) and turn mock.ts into a thin aggregator that composes MockAccessApi and re-exports every historical symbol, so no consumer imports change. Also fix compile errors that lived in this file: add 'invalid_state' to ApiErrorCode (used by governance methods), complete the legacy persisted-state load with proposals/votes, and route social-store reassignment through owning-module setters (fixes a latent blockMember runtime crash under ESM/CJS module semantics). 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #383 —
lib/api/mock.tshad grown to ~1,800 lines and contained every mock API domain (the in-memory store, persistence orchestration, SIWE/session simulation, member/resource/policy reads, webhooks, approvals, social graph, moderation, governance, analytics, fault-injection controls, and developer scenario presets) in a single file. Any structural mistake anywhere in it blocked the entire API layer from compiling, and the blast radius extended to consumers such aslib/api/index.tsandcomponents/nav.tsx.This PR reorganizes the mock implementation into 12 small, focused modules under
lib/api/mock/, each with a single, clearly documented responsibility, and reduceslib/api/mock.tsto a ~400-line aggregation point that composesMockAccessApiand preserves every existing export. No API behavior is removed and no consumer import needs to change.Before / After
lib/api/mock.tsMockAccessApiforwards)lib/api/mock/, each 34–413 linesinvalid_state×5,Cannot assign to import×3, legacy-state shape ×1)MockAccessApi,getCommunityState(),communityStates, developer controls, etc.New module layout (
lib/api/mock/)fixtures.ts(edited)state.ts(new)communityStates,getCommunityState(),ensureAddress(),initPromise,schedulePersist(),createMockStreamEvent(), beforeunload persistencesession.ts(new)getNonce/siweVerify/siweRefresh/siweLogout/getSessionStatus), nonce stores/TTL, and thecookie-auth-mode session-cookie simulationcore.ts(new)members.ts(new)analytics.ts(new)AnalyticsDataSourcesurfacewebhooks.ts(new)replayEvent, standalonereplayMockEvent(), admin event log paginationapprovals.ts(new)assignRole/removeRole/updatePolicy) + the multi-approval pending-action flowsocial.ts(new)moderation.ts(new)governance.ts(new)controls.ts(new)setMockRoleMutationFailure,setMockResourceFetchFailure,setMockResourceFetchDelay) and the API-version overridescenarios.ts(new)applyMockScenario) andresetMockData()How
MockAccessApicomposes the modulesEach class method forwards to its domain module through a fresh per-call
MockApiContext(address, communityId, and the currentauthModeread fromconfigat call time). Building the context per call — rather than capturing it at construction — is deliberate: it keepsconfig-derived values fresh across module reloads, which the cookie-mode session tests (test/mock-cookie-session.test.ts,test/session-cookie-mode.test.ts) rely on when they invalidate thelib/configandlib/api/mockrequire caches.No circular imports exist: the dependency graph is strictly layered —
errors/fixtures→state→ domain modules →mock.tsaggregator.Behavioral parity & correctness
lib/api/index.ts(viamock-boundary.ts)lib/api/mock-boundary.tslib/billing/mock.ts(getCommunityState)MockAccessApi,resetMockData,applyMockScenario,replayMockEvent,setMockRoleMutationFailure,setMockResourceFetchFailure,setMockResourceFetchDelay,setMockMetaVersiondirectly fromlib/api/mockreplayMockEventvsMockAccessApi.replayEventkept distinct — the standalone dev-tool export still applies member-store side effects; the class method does not (matching the original).Latent bugs fixed in the process (within the refactored file)
invalid_statenot a validApiErrorCode— 5 governance methods constructedApiErrors withcode: 'invalid_state', which failed the typecheck and prevented compilation. Added'invalid_state'to the union inlib/api/errors.ts(behavior preserving — runtime code values unchanged).proposals/votes— the backward-compat branch of the store initializer didn't satisfy theCommunityStateshape. It now initializes both to{}, matchinggetCommunityState()'s defaults.blockMembercrashed at runtime — reassigning an imported binding (mockConnections = mockConnections.filter(…)) throws under both ESM semantics and the CJS test build (“Cannot set property mockConnections … which has only a getter”). The original code failed onmainas soon as the social-graph domain was exercised in a test build. Reassignment now happens inside the owning module (fixtures.ts) via explicit setters (setMockConnections/setMockPrivacySettings/setMockReports), restoring the intended behavior.MOCK_META_VERSION_OVERRIDE/ control flags remain module-scoped insidecontrols.ts, with read-only accessors, soresetMockData()semantics are unchanged (meta override intentionally not reset, matching the original).Verification
tsc --noEmit(root)lib/wallet,app/…,components/…).tsc -p test/tsconfig.jsonnext lint --file …)setTimeouttiming assertion (mock-controls), passing on re-run with an identical code path tomain.mainvia an A/B stash run:analytics-flag(wagmihttpimport),api-mock-boundary(missingsetup-envalias registration),check-env/portfolio-analytics(env-dependent),siwe-threat-model(docs/env). None touch the mock API.private/public, block/unblock, connection accept/reject), moderation (report state transitions), approvals (2-of-2 pending-action flow), webhooks (replay, pagination), analytics (summary + data source), and scenarios (multiple-communities). All passed — the same script crashes onmainatblockMember, demonstrating the latent social-graph bug.next build(root)react/no-unescaped-entities,SiweAuthContextTypetype errors) that exist identically onmain; the refactored mock layer is not among them.Design decisions worth flagging for review
MockApiContextcarriesauthMode— session functions read the cookie-vs-bearer flag from the call context instead of importingconfigthemselves. This sidesteps a stale-module-binding problem that would break the cookie-mode tests, and keepsconfiga single, fresh read site (mock.ts).MockAccessApivia standalone domain functions + thin forwards was chosen over TS mixins: it's type-safe, keeps the class declaration readable, avoids private-field plumbing (#nonceStorepasses explicitly to session functions), and makes each domain independently testable.scenarios.tsre-exports throughmock-boundary.tsunchanged —lib/api/index.ts's public developer surface is byte-for-byte identical.docs/mock-api-boundaries.mdnow documents the module table, the new fixture mutation rules (ownership ofletbindings), and updated behavior-implementation guidance.Files changed
Modified:
lib/api/mock.ts— rewritten as aggregator/MockAccessApicomposition (1,807 → 409 lines)lib/api/mock/fixtures.ts— added mutable-store setters (keeping the originalletbindings)lib/api/errors.ts— added'invalid_state'toApiErrorCodedocs/mock-api-boundaries.md— documents the new module structure and rulesAdded:
lib/api/mock/{state,session,core,members,analytics,webhooks,approvals,social,moderation,governance,controls,scenarios}.ts(12 files)Unchanged (by design):
lib/api/index.ts,lib/api/mock-boundary.ts,lib/billing/mock.ts— no consumer changes requiredOut of scope / follow-ups
SiweAuthContextType, wallet bundle, etc.) predate this PR and are tracked separately.lib/api/live.ts(~1,400 lines) could benefit from the same domain-module treatment in a follow-up.Testing commands run:
tsc --noEmit·tsc -p test/tsconfig.json --skipLibCheck·next lint(changed files) ·node --test(full suite + focused mock batch) · end-to-end smoke script ·next build --no-lint(verify no mock-layer compile errors).