gateway/docs/SERVICE_CENTER_MIGRATION_PLAN.md
2026-03-06 14:03:18 +01:00

7.4 KiB
Raw Blame History

Service Center Migration Plan

Overview

This document describes a step-by-step plan to migrate from the old modules/services (Services hub) to the new modules/serviceCenter. The migration is incremental—one feature at a time—with UI-driven testing after each step.

Recommended first feature: Chatbot — it has a clear UI, limited service dependencies, and is already partially using the service center (AI, generation, billing).


Architecture Summary

Current State

Component Location Notes
Service Center modules/serviceCenter/ New: registry, resolver, context-based DI
Services Hub modules/services/ Legacy: getInterface()Services instance
Chatbot modules/features/chatbot/ Uses getServices().chat, .ai

Service Center vs Legacy Services

Aspect Service Center Legacy Services
Constructor (context: ServiceCenterContext, get_service) (services: Services) — receives hub
Context Minimal: user, mandate_id, feature_instance_id, workflow Full hub with all interfaces
Dependencies Injected via get_service("key") Via self.services.<attr>
RBAC Per-service objectKey in registry Shared via hub
Pre-warm preWarm() at app startup Loaded on first use

Services Already Using Service Center (in Services class)

The Services class in modules/services/__init__.py already uses getService() for:

  • messaging
  • ai
  • generation
  • billing

Services Still Using Legacy Direct Imports

  • chatTarget for Phase 1
  • sharepoint
  • ticket
  • utils
  • security
  • streaming
  • extraction
  • web

Phase 1: Migrate Chatbot to Use Service Center for Chat

Goal: Switch the Chatbot feature to get the Chat service from Service Center instead of the legacy hub. This validates the full flow with minimal risk.

Step 1.1: Switch Services Class to Use Service Center for Chat

File: modules/services/__init__.py

Change: Replace the direct ChatService import with getService("chat", ...).

# BEFORE (line ~126-127):
from .serviceChat.mainServiceChat import ChatService
self.chat = PublicService(ChatService(self))

# AFTER:
self.chat = PublicService(getService("chat", _ctx, legacy_hub=self))

The _ctx (ServiceCenterContext) is already created for messaging/ai/generation. Add workflow=self.workflow to the context if not already present (it should be—check the existing _ctx creation around line 109116).

Verification:

  1. Ensure ServiceCenterContext includes workflow when Services has one (chatbot often passes workflow=None initially).
  2. The service center ChatService gets interfaceDbComponent from getInterface(context.user, mandateId=context.mandate_id) — same as legacy. The chatbot calls getFileInfo(fileId) which only needs interfaceDbComponent, not workflow.

Step 1.2: Ensure Service Center Context Has Workflow

File: modules/services/__init__.py

Verify the existing context creation:

_ctx = ServiceCenterContext(
    user=self.user,
    mandate_id=self.mandateId,
    feature_instance_id=self.featureInstanceId,
    workflow=self.workflow,
)

If workflow is missing, add it. The ChatService uses _context.workflow for methods like getChatDocumentsFromDocumentList; for getFileInfo it is not needed.

Step 1.3: Run Unit Tests

cd c:\Users\IdaDittrich\Documents\01_Code\gateway
pytest tests/unit/serviceCenter/test_service_center_imports.py -v
python tests/scripts/smoke_test_service_center.py

Step 1.4: Manual UI Test — Chatbot with File Upload

  1. Start the gateway:

    cd c:\Users\IdaDittrich\Documents\01_Code\gateway
    uvicorn app:app --reload --host 0.0.0.0 --port 8000
    
  2. Start the frontend (if using frontend_nyla):

    cd c:\Users\IdaDittrich\Documents\01_Code\frontend_nyla
    npm run dev
    
  3. Log in as a user with access to the Chatbot feature.

  4. Open a Chatbot instance (navigate to the chatbot feature, select or create an instance).

  5. Create a new conversation — click "New conversation" or equivalent.

  6. Attach a file — upload a PDF or document before sending.

  7. Send a message — e.g. "Summarize this document."

  8. Verify:

    • No 500 errors in gateway logs
    • File is processed (chat services getFileInfo is used when creating ChatbotDocuments)
    • AI response streams back correctly (AI service already from service center)

Step 1.5: Rollback if Needed

If something breaks, revert the change in modules/services/__init__.py:

from .serviceChat.mainServiceChat import ChatService
self.chat = PublicService(ChatService(self))

Phase 2 (Future): Migrate Extraction for Chatbot

The chatbot may use extraction when processing documents. After Phase 1 is stable:

  1. Switch Services to use getService("extraction", _ctx, legacy_hub=self) instead of direct import.
  2. Ensure ExtractionService in service center has the same interface as the legacy one.
  3. Re-test chatbot with document-heavy prompts.

Phase 3 (Future): Migrate Remaining Services

Service Used By Priority
utils Chat, Extraction, AI, Web, Generation High (core)
security Sharepoint Medium
streaming Workflows, Chatbot SSE Medium
sharepoint Sharepoint workflows Medium
ticket Ticket system Low
web Web research workflows Medium

Service Center Bootstrap (Already Done)

The app already:

  • Calls preWarm() at startup (app.py lifespan)
  • Has registerServiceObjects() available for RBAC catalog (call from bootstrap if needed)

Optional: Register Service RBAC Objects

If you want service-level RBAC (e.g. can_access_service()), call during bootstrap:

# In app.py lifespan or interfaceBootstrap
from modules.serviceCenter import registerServiceObjects
from modules.security.rbacCatalog import getCatalogService
catalogService = getCatalogService()
registerServiceObjects(catalogService)

Testing Checklist (Chatbot Phase 1)

  • Unit tests pass: pytest tests/unit/serviceCenter/ -v
  • Smoke test passes: python tests/scripts/smoke_test_service_center.py
  • Gateway starts without import errors
  • Chatbot UI loads
  • New conversation creates successfully
  • Message without file sends and gets AI response
  • Message with file attachment sends and gets AI response
  • No errors in gateway logs during the above flows

File Summary for Phase 1

File Action
modules/services/__init__.py Replace ChatService import with getService("chat", _ctx, legacy_hub=self)
(No other changes) Service center ChatService and resolver already support legacy fallback

FAQ

Q: Why start with Chat instead of Utils?
A: Chat has a clear UI path (chatbot) and only a few call sites. Utils is used everywhere; migrating it later reduces risk.

Q: What if getService("chat", ctx) fails?
A: The resolver passes legacy_hub=self, so it falls back to the legacy Services.chat if the service center module fails to load. You get graceful degradation.

Q: Can I test without the frontend?
A: Yes. Use the API directly, e.g. POST /api/chatbot/{instanceId}/start/stream with a valid UserInputRequest (with listFileId for file upload).