Platform Docs
Membloc app ↔ app-engine API sync gap audit
/platform/app-engine-api-sync-gap-auditMembloc app ↔ app-engine API sync gap audit
Date: 2026-05-13
Scope: read-only multi-repo audit across membloc-app, membloc-app-engine, membloc-sdk, membloc-developer-portal, docs, and membloc-docs/content.
Current status, 2026-07-02: this audit is historical evidence. Since it was written, the app bridge gained module-token and runtime data routing. The current SDK support matrix lives in
docs/sdk-platform-truthfulness-2026-07-02.md; storage, activity, notifications, settings persistence, confirm, share-to-channel, and real auth/family payload wiring still must not be claimed as stable public SDK APIs.
Executive summary
The app-engine has substantial domain API coverage for auth bootstrap, family, files, chat, calendar, memories, archives, FCM tokens, marketplace, publisher/admin, module installation, and runtime data routes. The biggest remaining gaps are not simple route absence; they are integration seams where the Flutter app and SDK still assume Firebase/Cloud Functions or local stubs while app-engine routes exist but are not wired.
Highest-priority findings:
- P0 - WebView module runtime is not end-to-end usable through the app bridge. SDK methods are typed/documented, but
JsBridgeControllerreturns stub data for auth/family/data/settings and does not route storage, notifications, activity, confirm, or share-to-channel. App token retrieval returns a Firebase ID token, while app-engine runtime routes require a module-scoped token. - P0/P1 - Marketplace install/uninstall is not wired in the app. app-engine exposes install/uninstall/list installed routes, but the Flutter
MarketplaceApiinstall/uninstall methods only check auth and contain TODOs. - P1 - Default app boot remains Firebase-backed unless an explicit
MEMBLOC_BACKEND_MODE=engineflag is set. Even the engine domain bridge keeps notification Firebase-backed until full bridge mode. - P1 - Many native module features and trip flows still use Firebase/Cloud Functions directly, with no engine adapters or dedicated engine data model. app-engine has generic
module_data, but existing native Flutter module services are not using it. - P2 - Family/onboarding semantics are shape-mismatched. The app sends family shape hints and represented-person related user IDs; app-engine ignores those fields. Pending household request behavior is also collapsed into synchronous join.
- P2/P3 - Publisher/admin current portal flows are mostly backed, but planned docs include team-member, module delete/version, and admin unsuspend endpoints that app-engine does not expose yet. Portal asset uploads still use Firebase Storage.
Current architecture map
- Flutter app (
membloc-app) initializes Firebase and Firestore persistence on boot (membloc-app/lib/main.dart:30-35) and uses Firebase auth state for top-level routing (membloc-app/lib/main.dart:76-78). Repository injection can flip to app-engine only whenAppConfig.engineFullBridgeis true (membloc-app/lib/main.dart:39-45;membloc-app/lib/core/config/app_config.dart:20-26). - Repository seam (
membloc-app) defaults every domain repository to Firebase (membloc-app/lib/core/repositories/membloc_repositories.dart:61-80).engineFullBridgeswaps auth/family/channel/memory/calendar/archive/notification/storage to engine adapters (membloc-app/lib/core/repositories/membloc_repositories.dart:351-370), but global lazy default remains Firebase (membloc-app/lib/core/repositories/membloc_repositories.dart:374-379). - app-engine (
membloc-app-engine) is an Echo backend. Authenticated/api/*routes use Firebase-auth-derived user identity. Separate/api/runtime/:moduleKey/families/:familyId/*routes use module-scoped JWT middleware (membloc-app-engine/internal/auth/runtime_middleware.go:11-39). - WebView SDK/runtime (
membloc-sdk+ app bridge) expects JS calls to go through the Flutter bridge and then to runtime APIs. The SDK exposes data/storage/notifications/activity/ui/settings methods (membloc-sdk/membloc-sdk.js:140-252;membloc-sdk/membloc-sdk.d.ts:93-140), but bridge handlers are partially stubs (membloc-app/lib/core/modules/js_bridge_controller.dart:172-257). - Developer portal (
membloc-developer-portal) calls app-engine publisher/admin endpoints via Firebase bearer auth (membloc-developer-portal/src/lib/portal-api.ts:79-307per worker-4 audit). Current portal flows are broadly covered by engine routes (membloc-app-engine/cmd/server/main.go:344-385); asset upload uses Firebase Storage (membloc-developer-portal/src/lib/storage-upload.ts:3-47). - Docs/plans describe WebView runtime completion criteria and remaining automation gaps (
docs/phase2-webview-runtime.md:585-651;membloc-docs/content/operations/phase3-qa-runbook.md:253-265).
Gap matrix
| Area | App expectation | Engine status | Evidence | Severity | Suggested fix | Test needed |
|---|---|---|---|---|---|---|
| Default backend selection | Product app should run against app-engine-backed domain repositories when engine migration is considered complete. | Engine bridge exists but is opt-in only; default stays Firebase. | MEMBLOC_BACKEND_MODE defaults to firebase and only engine enables bridge (membloc-app/lib/core/config/app_config.dart:20-26); main.dart logs Firebase default otherwise (membloc-app/lib/main.dart:39-45); registry default is Firebase (membloc-app/lib/core/repositories/membloc_repositories.dart:61-80, 374-379). | P1 | Decide launch mode: either flip default to engineFullBridge for target environments or keep a clearly named legacy/Firebase lane. | App boot smoke test for both default and MEMBLOC_BACKEND_MODE=engine; assert repository classes selected. |
| Auth routing | Engine adapter should remove product dependency on Firebase where possible. | Engine API still depends on Firebase ID token for /api/*; app top-level auth is Firebase. This may be intentional for auth provider, but not full Firebase removal. | App boot initializes Firebase (membloc-app/lib/main.dart:30) and routes via FirebaseAuth.instance.authStateChanges() (membloc-app/lib/main.dart:76-78); EngineAuthRepository uses Firebase ID tokens for /api/* calls (membloc-app/lib/core/repositories/engine_auth_repository.dart:15-22, 159-166). | P2 | Clarify whether Firebase Auth remains the identity provider. If yes, document as intentional; if no, define engine session/auth replacement. | Auth contract test: sign-in, call /api/auth/google, then authenticated engine domain calls. |
| Notification repository bridge | Engine domain bridge should cover notification token registration when app is in engine mode. | engineDomainBridge leaves notification Firebase-backed; only engineFullBridge uses EngineNotificationRepository. | engineDomainBridge passes notification through and comments “Firebase until Stage 14I” (membloc-app/lib/core/repositories/membloc_repositories.dart:315-334); engineFullBridge swaps notification (351-370). | P1 | Use engineFullBridge in all engine QA/product paths; retire partial bridge names or document them as legacy migration helpers. | Repository-selection unit test for engineDomainBridge vs engineFullBridge. |
| FCM token unregister | App expects token lifecycle to be robust across cold starts. | app-engine supports revoke by token ID only; app skips unregister if it only has raw token. | Engine routes: POST and DELETE by tokenId (membloc-app-engine/cmd/server/main.go:337-338); app repository calls DELETE /api/me/fcm-tokens/$id (membloc-app/lib/core/repositories/engine_notification_repository.dart:109) and registers with POST (:127); cold-start raw-token skip noted in repository implementation (worker-1/local audit). | P2 | Add revoke-by-token or list-current-token endpoint, or persist token ID durably before any unregister attempt. | Engine integration test for register + revoke by id and/or revoke by raw token. |
| Marketplace install/uninstall from app | App marketplace install/uninstall should call engine module installation APIs. | Engine endpoints exist; app methods are TODO no-ops after auth token check. | App installModule and uninstallModule TODOs (membloc-app/lib/core/services/marketplace_api.dart:92-110); engine install/uninstall/list routes exist (membloc-app-engine/cmd/server/main.go:364-369). | P0 | Wire app MarketplaceApi to POST /api/families/:familyId/modules/:key/install and /uninstall, then refresh installed modules. | Flutter API-client test with fake engine client; engine route tests for install/uninstall/list installed. |
| Module install source of truth | Installed module state should come from app-engine. | Engine has module_installations; app module services still read/write Firebase module instances and preferences. | Engine module install routes (membloc-app-engine/cmd/server/main.go:364-369) and migrations include module installation tables (membloc-app-engine/migrations/002_marketplace.up.sql, local audit); app module runtime services use Firestore/Functions (membloc-app/lib/core/services/module_service.dart, module_instance_service.dart; local audit). | P1 | Introduce engine-backed module installation repository/service in Flutter; migrate native module launchers to it. | Contract test: install module via engine, app launcher sees installed module without Firestore. |
| WebView module token | SDK auth.getAccessToken should provide a token accepted by runtime routes. | Engine exposes /api/auth/module-token and runtime middleware requires module-scoped token; app returns Firebase ID token. | App getModuleToken returns user.getIdToken() (membloc-app/lib/core/services/module_instance_service.dart:116-130); engine issues scoped module token (membloc-app-engine/internal/handler/auth.go:37-70); runtime middleware validates module token and path match (membloc-app-engine/internal/auth/runtime_middleware.go:11-39). | P0 | Implement app getModuleToken by POSTing /api/auth/module-token and returning the response token. | End-to-end WebView runtime test: SDK obtains token and calls /api/runtime/.../data. |
| SDK data API bridge | SDK data.get/set/delete/list should persist in engine module_data. | Engine runtime data CRUD exists; app bridge handlers return placeholder results and never call runtime. | Runtime data routes (membloc-app-engine/cmd/server/main.go:387-394); module_data table (membloc-app-engine/migrations/005_module_data.up.sql:4-18); app bridge routes data methods (membloc-app/lib/core/modules/js_bridge_controller.dart:137-146) but has TODO placeholders (:209-257). | P0 | Add an app runtime API client used by JsBridgeController for data CRUD. | SDK bridge integration test: set/list/get/delete persists to module_data. |
| SDK storage API | SDK storage upload/getUrl/list/delete should work or be explicitly unsupported. | SDK exposes storage; bridge maps only upload/delete permissions and routes none; engine runtime route group has no storage endpoints. | SDK storage methods (membloc-sdk/membloc-sdk.js:140-180; membloc-sdk/membloc-sdk.d.ts:104-109); bridge permission map has storage upload/delete (membloc-app/lib/core/modules/js_bridge_controller.dart:94-97) but switch omits storage (:137-157); runtime routes include data/activity/notifications only (membloc-app-engine/cmd/server/main.go:387-396). | P0 | Either implement storage bridge backed by engine files APIs or remove/deprecate storage methods from SDK/docs for MVP. | SDK contract tests for each storage method; engine tests if runtime storage endpoints are added. |
| SDK activity API | SDK activity.post should produce durable activity events. | Bridge does not route it; engine runtime service is a no-op stub even though route exists. | SDK method (membloc-sdk/membloc-sdk.js:194-202; types membloc-sdk/membloc-sdk.d.ts:115-117); bridge permission only (membloc-app/lib/core/modules/js_bridge_controller.dart:98-101) but no switch case (:137-157); engine route exists (membloc-app-engine/cmd/server/main.go:395) and service stub returns nil (membloc-app-engine/internal/service/module_runtime.go:57-67). | P0/P2 | Add bridge route and implement engine activity persistence/dispatch. | Runtime API test asserts created activity record or expected downstream effect. |
| SDK notifications API | SDK notifications.send should send or enqueue FCM notifications. | Bridge does not route it; engine runtime service is a no-op stub. | SDK method (membloc-sdk/membloc-sdk.js:182-192; types membloc-sdk/membloc-sdk.d.ts:111-113); bridge permission only (membloc-app/lib/core/modules/js_bridge_controller.dart:98-100), no switch route (:137-157); engine route exists (membloc-app-engine/cmd/server/main.go:396) but service stub returns nil (membloc-app-engine/internal/service/module_runtime.go:69-79). | P0/P2 | Add bridge route and implement FCM dispatch through engine notification service. | Integration test with FCM mock/push-dispatch spy. |
| SDK UI confirm/share | SDK ui.showConfirm and ui.shareToChannel should be callable. | SDK exposes both; bridge does not implement either. | SDK methods (membloc-sdk/membloc-sdk.js:226-236; types membloc-sdk/membloc-sdk.d.ts:119-124); bridge supports close/title/toast only (membloc-app/lib/core/modules/js_bridge_controller.dart:147-150) and returns UNKNOWN_METHOD otherwise (:152-157). | P2 | Implement bridge handlers or remove methods from public SDK until supported. | Bridge unit tests for supported/unsupported UI methods. |
| SDK settings API | SDK settings get/update should persist module settings. | Bridge returns TODO/stub values; engine has no runtime settings route/table. | SDK settings methods (membloc-sdk/membloc-sdk.js:239-252; membloc-sdk/membloc-sdk.d.ts:127-130); bridge routes settings (membloc-app/lib/core/modules/js_bridge_controller.dart:150-151) to TODO handlers (worker-3 audit); runtime routes lack settings (membloc-app-engine/cmd/server/main.go:387-396). | P2 | Add module settings persistence or mark settings as future API. | Settings set/get contract test across SDK → app bridge → engine. |
| WebView auth/family data | SDK auth/family calls should return real user/family/member data. | App bridge currently returns hard-coded or empty values. | getUserInfo returns user123/User Name (membloc-app/lib/core/modules/js_bridge_controller.dart:172-178); family and members handlers are TODO stubs (:193-205). | P0/P2 | Wire bridge to engine auth/family repositories or pass current app session data into bridge. | Bridge unit tests with fake family/member repository. |
| Family pending join flow | App onboarding can represent pending household requests and approval states. | Engine family join is synchronous; app engine repo emits no pending request and returns synthetic active request. | pendingHouseholdRequestStream emits null because engine does not model pending requests (membloc-app/lib/core/repositories/engine_family_repository.dart:152-157); join returns status active after POST /api/families/join (:203-225). | P2 | Decide product semantics. If approval remains required, add engine pending invite/request APIs and states. If not, update UI copy/tests to synchronous join. | Onboarding flow tests for request, cancel, approve/reject or synchronous join. |
| Family shape hints | App sends shape hints when creating a family. | Engine create handler accepts only name; hints are ignored. | App sends familyShapeHints (membloc-app/lib/core/repositories/engine_family_repository.dart:180-188); engine request struct has only Name (membloc-app-engine/internal/handler/family.go:28-30). | P2 | Persist shape hints or remove app request field and UI dependence. | Create-family contract test asserting shape hints stored/returned if supported. |
| Represented person related users | App can send relatedUserIds when adding represented persons. | Engine request binds relatedUserIds but does not pass them into service. | App body includes relatedUserIds (membloc-app/lib/core/repositories/engine_family_repository.dart:300-315); engine binds field (membloc-app-engine/internal/handler/family.go:130-134) but calls AddRepresentedPerson without related IDs (:149). | P2 | Add relation table/service handling or remove field from app until supported. | Add represented-person test with related users and verify readback. |
| Trip feature repository | Trip screens should use repository seam with engine-backed implementation. | Only Firebase trip repository is present/used; trip is also absent from the central MemblocRepositories seam. | FirebaseTripRepository uses Cloud Functions/Firestore/Storage (membloc-app/lib/core/repositories/firebase_trip_repository.dart:15-19); trip detail screen and widgets default to Firebase (membloc-app/lib/features/trip/membloc_trip_detail_screen.dart:63-64, membloc-app/lib/features/trip/widgets/membloc_trip_create_modal.dart:305-306, membloc-app/lib/features/trip/widgets/membloc_trip_candidate_create_modal.dart:274-275, membloc-app/lib/features/trip/widgets/membloc_trip_day_plans_section.dart:525-526, membloc-app/lib/features/trip/widgets/membloc_trip_bookings_section.dart:575-576); repository registry has no trip field/arg (membloc-app/lib/core/repositories/membloc_repositories.dart:38-45, 61-80). | P1 | Design app-engine trip APIs/migrations or move trip under generic module runtime deliberately; add EngineTripRepository and central trip seam. | Trip flow contract tests for create/candidates/bookings/day plans/end/archive. |
| Chat vote/proposal lifecycle | Chat UI vote/proposal actions should work in engine mode through ChannelRepository. | Engine channel repository methods exist but throw UnimplementedError; app-engine route surface lacks dedicated vote/proposal lifecycle endpoints. | Interface requires vote/proposal methods (membloc-app/lib/core/repositories/channel_repository.dart:192-292); engine implementation throws for those methods (membloc-app/lib/core/repositories/engine_channel_repository.dart:838-950); UI calls them in chat sheets/screen (membloc-app/lib/features/channels/widgets/membloc_quick_save_sheets.dart:1590, :1822; membloc-app/lib/features/channels/membloc_chat_room_screen.dart:676, 749, 794, 818, 851, 886, 910, 934); engine chat routes omit vote/proposal actions (membloc-app-engine/cmd/server/main.go:283-308; membloc-app-engine/internal/handler/channel.go:17-44). | P0 | Add app-engine vote/proposal action endpoints or implement the methods using an explicitly supported typed-message contract; wire service persistence and promote/retry semantics. | Engine repository unit tests plus API/e2e tests for send/submit/close/promote/retry vote and proposal flows. |
| Native modules: shopping/budget/projects/health/travel/chores/etc. | Native module screens should be backed by engine or a deliberate runtime data abstraction. | Services still use Firebase/Firestore/Functions/Storage directly; no dedicated engine tables/APIs found. | Examples: shared budget Firestore/Auth and moduleInstances paths (membloc-app/lib/modules/shared_budget/services/shared_budget_service.dart:24-46); travel uses Functions (membloc-app/lib/modules/travel/services/travel_service.dart:18-62); chores uses FirebaseAuth/Storage (local audit); engine migrations contain generic module_data but no dedicated native-module tables (membloc-app-engine/migrations/005_module_data.up.sql:4-18). | P1 | Choose migration strategy: generic module_data adapter for native modules or domain-specific engine APIs/tables for each native module. | One module pilot test (e.g. shopping) proving no Firestore access in engine mode. |
| Legacy core services | Screens/services may bypass repository seam and call Firebase directly. | Multiple core services remain Firebase/Functions-backed. | Local audit found direct Firebase in memory_service.dart, family_service.dart, module_service.dart, module_instance_service.dart, activity_service.dart, context_api_service.dart, family_context_item_service.dart, user_preferences_service.dart. | P1 | Inventory call sites and either replace with repositories or mark as legacy-only paths disabled in engine mode. | Static test/CI grep preventing Firebase imports in engine-mode app layers except auth/provider allowlist. |
| Calendar update/delete consumption | App screens may eventually need event edit/delete. | Engine exposes update/delete routes; current app repository interface only uses create/from-chat/get/list/overview/completion. | Engine route group includes calendar routes in server (local audit); app EngineCalendarRepository calls overview/events/from-chat/completion (membloc-app/lib/core/repositories/engine_calendar_repository.dart:72-246) but no update/delete method exists in repository interface (local audit). | P3 | Add app interface methods when UI supports edit/delete; otherwise document unconsumed engine endpoints. | Contract tests when edit/delete UI is introduced. |
| Memory list/search consumption | Engine has more memory endpoints than app consumes. | App engine repo uses overview/get/create/from-chat/delete, not list/search. | Engine memory handlers expose list/search/overview (local audit); app calls overview/get/from-chat/create/delete (membloc-app/lib/core/repositories/engine_memory_repository.dart:76-219). | P3 | Decide if app memory browsing/search should use engine list/search; otherwise keep endpoints for future/admin. | Memory browsing/search UI integration tests. |
| Family invites endpoints | Engine has invite endpoints not consumed by app engine family repo. | app repo uses join/list/members/represented persons; does not call create/list invites. | Engine family handler has create/list invites (local audit); app family repo routes listed at membloc-app/lib/core/repositories/engine_family_repository.dart:162-313. | P3 | Wire invite management UI to engine invite endpoints if product needs it. | Invite create/list/consume integration test. |
| Publisher/admin current portal flows | Publisher/admin portal current API client calls should be backed. | No gap found for current routes in portal audit. | Portal calls publisher/admin endpoints (membloc-developer-portal/src/lib/portal-api.ts:79-307); engine routes match publisher/admin/current flows (membloc-app-engine/cmd/server/main.go:344-385); worker-4 confirmed wrappers for modules/analytics/api-keys/webhooks/admin queues. | No gap | Keep contract tests for response wrappers and role gates. | Portal API client tests + engine integration tests for publisher/admin happy paths. |
| Publisher planned member/version/delete APIs | Docs describe publisher team management, module delete, module version APIs, and admin unsuspend. | Engine routes do not include publisher members, module delete/version routes, or admin unsuspend. Current portal also does not appear to consume these yet. | Docs planned endpoints (docs/phase3-publisher-portal.md:295-310, 338-339); engine current routes stop at profile/modules/submit/analytics/api-keys/webhooks and admin suspend (membloc-app-engine/cmd/server/main.go:344-385). | P3 | Either implement planned endpoints or update docs to mark future-phase. | API route tests once implemented; docs sync check if deferred. |
| Publisher asset upload | Portal module icon/screenshot upload should be app-engine-backed if engine is source of truth. | Portal uploads assets to Firebase Storage and sends URLs to engine. | Storage upload helper imports Firebase Storage (membloc-developer-portal/src/lib/storage-upload.ts:3-4) and writes publisher-assets/... (:36-47); publisher portal migration has screenshot metadata table (membloc-app-engine/migrations/006_publisher_portal.up.sql:45-53) but no engine asset upload route in current server routes (membloc-app-engine/cmd/server/main.go:344-385). | P2 | Add publisher asset upload-intent/finalize endpoints using engine file/storage service, or document Firebase Storage as intentional external asset store. | Portal upload integration test with engine-backed asset URL persistence. |
| Publisher portal platform bring-up | Phase 3 register→approve→submit→admin approve loop should be runnable. | Docs identify migration/config/E2E loop as next priority; current API routes are present, but operational readiness remains documented incomplete. | Worker-5 docs synthesis: docs/phase3-execution-plan.md:15-35, 51-63, 319-334, 343-370; QA runbook has missing automation (membloc-docs/content/operations/phase3-qa-runbook.md:253-265). | P1 | Apply migration/config checklist and run E2E loop before product use. | Manual QA runbook now; add automated smoke once tokens/webhook mock exist. |
| Runtime/docs completion criteria | Runtime docs say JS bridge, module data, permissions, sample budget notification flow must work. | Code only partially satisfies criteria. | Runtime docs tasks and completion criteria (docs/phase2-webview-runtime.md:585-651); gaps above show bridge/runtime stubs and unimplemented storage/activity/notification flows. | P0/P1 | Treat docs completion checklist as acceptance criteria for next execution sprint. | End-to-end sample module test: data write/read, notification, permission denial, rate limit. |
Product blockers
- WebView module MVP blocker (P0): SDK calls cannot reliably persist or reach app-engine through the Flutter bridge. Token shape is wrong, data handlers are stubs, storage/activity/notifications/settings/share/confirm are missing or no-op.
- Chat vote/proposal blocker (P0): engine-mode chat vote/proposal methods throw
UnimplementedErrorwhile UI calls them, and app-engine lacks matching lifecycle routes. - Marketplace install/uninstall blocker (P0/P1): app-engine install routes exist but the app does not call them, so remote module acquisition cannot be engine-source-of-truth from the Flutter client.
- Engine-mode app blocker (P1): default product boot is Firebase-backed. Without an explicit engine flag, repository migration coverage is not exercised.
- Native module blocker (P1): native module features and trip flows remain Firebase/Cloud Functions backed. They cannot be claimed as fully engine-backed until adapters/data models are chosen and implemented.
- Publisher portal operational blocker (P1): current API coverage is mostly present, but docs still require migration/config/E2E bring-up before launch.
Backend implementation backlog
- Add chat vote/proposal lifecycle endpoints/services, or formalize a typed-message contract that covers send/submit/close/promote/retry.
- Implement or explicitly deprecate runtime storage endpoints for SDK storage methods.
- Implement
ModuleRuntimeService.PostActivityandSendNotificationside effects instead of no-op stubs. - Add module settings persistence if SDK settings remains public.
- Add revoke-by-raw-FCM-token or current-token lookup endpoint.
- Decide and implement family pending request semantics if approval flow remains part of product.
- Persist family shape hints and represented-person related user IDs, or remove those fields from app contract.
- Add publisher asset upload endpoints if Firebase Storage is not intended for portal assets.
- Decide planned Phase 3 publisher endpoints: members, module delete, module versions, admin unsuspend.
- Define trip/native module engine APIs or generic
module_dataaccess policies.
App integration backlog
- Flip or explicitly configure
MEMBLOC_BACKEND_MODE=enginein engine QA/product builds. - Wire
MarketplaceApi.installModuleanduninstallModuleto app-engine routes and installed-module refresh. - Replace
ModuleInstanceService.getModuleTokenwith/api/auth/module-tokencall. - Implement an app runtime API client and wire
JsBridgeControllerdata/storage/activity/notifications/settings/share/confirm handlers. - Replace hard-coded bridge user/family/member responses with real repositories/session data.
- Implement engine-mode chat vote/proposal repository methods and remove
UnimplementedErrorcrash paths. - Add
EngineTripRepositoryor move trip feature onto a documented module-runtime path. - Inventory direct Firebase service call sites and either add engine repositories or block them in engine mode.
- Decide whether app UI needs engine calendar edit/delete, memory list/search, and family invite endpoints.
Migration/data model backlog
- Existing engine coverage:
module_data(membloc-app-engine/migrations/005_module_data.up.sql:4-18), publisher portal metadata/webhooks/stats (membloc-app-engine/migrations/006_publisher_portal.up.sql:30-103), files, chat, calendar, memories, archives, FCM tokens, household/lineage tables (local audit). - Missing or unresolved for app expectations:
- Native module domain data: shopping lists/items, shared budget entries, project tasks, health/medication logs, chores/media, travel trips/bookings/day plans, meal/school/bills/family-story/growth-journal data if they remain native features.
- Module settings if SDK settings remains supported.
- Runtime storage namespace if it should be distinct from app family files.
- Activity/event persistence for module
activity.post. - Notification dispatch/audit rows for module
notifications.send. - Family shape hints and represented-person related-user linkage.
- Publisher asset binary/object metadata if moving portal assets from Firebase Storage.
Verification plan by repo
-
membloc-app
- Add repository-selection tests for Firebase default vs engine full bridge.
- Add API client unit tests for marketplace install/uninstall.
- Add WebView bridge tests for every SDK method: success, permission denied, unsupported, malformed params.
- Add static guard for Firebase imports in engine-mode app layers, with allowlist for Firebase Auth if intentionally retained.
- Run Flutter tests/web build for changed surfaces in implementation phase.
-
membloc-app-engine
- Run
go test ./...,go vet ./..., andgo build ./cmd/serverafter implementation changes. - Add route contract tests for
/api/auth/module-tokenand/api/runtime/:moduleKey/families/:familyId/*. - Add integration tests for module install/uninstall/list installed and FCM token lifecycle.
- Add publisher/admin response-shape tests for wrappers consumed by portal.
- Run
-
membloc-sdk
- Add a contract matrix test that each typed method maps to a bridge method and receives documented response/error shapes.
- If methods are deferred, update
.d.ts, JS implementation, README/docs together.
-
membloc-developer-portal
- Keep
npm run lintandnpm run buildin implementation verification. - Add API-client tests for publisher/admin wrappers.
- Add upload tests once asset storage source of truth is decided.
- Keep
-
docs / membloc-docs/content
- No membloc-docs build was required for this audit because only the root audit report was created.
- If runtime or portal docs are changed later, run docs mirror/diff checks and the docs build per repo guidance.
Suggested next omx team execution prompt
omx team 5:executor "
Membloc app-engine API sync implementation sprint.
Use docs/app-engine-api-sync-gap-audit.md as source of truth.
Constraints: do not touch deploy/tags/secrets/Firebase config/OCI config/branch protection. Keep diffs small and add tests.
Lanes:
1. membloc-app WebView runtime token + data bridge: implement /api/auth/module-token and runtime data CRUD client, with bridge tests.
2. membloc-app marketplace install/uninstall/list integration: wire engine routes and add API-client tests.
3. membloc-app-engine runtime activity/notifications/settings/storage decision: implement MVP side effects or remove/deprecate SDK surfaces with docs/tests.
4. native module/trip migration plan: pick one pilot feature and define adapter/data model without changing production data.
5. publisher portal asset/planned endpoint cleanup: decide Firebase Storage vs engine asset upload and mark docs/API gaps.
Verification: run targeted tests per repo, then summarize changed files, test evidence, and remaining risks.
"
Audit verification
- No source-code files were edited for this audit.
- Report artifact path:
docs/app-engine-api-sync-gap-audit.md. membloc-docsbuild not run and not required because docs content was not synced/edited in this audit.
SDK assets