Services Documentation
Last Updated: 2026-05-08
The backend contains 38 service files across 12 directories, organized by domain following a clean layered architecture.
Service Architecture
Controller → Orchestrator → Domain Services → Persistence → Repository
↕
AI Provider
↕
Notion Sync ServiceService Overview
| Domain | Files | Key Services |
|---|---|---|
| Orchestrator | 2 | DigestOrchestrator, KnowledgeOrchestrator |
| Digest | 10 | Generation, formatting, creation, distribution, scheduling, delivery tracking |
| Knowledge | 3 | Creation, persistence, query |
| Subscription | 3 | Facade + query/persistence CQRS split |
| Notion | 11 | Sync, 4 repositories, page builder, property extractor, markdown content |
| AI | 2 | Provider interface + OpenAI/OpenRouter implementation |
| Content | 2 | Content extraction + HTML parser |
| Slack | 1 | Slack DM delivery |
| Transport | 2 | Message transport interface + Slack implementation |
| Root | 2 | CategoryService + EmojiConverter |
Orchestrator Layer
Thin coordination layer that orchestrates multi-step workflows without containing business logic.
DigestOrchestrator
Coordinates the 7-step digest generation pipeline:
- Resolve category → 2. Parse date range → 3. Query knowledge → 4. Generate AI highlights → 5. Format Markdown → 6. Create entity → 7. Persist & sync to Notion
Also handles distribution if distributeNow is set.
KnowledgeOrchestrator
Coordinates knowledge creation: resolve category, create entity, persist, sync to Notion.
Digest Services (10 files)
| Service | Responsibility |
|---|---|
DateRangeParser | Parses date range strings ("7 days", "last week", "2026-01-01 to 2026-01-07") into DateRangeDto |
DigestContentFormatter | Formats knowledge highlights into Dutch Markdown with headers, summaries, tags, and read time |
DigestCreationService | Creates Digest entity with title, content, statistics, highlight snapshot, and knowledge links |
DigestPersistenceService | Persists digests to database and syncs to Notion |
DigestDistributionService | Resolves subscribers, sends via Slack DMs, logs per-user delivery |
DigestDeliveryLogService | Creates/updates DigestDelivery entities for delivery tracking |
DigestDeliveryPersistenceService | Low-level save/mark operations on DigestDelivery entities |
DigestDeliveryQueryService | Query deliveries by digest, user, status |
DigestQueryService | Find digest by ID or category |
DigestSchedulerService | Checks digest-enabled categories and triggers generation when due |
KnowledgeHighlightGenerator | Generates 2-3 sentence Dutch AI summaries per knowledge item |
AI Services (2 files)
AiProviderInterface
php
interface AiProviderInterface {
public function generateCompletion(string $prompt, AiOptionsDto $options): AiResponseDto;
}OpenAIService
Implements AiProviderInterface. Supports:
- OpenAI (default) via Symfony AI Platform
- OpenRouter (detected by API URL containing
openrouter.ai) - Configured via
OPENAI_MODEL,OPENAI_API_KEY,OPENAI_API_URL
Notion Services (11 files)
| Service | Responsibility |
|---|---|
NotionSyncService | Coordinates bidirectional sync for all entity types |
NotionRepositoryManager | Resolves correct repository by ID type (local int vs Notion UUID) |
NotionKnowledgeRepository | CRUD on Notion Knowledge database |
NotionCategoryRepository | CRUD on Notion Categories database |
NotionDigestRepository | CRUD on Notion Digests database |
NotionSubscriptionRepository | CRUD on Notion Subscriptions database |
NotionPageBuilder | Fluent builder for constructing Notion page properties |
NotionPropertyExtractor | Reads typed values from Notion page properties |
NotionMarkdownContentService | Embeds full Markdown content as Notion blocks |
NotionClientFactory | Static factory for Notion SDK client |
NotionPaginationTrait | Handles paginated Notion API queries |
Environment Variables
bash
# Notion API
NOTION_API_KEY=secret_xxx
NOTION_KNOWLEDGE_DATABASE_ID=xxx
NOTION_CATEGORIES_DATABASE_ID=xxx
NOTION_DIGESTS_DATABASE_ID=xxx
NOTION_SUBSCRIPTIONS_DATABASE_ID=xxx
# AI Provider
OPENAI_API_KEY=sk-xxx
OPENAI_MODEL=gpt-4
OPENAI_API_URL=https://api.openai.com/v1
# Slack Integration (for digest delivery)
SLACK_BOT_URL=http://localhost:4001
INTERNAL_API_SECRET=xxx