Object-Service Design Overview¶
High-level overview of TNH Scholar's layered architecture for complex objects and API-backed services.
Purpose¶
This document provides a high-level introduction to the Object-Service design pattern used throughout TNH Scholar. For complete architectural details, see ADR-OS01: Object-Service Design Architecture V3.
Core Principle¶
Goal: Ship reliable, composable features fast by separating concerns and keeping boundaries explicit.
Architectural Layers¶
Application Layer (CLI, notebooks, web, Streamlit)
└─ Orchestrators (thin): <Feature>Processor, ResultWriter
â–²
│ domain objects / protocols
│
Domain Service Layer
└─ <Feature>Service (Protocol-based orchestrator)
└─ ProviderClient (impl: OpenAIClient, PyannoteClient, etc.)
└─ RequestMapper (bi-directional: domain ↔ transport)
└─ TransportClient (HTTP, polling, streaming)
â–²
│ transport models (anti-corruption boundary)
│
Transport Layer
└─ VendorClient (upload/start/status/poll, retries, rate-limit)
JobPoller (backoff, jitter, deadline)
Key Design Contracts¶
- Config at init, Params per call, Response envelope always
- Service protocol is minimal:
start(),get_response(),generate()for async jobs;generate()orrun()for sync - Adapter maps API shapes → canonical domain shapes (bi-directional)
- All payloads use strong typing (Pydantic or dataclass models)
- No literals or untyped dicts in application logic
Primary Benefits¶
- Separation of Concerns: Domain logic isolated from API transport details
- Testability: Each layer can be tested independently with clear interfaces
- Flexibility: Swap providers without changing application code
- Type Safety: Strong typing throughout prevents runtime errors
- Maintainability: Clear boundaries make refactoring safer
Core Services¶
Current TNH Scholar services following this architecture:
- GenAIService: AI text processing with OpenAI/Anthropic providers
- TranscriptionService: Audio transcription with Whisper/AssemblyAI providers
- DiarizationService: Speaker diarization with Pyannote provider
Future services planned:
- PromptCatalogService: Enhanced prompt management
- EmbeddingService: Text embeddings for semantic search
- VectorStoreService: Vector database integration
Implementation Status¶
See object-service-implementation-status.md for current gaps, resolved items, and planned work.
Related Documentation¶
- ADR-OS01: Object-Service Design Architecture V3 - Complete architectural specification
- Implementation Status - Gaps analysis and progress
- Design Principles - General design philosophy
- Conceptual Architecture - High-level system model
Quick Reference¶
Service Protocol Example¶
from typing import Protocol
class TextProcessingService(Protocol):
"""Protocol for text processing services."""
def generate(
self,
request: ProcessingRequest
) -> ProcessingResponse:
"""Process text and return result."""
...
Adapter Pattern Example¶
class OpenAIAdapter:
"""Maps domain models to/from OpenAI API."""
def to_api_request(
self,
domain_request: ProcessingRequest
) -> OpenAICompletionRequest:
"""Map domain request to OpenAI format."""
...
def from_api_response(
self,
api_response: OpenAICompletion
) -> ProcessingResponse:
"""Map OpenAI response to domain format."""
...
For complete examples, templates, and detailed patterns, see ADR-OS01.