Yappa Knowledge Hub - Architecture & Database Design
Version: 1.0 | Date: 2026-02-15
System Overview
Slack Bot (Node.js/Bolt) ─HTTP─► Symfony Backend (PHP 8.2) ─API─► Notion (Cloud DB)
│
├─► OpenAI API (GPT-4)
└─► Slack API (Send DMs)Technology Stack
| Layer | Technology | Role |
|---|---|---|
| Input | Slack Bot (Node.js, @slack/bolt) | UI — commands, modals, shortcuts, reactions |
| Input | Notion UI | Direct web access to databases |
| Processing | Symfony 7.2 (PHP) | REST API, business logic, AI orchestration |
| Storage | Notion Databases | Single source of truth (3 databases) |
| AI | OpenAI GPT-4 | Summary generation per target group |
| Cache | Redis (optional) | Performance layer, 5-minute TTL |
High-Level Architecture
Notion Database Schema
Database 1: Knowledge Items
ID: 306e292a15d58004a8cbc222dcd48bb2
| Property | Type | Required | Description |
|---|---|---|---|
| Title | title | ✅ | Knowledge item name |
| Content | rich_text | ✅ | Full content (up to 2000 chars) |
| Status | status | ✅ | Draft → Review → Published → Archived/Outdated |
| Tags | multi_select | Keywords for filtering | |
| Categories | relation | Link to Categories DB | |
| Priority | select | High / Medium / Low | |
| Target Groups | multi_select | Audience segments | |
| Source Type | select | Slack Message / Manual / File / URL | |
| Source URL | url | Original link | |
| Author | people | Who created it | |
| AI Summary | rich_text | Generated per target group | |
| Slack User ID | rich_text | Traceability | |
| Slack Message TS | rich_text | Message timestamp | |
| Slack Channel ID | rich_text | Channel identifier | |
| View Count | number | Access tracking | |
| Last Reviewed | date | Content freshness | |
| Attachments | files | Supporting files | |
| Created | created_time | Auto | |
| Last Edited | last_edited_time | Auto |
Database 2: Categories (Thematic Lists)
ID: 306e292a15d5805dae13e64bed8519c5
| Property | Type | Required | Description |
|---|---|---|---|
| Name | title | ✅ | Category name |
| Description | rich_text | Purpose and scope | |
| Icon | rich_text | Emoji icon | |
| Default Target Groups | multi_select | Auto-assigned groups for new items | |
| Subscribers | people | Users who receive digests | |
| Digest Frequency | select | Daily / Weekly / Bi-weekly / Monthly / On-demand | |
| Digest Day | select | Day of week for delivery | |
| Active | checkbox | ✅ | Whether category is in use |
| Knowledge Count | rollup | Auto | Items in this category |
| Last Digest | date | When last digest was sent | |
| Created | created_time | Auto |
Database 3: Digest Reports
ID: 306e292a15d580d7a0f6fe8421baff10
| Property | Type | Required | Description |
|---|---|---|---|
| Title | title | ✅ | Digest name |
| Category | relation | Link to Categories DB | |
| Period Start | date | Report period start | |
| Period End | date | Report period end | |
| Items Count | number | Items included | |
| Target Groups | multi_select | Audience | |
| Generated By | people | Who requested | |
| Status | status | Generating / Sent / Failed | |
| Slack Sent | checkbox | Sent to Slack DMs | |
| Recipients | rich_text | Slack user IDs | |
| Generated At | created_time | Auto |
API Endpoints
POST /api/knowledge Create knowledge item
GET /api/knowledge List knowledge items
GET /api/knowledge/{id} Get single item
PUT /api/knowledge/{id} Update item
DELETE /api/knowledge/{id} Delete item
POST /api/knowledge/search Search knowledge
POST /api/categories Create category
GET /api/categories List categories
GET /api/categories/{id} Get category
PUT /api/categories/{id} Update category
DELETE /api/categories/{id} Delete category
POST /api/digests/generate Generate digest report
GET /api/digests List digests
GET /api/digests/{id} Get digest
POST /api/digests/{id}/send Send digest to Slack
POST /api/notion/sync Sync data to Notion
GET /api/notion/sync/status Check sync statusData Flow Patterns
Add Knowledge (most common path, ~3-5s)
Generate Digest (~5-10s)
Search Knowledge (~1-2s)
User → Slack → Symfony → Notion Search API → Format → Slack ResponseService Architecture
Symfony Services
| Service | Methods | Purpose |
|---|---|---|
NotionClient | request(), retry logic | HTTP client for Notion API |
NotionKnowledgeService | CRUD operations | Knowledge item management |
NotionCategoryService | CRUD operations | Category management |
NotionPropertyMapper | Property conversion | Notion ↔ PHP mapping |
AIService | generateSummary() | OpenAI integration |
DigestService | generateDigest() | Report generation |
SlackService | sendDM(), sendMessage() | Slack messaging |
Slack Bot Handlers (TypeScript)
| Handler | File | Purpose |
|---|---|---|
| Commands | src/handlers/commands.ts | /knowledge slash command |
| Actions | src/handlers/actions.ts | Button and menu actions |
| Submissions | src/handlers/submissions.ts | Modal form submissions |
| Events | src/handlers/events.ts | URL detection, file shares |
| Reactions | src/handlers/reactions.ts | Emoji-based capture |
| Shortcuts | src/handlers/shortcuts.ts | Message & global shortcuts |
| Home | src/handlers/home.ts | App Home tab |
| Dashboard | src/handlers/dashboard.ts | Dashboard rendering |
| Items | src/handlers/items.ts | Knowledge item operations |
| Lists | src/handlers/lists.ts | Category/list management |
| SaveModals | src/handlers/saveModals.ts | Save modal handlers |
| SearchModal | src/handlers/searchModal.ts | Search modal interface |
File Structure
yappa-knowledge-hub/
├── src/ # Slack bot (Node.js)
│ ├── app.js # Entry point
│ ├── handlers/ # Slack event handlers
│ ├── services/ # Business logic
│ └── i18n/nl.js # Dutch translations
├── backend/ # Symfony API
│ ├── src/
│ │ ├── Controller/ # REST endpoints
│ │ ├── Entity/ # Doctrine entities
│ │ ├── Service/Notion/ # Notion integration
│ │ └── Kernel.php
│ ├── config/ # Symfony config
│ └── var/data.db # SQLite (legacy/backup)
├── tests/ # Jest tests
├── docs/ # Documentation
│ ├── weekly/ # 12 weekly internship reports
│ └── report/ # Final report
└── scripts/ # Utility scriptsDesign Decisions
| Decision | Rationale |
|---|---|
| Symfony backend | Existing codebase, strong for background jobs, type safety |
| Notion as primary DB | Single source of truth, web UI, collaboration |
| SQLite as backup | Fallback during Notion outages, local dev |
| Socket Mode | No public URL needed for development |
| Dutch localization | Belgian company (Yappa), NL-speaking users |
| Per-group AI summaries | Different audiences need different perspectives |
Performance Considerations
- Notion API rate limit: 3 req/sec — batch operations, caching needed
- OpenAI latency: 2-3s per summary — async processing via Symfony Messenger
- Redis caching: Optional, for frequently accessed categories/knowledge
- Pagination: All list endpoints support limit/offset