# Munich News Daily - System Architecture ## πŸ“Š Complete System Overview ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Munich News Daily System β”‚ β”‚ Fully Automated Pipeline β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ Daily Schedule β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ 6:00 AM Berlin β”‚ β”‚ News Crawler β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ News Crawler β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚ Fetch RSS β”‚β†’ β”‚ Extract β”‚β†’ β”‚ Summarize β”‚β†’ β”‚ Save to β”‚β”‚ β”‚ β”‚ Feeds β”‚ β”‚ Content β”‚ β”‚ with AI β”‚ β”‚ MongoDB β”‚β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ β”‚ β”‚ Sources: SΓΌddeutsche, Merkur, BR24, etc. β”‚ β”‚ Output: Full articles + AI summaries β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ Articles saved β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ MongoDB β”‚ β”‚ (Data Storage) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ Wait for crawler β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ 7:00 AM Berlin β”‚ β”‚ Newsletter Sender β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Newsletter Sender β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚ Wait for β”‚β†’ β”‚ Fetch β”‚β†’ β”‚ Generate β”‚β†’ β”‚ Send to β”‚β”‚ β”‚ β”‚ Crawler β”‚ β”‚ Articles β”‚ β”‚ Newsletter β”‚ β”‚ Subscribersβ”‚β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β”‚ β”‚ β”‚ Features: Tracking pixels, link tracking, HTML templates β”‚ β”‚ Output: Personalized newsletters with engagement tracking β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ Emails sent β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Subscribers β”‚ β”‚ (Email Inboxes) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ Opens & clicks β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Tracking System β”‚ β”‚ (Analytics API) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ## πŸ”„ Data Flow ### 1. Content Acquisition (6:00 AM) ``` RSS Feeds β†’ Crawler β†’ Full Content β†’ AI Summary β†’ MongoDB ``` **Details**: - Fetches from multiple RSS sources - Extracts full article text - Generates concise summaries using Ollama - Stores with metadata (author, date, source) ### 2. Newsletter Generation (7:00 AM) ``` MongoDB β†’ Articles β†’ Template β†’ HTML β†’ Email ``` **Details**: - Waits for crawler to finish (max 30 min) - Fetches today's articles with summaries - Applies Jinja2 template - Injects tracking pixels - Replaces links with tracking URLs ### 3. Engagement Tracking (Ongoing) ``` Email Open β†’ Pixel Load β†’ Log Event β†’ Analytics Link Click β†’ Redirect β†’ Log Event β†’ Analytics ``` **Details**: - Tracks email opens via 1x1 pixel - Tracks link clicks via redirect URLs - Stores engagement data in MongoDB - Provides analytics API ## πŸ—οΈ Component Architecture ### Docker Containers ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Docker Network β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ MongoDB β”‚ β”‚ Crawler β”‚ β”‚ Sender β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Port: 27017 │←─│ Schedule: │←─│ Schedule: β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ 6:00 AM β”‚ β”‚ 7:00 AM β”‚ β”‚ β”‚ β”‚ Storage: β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ - articles β”‚ β”‚ Depends on: β”‚ β”‚ Depends on: β”‚ β”‚ β”‚ β”‚ - subscribersβ”‚ β”‚ - MongoDB β”‚ β”‚ - MongoDB β”‚ β”‚ β”‚ β”‚ - tracking β”‚ β”‚ β”‚ β”‚ - Crawler β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ All containers auto-restart on failure β”‚ β”‚ All use Europe/Berlin timezone β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### Backend Services ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Backend Services β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Flask API (Port 5001) β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ Tracking β”‚ β”‚ Analytics β”‚ β”‚ Privacy β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Endpoints β”‚ β”‚ Endpoints β”‚ β”‚ Endpoints β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Services Layer β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ Tracking β”‚ β”‚ Analytics β”‚ β”‚ Ollama β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Service β”‚ β”‚ Service β”‚ β”‚ Client β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ## πŸ“… Daily Timeline ``` Time (Berlin) β”‚ Event β”‚ Duration ───────────────┼──────────────────────────┼────────── 05:59:59 β”‚ System idle β”‚ - 06:00:00 β”‚ Crawler starts β”‚ ~10-20 min 06:00:01 β”‚ - Fetch RSS feeds β”‚ 06:02:00 β”‚ - Extract content β”‚ 06:05:00 β”‚ - Generate summaries β”‚ 06:15:00 β”‚ - Save to MongoDB β”‚ 06:20:00 β”‚ Crawler finishes β”‚ 06:20:01 β”‚ System idle β”‚ ~40 min 07:00:00 β”‚ Sender starts β”‚ ~5-10 min 07:00:01 β”‚ - Wait for crawler β”‚ (checks every 30s) 07:00:30 β”‚ - Crawler confirmed done β”‚ 07:00:31 β”‚ - Fetch articles β”‚ 07:01:00 β”‚ - Generate newsletters β”‚ 07:02:00 β”‚ - Send to subscribers β”‚ 07:10:00 β”‚ Sender finishes β”‚ 07:10:01 β”‚ System idle β”‚ Until tomorrow ``` ## πŸ” Security & Privacy ### Data Protection ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Privacy Features β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Data Retention β”‚ β”‚ β”‚ β”‚ - Personal data: 90 days β”‚ β”‚ β”‚ β”‚ - Anonymization: Automatic β”‚ β”‚ β”‚ β”‚ - Deletion: On request β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ User Rights β”‚ β”‚ β”‚ β”‚ - Opt-out: Anytime β”‚ β”‚ β”‚ β”‚ - Data access: API available β”‚ β”‚ β”‚ β”‚ - Data deletion: Full removal β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Compliance β”‚ β”‚ β”‚ β”‚ - GDPR compliant β”‚ β”‚ β”‚ β”‚ - Privacy notice in emails β”‚ β”‚ β”‚ β”‚ - Transparent tracking β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ## πŸ“Š Database Schema ### Collections ``` MongoDB (munich_news) β”‚ β”œβ”€β”€ articles β”‚ β”œβ”€β”€ title β”‚ β”œβ”€β”€ author β”‚ β”œβ”€β”€ content (full text) β”‚ β”œβ”€β”€ summary (AI generated) β”‚ β”œβ”€β”€ link β”‚ β”œβ”€β”€ source β”‚ β”œβ”€β”€ published_at β”‚ └── crawled_at β”‚ β”œβ”€β”€ subscribers β”‚ β”œβ”€β”€ email β”‚ β”œβ”€β”€ active β”‚ β”œβ”€β”€ tracking_enabled β”‚ └── subscribed_at β”‚ β”œβ”€β”€ rss_feeds β”‚ β”œβ”€β”€ name β”‚ β”œβ”€β”€ url β”‚ └── active β”‚ β”œβ”€β”€ newsletter_sends β”‚ β”œβ”€β”€ tracking_id β”‚ β”œβ”€β”€ newsletter_id β”‚ β”œβ”€β”€ subscriber_email β”‚ β”œβ”€β”€ opened β”‚ β”œβ”€β”€ first_opened_at β”‚ └── open_count β”‚ β”œβ”€β”€ link_clicks β”‚ β”œβ”€β”€ tracking_id β”‚ β”œβ”€β”€ newsletter_id β”‚ β”œβ”€β”€ subscriber_email β”‚ β”œβ”€β”€ article_url β”‚ β”œβ”€β”€ clicked β”‚ └── clicked_at β”‚ └── subscriber_activity β”œβ”€β”€ email β”œβ”€β”€ status (active/inactive/dormant) β”œβ”€β”€ last_opened_at β”œβ”€β”€ last_clicked_at β”œβ”€β”€ total_opens └── total_clicks ``` ## πŸš€ Deployment Architecture ### Development ``` Local Machine β”œβ”€β”€ Docker Compose β”‚ β”œβ”€β”€ MongoDB (no auth) β”‚ β”œβ”€β”€ Crawler β”‚ └── Sender β”œβ”€β”€ Backend (manual start) β”‚ └── Flask API └── Ollama (optional) └── AI Summarization ``` ### Production ``` Server β”œβ”€β”€ Docker Compose (prod) β”‚ β”œβ”€β”€ MongoDB (with auth) β”‚ β”œβ”€β”€ Crawler β”‚ └── Sender β”œβ”€β”€ Backend (systemd/pm2) β”‚ └── Flask API (HTTPS) β”œβ”€β”€ Ollama (optional) β”‚ └── AI Summarization └── Nginx (reverse proxy) └── SSL/TLS ``` ## πŸ”„ Coordination Mechanism ### Crawler-Sender Synchronization ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Coordination Flow β”‚ β”‚ β”‚ β”‚ 6:00 AM β†’ Crawler starts β”‚ β”‚ ↓ β”‚ β”‚ Crawling articles... β”‚ β”‚ ↓ β”‚ β”‚ Saves to MongoDB β”‚ β”‚ ↓ β”‚ β”‚ 6:20 AM β†’ Crawler finishes β”‚ β”‚ ↓ β”‚ β”‚ 7:00 AM β†’ Sender starts β”‚ β”‚ ↓ β”‚ β”‚ Check: Recent articles? ──→ No ──┐ β”‚ β”‚ ↓ Yes β”‚ β”‚ β”‚ Proceed with send β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ ← Wait 30s ← Wait 30s ← Wait 30sβ”˜ β”‚ β”‚ (max 30 minutes) β”‚ β”‚ β”‚ β”‚ 7:10 AM β†’ Newsletter sent β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ## πŸ“ˆ Monitoring & Observability ### Key Metrics ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Metrics to Monitor β”‚ β”‚ β”‚ β”‚ Crawler: β”‚ β”‚ - Articles crawled per day β”‚ β”‚ - Crawl duration β”‚ β”‚ - Success/failure rate β”‚ β”‚ - Summary generation rate β”‚ β”‚ β”‚ β”‚ Sender: β”‚ β”‚ - Newsletters sent per day β”‚ β”‚ - Send duration β”‚ β”‚ - Success/failure rate β”‚ β”‚ - Wait time for crawler β”‚ β”‚ β”‚ β”‚ Engagement: β”‚ β”‚ - Open rate β”‚ β”‚ - Click-through rate β”‚ β”‚ - Active subscribers β”‚ β”‚ - Dormant subscribers β”‚ β”‚ β”‚ β”‚ System: β”‚ β”‚ - Container uptime β”‚ β”‚ - Database size β”‚ β”‚ - Error rate β”‚ β”‚ - Response times β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ## πŸ› οΈ Maintenance Tasks ### Daily - Check logs for errors - Verify newsletters sent - Monitor engagement metrics ### Weekly - Review article quality - Check subscriber growth - Analyze engagement trends ### Monthly - Archive old articles - Clean up dormant subscribers - Update dependencies - Review system performance ## πŸ“š Technology Stack ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Technology Stack β”‚ β”‚ β”‚ β”‚ Backend: β”‚ β”‚ - Python 3.11 β”‚ β”‚ - Flask (API) β”‚ β”‚ - PyMongo (Database) β”‚ β”‚ - Schedule (Automation) β”‚ β”‚ - Jinja2 (Templates) β”‚ β”‚ - BeautifulSoup (Parsing) β”‚ β”‚ β”‚ β”‚ Database: β”‚ β”‚ - MongoDB 7.0 β”‚ β”‚ β”‚ β”‚ AI/ML: β”‚ β”‚ - Ollama (Summarization) β”‚ β”‚ - Phi3 Model (default) β”‚ β”‚ β”‚ β”‚ Infrastructure: β”‚ β”‚ - Docker & Docker Compose β”‚ β”‚ - Linux (Ubuntu/Debian) β”‚ β”‚ β”‚ β”‚ Email: β”‚ β”‚ - SMTP (configurable) β”‚ β”‚ - HTML emails with tracking β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` --- **Last Updated**: 2024-01-16 **Version**: 1.0 **Status**: Production Ready βœ