Files
Munich-news/docs/SYSTEM_ARCHITECTURE.md
2025-11-11 14:09:21 +01:00

21 KiB

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