Skip to content

Services Documentation

This document provides comprehensive documentation for all services in the Yappa Knowledge Hub backend.

Overview

Services contain the core business logic and external API integrations. The backend has two main service categories:

  1. Notion Services - Integration with Notion API
  2. Application Services - Core business logic

Detailed Service Guides

For in-depth technical specifications, method lists, and integration patterns, refer to the following guides:

🔄 Notion Services

Detailed documentation on the NotionClient, NotionSyncService, and property mapping logic.

👔 Category Services

Understanding the business logic behind thematic lists, activation, and sort management.

📝 Digest Services

Documentation on role-specific knowledge aggregation and report generation logic.

🤖 AI Summary Services

Detailed guide on the AI orchestration layer, prompt templates, and summary versioning.


Service Layer Architecture

Last Updated: 2026-03-09 Version: 2.0 (Consolidated)

The Service Layer in Yappa Knowledge Hub acts as the "braid" that connects external integrations (Notion, Slack), AI processing (OpenAI), and persistent storage (Doctrine).

Service Overview

ComponentResponsibilityKey Interactions
Notion IntegrationBidirectional sync with Notion databases.Notion API, Doctrine, Mapping Services
AI OrchestrationSummary generation, template resolution.OpenAI API, PromptBuilder, AiSummary Entity
Knowledge ManagementCRUD operations, validation, and status transitions.Knowledge Entity, Category Entity
Digest & ReportingPeriodic aggregation of knowledge for target groups.Summary Service, Scheduled Tasks

🏛️ Domain Services

📘 Notion Services

Handles the heavy lifting of communicating with Notion. It includes:

  • NotionClient: Low-level Guzzle-based client for Notion API.
  • NotionSyncService: Orchestrates the sync lifecycle (Fetch → Map → Persist).

🤖 AI Summary Services

Orchestrates the creation of context-aware summaries.

  • AiSummaryService: Handles requests for new summaries.
  • PromptBuilder: Logic for template inheritance (Global vs. Category-specific).

🏮 Knowledge Service

Business logic for knowledge items that isn't purely persistence-related, such as:

  • Content sanitization.
  • Metadata extraction from URLs.
  • Status workflow management.

🏗️ Architectural Patterns

1. Data Mapping

We use specialized Mappers to convert Notion's complex JSON properties into clean PHP entities. This keeps the Domain model decoupled from external API changes.

2. Error Handling & Logging

Services follow a "Graceful Degradation" policy:

  • If Notion is down, the local SQLite database remains the source of truth for the Slack Bot.
  • Failed AI generations are logged with detailed metadata for later debugging without crashing the request.

3. Dependency Injection

All services are autowired following Symfony best practices. Cross-service communication is strictly via dependency injection into constructors.


Technical Context

For more details on specific implementations, see the files in src/Service/.

Environment Variables

Required environment variables for services:

bash
# Notion API
NOTION_API_KEY=secret_xxx
NOTION_KNOWLEDGE_DATABASE_ID=xxx
NOTION_CATEGORIES_DATABASE_ID=xxx

# OpenAI API
OPENAI_API_KEY=sk-xxx
OPENAI_MODEL=gpt-4
OPENAI_MOCK_MODE=false

Error Handling

All services implement proper error handling:

  1. Logging: Errors are logged with context
  2. Exceptions: Throw meaningful exceptions
  3. Retries: Automatic retries for transient failures (OpenAI)
  4. Fallbacks: Graceful degradation (sync service)

Testing Services

Services can be tested using PHPUnit:

php
use App\Service\OpenAiService;
use PHPUnit\Framework\TestCase;

class OpenAiServiceTest extends TestCase
{
    public function testMockMode(): void
    {
        $service = new OpenAiService(
            $this->createMock(HttpClientInterface::class),
            $this->createMock(LoggerInterface::class),
            '',
            'gpt-4',
            true // mock mode
        );

        $result = $service->generateCompletion('Test prompt');
        $this->assertNotEmpty($result);
    }
}