Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ Always run lint locally before pushing. Protected branches require PR workflow

### Modular Infrastructure (`modules/`)

Foundation layer for modular decomposition (issue #489). Phases 0–4.7a complete: all 28 routers migrated (Phase 3), all inline endpoints extracted from `orchestrator.py` (Phase 4.1–4.5), all background tasks migrated to `TaskRegistry` (Phase 4.6), 8 startup helpers extracted to domain `startup.py` modules + graceful shutdown (Phase 4.7a). Phase 4.7b (service init + globals removal), Phase 5 (EventBus events) and Phase 6 (protocol interfaces) pending.
Foundation layer for modular decomposition (issue #489). Phase 4 complete: all 28 routers migrated (Phase 3), all inline endpoints extracted (Phase 4.1–4.5), all background tasks via `TaskRegistry` (Phase 4.6), all startup helpers + service init extracted to domain `startup.py` modules, global service variables removed (Phase 4.7a/b). Phase 5 (EventBus events) and Phase 6 (protocol interfaces) pending.

- **`EventBus`** (`modules/core/events.py`): In-process async pub/sub. Handlers run concurrently via `asyncio.gather`; exceptions are logged, never propagated to publisher. `BaseEvent` dataclass with auto-timestamp.
- **`TaskRegistry`** (`modules/core/tasks.py`): Named background tasks β€” periodic (interval-based) or one-shot. `start_all()` / `cancel_all(timeout)` lifecycle. `TaskInfo` dataclass tracks status, run count, last error. 6 tasks registered in `startup_event()`: `session-cleanup` (1h), `periodic-vacuum` (7d), `kanban-sync` (15min), `woocommerce-sync` (daily 23:00 UTC), `wiki-embeddings` (one-shot), `wiki-collection-indexes` (one-shot). Task functions in `modules/core/maintenance.py`, `modules/knowledge/tasks.py`, `modules/kanban/tasks.py`, `modules/ecommerce/tasks.py`.
Expand Down Expand Up @@ -210,9 +210,9 @@ New routers import domain services directly (`from modules.monitoring.service im

### Key Components

**`orchestrator.py`** (~805 lines): FastAPI entry point. **Zero inline endpoints** β€” all business logic extracted to `modules/*/router*.py` (Phase 4.1–4.5). **Zero raw `asyncio.create_task()`** β€” all background tasks via `TaskRegistry` (Phase 4.6). **Zero helper functions** β€” startup helpers (seeding, auto-start, reload) extracted to `modules/*/startup.py` (Phase 4.7a). Contains only: imports, CORS/middleware, router registration (~28 `include_router` calls), global service variables, `startup_event()` (service init + task registration), `shutdown_event()` (cancel tasks + stop bots/bridge + close DB), static file serving, Vite dev proxy. Startup helpers in `modules/core/startup.py`, `modules/llm/startup.py`, `modules/channels/{telegram,whatsapp}/startup.py`, `modules/knowledge/startup.py`, `modules/speech/startup.py`.
**`orchestrator.py`** (~320 lines): FastAPI entry point β€” **pure wiring**, zero domain logic. No inline endpoints (Phase 4.1–4.5), no raw `asyncio.create_task()` (Phase 4.6), no helper functions (Phase 4.7a), no global service variables (Phase 4.7b). Contains only: imports, CORS/middleware, declarative router registration (~28 routers), `startup_event()` (calls domain init functions + registers tasks), `shutdown_event()` (delegates to `graceful_shutdown()`), static file serving, Vite dev proxy. All service initialization in domain `startup.py` modules: `modules/speech/startup.py` (TTS/STT), `modules/llm/startup.py` (LLM + fallback chain + InternetMonitor callback), `modules/knowledge/startup.py` (Wiki RAG + embeddings), `modules/core/startup.py` (seed, monitor, shutdown), `modules/telephony/startup.py` (GSM), `modules/channels/{telegram,whatsapp}/startup.py` (bot auto-start).

**`ServiceContainer` (`app/dependencies.py`)**: Singleton holding references to all initialized services. Routers get services via FastAPI `Depends`. Populated during app startup.
**`ServiceContainer` (`app/dependencies.py`)**: Singleton holding references to all initialized services β€” the **single source of truth** for service state (no global variables). Routers get services via FastAPI `Depends`. Populated during app startup by domain `init_*()` functions. Runtime mutations (LLM backend switch) write directly to container.

**Two service layers**: Core AI services at project root (`cloud_llm_service.py`, `vllm_llm_service.py`, `voice_clone_service.py`, `stt_service.py`, etc.). Domain services in `app/services/` (`amocrm_service.py`, `wiki_rag_service.py`, `backup_service.py`, `sales_funnel.py`, etc.).

Expand Down
Loading