Backend Overview
Technology Stack
The Yappa Knowledge Hub backend is built with modern PHP technologies:
- PHP: 8.2+
- Symfony: 7.2.* (latest stable)
- Doctrine ORM: 3.6+ with Doctrine Migrations 3.7+
- API Platform: 4.1+ for REST API capabilities
- Database: SQLite (local storage) + Notion API (cloud sync)
- HTTP Client: Symfony HTTP Client + Guzzle
- Testing: PHPUnit 11.5+
Architecture Overview
The backend follows a dual-storage architecture that combines:
- SQLite Database: Local persistent storage for fast queries and offline capability
- Notion API: Cloud-based knowledge management with rich UI and collaboration features
This hybrid approach provides:
- Fast local queries from SQLite
- Rich collaborative features from Notion
- Automatic bidirectional synchronization
- Resilience (works even if Notion is unavailable)
Directory Structure
backend/
config/ # Symfony configuration files
packages/ # Bundle configurations
routes.yaml # Route definitions
services.yaml # Service container configuration
migrations/ # Doctrine database migrations
public/ # Web server document root
index.php # Application entry point
src/
ApiResource/ # API Platform resources
Command/ # Console commands
PopulateKnowledgeCommand.php
SeedPocDataCommand.php
Controller/ # HTTP controllers (8 controllers)
CategoryController.php
DigestController.php
KnowledgeController.php
LocalKnowledgeController.php
NotionDigestController.php
NotionSyncController.php
NotionWebhookController.php
SummaryController.php
DataFixtures/ # Database fixtures for testing
Entity/ # Doctrine entities (6 entities)
Category.php
Knowledge.php
Resource.php
ResourceContent.php
Summary.php
Tag.php
Enum/ # PHP 8.2 enumerations
SourceType.php
Status.php
Repository/ # Doctrine repositories
CategoryRepository.php
KnowledgeRepository.php
ResourceContentRepository.php
ResourceRepository.php
SummaryRepository.php
TagRepository.php
Service/ # Business logic services
Notion/ # Notion API integration
NotionCategoryService.php
NotionClient.php
NotionDatabaseService.php
NotionDigestService.php
NotionException.php
NotionKnowledgeService.php
NotionPropertyMapper.php
NotionSyncService.php
OpenAiService.php
SlackHomeRefreshService.php
SummaryService.php
TargetGroupService.php
Kernel.php # Symfony kernel
tests/ # PHPUnit tests
var/ # Cache, logs, sessions
composer.json # PHP dependenciesKey Components
1. Controllers (HTTP Layer)
Controllers handle HTTP requests and return JSON responses. They orchestrate between services and entities.
- KnowledgeController: Main CRUD operations for knowledge items (syncs to Notion)
- LocalKnowledgeController: Read-only SQLite queries (no Notion sync)
- CategoryController: Category management with auto-sync from Notion
- SummaryController: AI-generated summaries management
- NotionSyncController: Manual sync operations
- NotionWebhookController: Handles Notion webhook events
- DigestController: Digest generation and management
- NotionDigestController: Notion-specific digest operations
2. Services (Business Logic)
Services contain the core business logic and external API integrations.
Notion Services
- NotionClient: Low-level HTTP client for Notion API
- NotionKnowledgeService: Knowledge item operations in Notion
- NotionCategoryService: Category operations in Notion
- NotionSyncService: Bidirectional sync between SQLite and Notion
- NotionPropertyMapper: Maps between Notion properties and PHP arrays
- NotionDatabaseService: Database-level operations
- NotionDigestService: Digest operations in Notion
Other Services
- OpenAiService: AI completion generation with retry logic and mock mode
- SummaryService: Summary generation and management
- TargetGroupService: Target group management
- SlackHomeRefreshService: Slack integration
3. Entities (Data Models)
Doctrine ORM entities represent database tables and relationships.
- Knowledge: Main knowledge items with Notion sync
- Category: Knowledge categories with target groups
- Resource: External resources (URLs, PDFs, etc.)
- ResourceContent: Content extracted from resources
- Summary: AI-generated summaries
- Tag: Tags for resources (many-to-many)
4. Repositories (Data Access)
Repositories provide database query methods for entities.
5. Commands (CLI)
Console commands for maintenance and data operations:
- PopulateKnowledgeCommand: Bulk import knowledge items
- SeedPocDataCommand: Seed proof-of-concept data
Design Patterns
1. Repository Pattern
All database access goes through Doctrine repositories, providing a clean abstraction layer.
2. Service Layer Pattern
Business logic is encapsulated in service classes, keeping controllers thin.
3. Data Mapper Pattern
Notion API responses are mapped to PHP arrays using NotionPropertyMapper.
4. Dependency Injection
All dependencies are injected via constructor, managed by Symfony's service container.
5. Dual-Storage Pattern
Custom pattern combining local SQLite with remote Notion API:
- Write operations go to both stores
- Read operations prefer local SQLite
- Sync service keeps stores consistent
API Design
The backend exposes RESTful JSON APIs:
- Base URL:
/api - Content-Type:
application/json - Response Format: JSON
- Error Handling: Standard HTTP status codes with error messages
API Prefixes
/api/knowledge- Knowledge items (with Notion sync)/api/local- Local-only queries (SQLite)/api/categories- Category management/api/summaries- AI summaries/api/notion/sync- Sync operations/api/notion/webhook- Notion webhooks/api/digest- Digest operations
Configuration
Configuration is managed through Symfony's environment system:
.env- Environment variables (not committed).env.local- Local overrides (not committed)config/packages/- Bundle configurationsconfig/services.yaml- Service definitions
Key Environment Variables
DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db"
NOTION_API_KEY="secret_xxx"
NOTION_KNOWLEDGE_DATABASE_ID="xxx"
NOTION_CATEGORIES_DATABASE_ID="xxx"
OPENAI_API_KEY="sk-xxx"
OPENAI_MODEL="gpt-4"
OPENAI_MOCK_MODE="false"Database
The application uses SQLite for local storage with Doctrine ORM:
- Location:
var/data.db - Migrations: Managed by Doctrine Migrations
- Schema: Automatically generated from entities
Error Handling
The backend uses Symfony's exception handling:
- NotionException: Custom exception for Notion API errors
- NotFoundHttpException: 404 errors
- Standard Exceptions: Caught and converted to JSON responses
Logging
Logging is handled by Symfony's Monolog integration:
- Location:
var/log/ - Levels: DEBUG, INFO, WARNING, ERROR
- Format: JSON for structured logging
Testing
Testing infrastructure is set up with PHPUnit:
- Unit Tests: Test individual classes
- Integration Tests: Test service interactions
- Functional Tests: Test HTTP endpoints
Run tests with:
composer testPerformance Considerations
- Local SQLite Cache: Fast queries without network latency
- Notion Pagination: Handles large datasets with pagination
- Lazy Loading: Doctrine lazy-loads relationships
- HTTP Client Pooling: Reuses connections to Notion API
- OpenAI Retry Logic: Automatic retries with exponential backoff
Security
- Environment Variables: Sensitive data in
.envfiles - Input Validation: Symfony Validator component
- SQL Injection Protection: Doctrine ORM parameterized queries
- CORS: Configured via NelmioCorsBundle
- API Keys: Stored securely in environment variables
Future Enhancements
Potential improvements:
- Add authentication/authorization
- Implement caching layer (Redis)
- Add rate limiting
- Implement webhook verification
- Add API versioning
- Implement GraphQL endpoint
- Add full-text search (Elasticsearch)