AI-Powered Competitive Intelligence Newsletter System
An intelligent newsletter generation platform that leverages Google Cloud AI (Gemini, Vertex AI) to automatically fetch, analyze, and curate competitive intelligence news.
- Daily News Fetching: Automated daily collection of competitive intelligence articles from web sources
 - AI-Powered Analysis: Gemini 2.0 Flash integration for intelligent content classification and summarization
 - Weekly Digest Compilation: Smart aggregation of daily news into comprehensive weekly newsletters
 - Compose Weekly: Advanced feature allowing manual curation with AI-powered similarity scoring and insights
 - Search & Discovery: Full-text search across historical news articles using Google Discovery Engine
 - Multi-Source Integration: Firestore for real-time data, BigQuery for analytics, and Cloud Storage for media
 
- Daily Newsletter View: Browse and manage daily news articles
 - Weekly Digest View: Review and export weekly compilations
 - Compose Weekly Interface:
- Upload Excel files with news items
 - Get Gemini-powered insights (classification, similarity scores, commentary)
 - Color-coded similarity heatmap (green for high relevance, red for low)
 - Interactive selection with "Keep?" checkboxes
 - Export to Excel or HTML
 
 - Advanced Search: Query historical articles with filters and relevance scoring
 - Setup/Configuration: Manage application settings and preferences
 
ci_newsletter/
βββ client/                    # React + TypeScript Frontend
β   βββ src/
β   β   βββ pages/            # Main application pages
β   β   β   βββ DailyNewsletter.tsx
β   β   β   βββ WeeklyDigest.tsx
β   β   β   βββ ComposeWeekly.tsx
β   β   β   βββ SearchResults.tsx
β   β   β   βββ Setup.tsx
β   β   βββ components/       # Reusable UI components
β   β   βββ backend/          # API integration layer
β   β   βββ dto/              # TypeScript interfaces
β   β   βββ routes/           # React Router configuration
β   βββ Dockerfile            # Production container
β   βββ Dockerfile.dev        # Development container
β
βββ server/                    # Python + Flask Backend
β   βββ app.py                # Main Flask application
β   βββ news_fetcher.py       # Daily news collection
β   βββ digest_generation.py  # Weekly digest compiler
β   βββ compose_weekly.py     # Compose Weekly feature
β   βββ news_search.py        # Discovery Engine integration
β   βββ firebase_helpers.py   # Firestore operations
β   βββ bigquery_helpers.py   # BigQuery operations
β   βββ utils.py              # Shared utilities
β   βββ config/               # Firestore prompts & configs
β   βββ requirements.txt      # Python dependencies
β
βββ cloud_run_job/            # GCP Cloud Run job for automated fetching
β   βββ main.py               # Job entry point
β   βββ Dockerfile            # Job container
β
βββ scripts/                   # Utility scripts
β   βββ start_dev.sh          # Start development servers
β   βββ stop_dev.sh           # Stop development servers
β   βββ sync_bq_to_firestore.py
β
βββ docker/docker-compose.yml         # Production Docker setup
βββ docker/docker-compose.dev.yml     # Development Docker override
βββ docker/cloudbuild.yaml           # CI/CD configuration
βββ docker/deploy-to-gcp.sh          # GCP deployment script
βββ .env                      # Environment configuration
- Node.js 18+ (for frontend)
 - Python 3.11+ (for backend)
 - Google Cloud Project with the following APIs enabled:
- Vertex AI API
 - Firestore API
 - BigQuery API
 - Cloud Storage API
 - Discovery Engine API
 
 - Service Account with appropriate permissions
 - Docker (optional, for containerized deployment)
 
- 
Clone the repository
git clone <repository-url> cd ci_newsletter
 - 
Configure environment
cp .env.example .env # Edit .env with your GCP project detailsKey environment variables:
PROJECT_ID: Your GCP project IDREGION: GCP region (default: europe-west4)MODEL_FLASH: Gemini model (default: gemini-2.0-flash-001)PORT: Backend port (default: 5001)COMPOSE_WEEKLY_SIM_WEIGHT: Similarity weight for Compose Weekly (0.0-1.0)
 - 
Place your service account credentials
# Place your service account JSON file in the root directory # It should match the pattern configured in .env
 - 
Start development servers
# Automated startup (recommended) ./scripts/start_dev.sh # Or manually: # Backend cd server python -m venv .venv source .venv/bin/activate pip install -r requirements.txt python app.py # Frontend (in new terminal) cd client npm install npm run dev
 - 
Access the application
- Frontend: http://localhost:5173
 - Backend API: http://localhost:5001/api
 
 
# Start with hot-reload enabled
docker-compose -f docker/docker-compose.yml -f docker/docker-compose.dev.yml up
# Access at:
# - Frontend: http://localhost:5173
# - Backend: http://localhost:5001chmod +x docker/deploy-to-gcp.sh
./docker/deploy-to-gcp.shThis will:
- Build Docker images for backend and frontend
 - Push to Google Container Registry
 - Deploy to Cloud Run
 - Configure environment variables
 - Return service URLs
 
The repository includes docker/cloudbuild.yaml for automated CI/CD:
# Trigger build manually
gcloud builds submit --config=docker/cloudbuild.yaml
# Or connect to GitHub for automatic deployments
gcloud builds triggers create github \
  --repo-name=<your-repo-name> \
  --repo-owner=<your-github-username> \
  --branch-pattern="^main$" \
  --build-config=docker/cloudbuild.yamlSee DOCKER_DEPLOYMENT.md for detailed instructions.
GET /api/daily/news- Fetch daily news articlesGET /api/daily/news/<date>- Get news for specific date
GET /api/weekly/digests- List all weekly digestsGET /api/weekly/digest/<id>- Get specific digestPOST /api/weekly/generate- Generate new weekly digest
POST /api/compose-weekly/upload- Upload Excel filePOST /api/compose-weekly/analyze- Analyze with Gemini AIPOST /api/compose-weekly/export- Export curated list
POST /api/search- Search historical articlesGET /api/search/history- Get search history
- React 18 - UI framework
 - TypeScript - Type-safe JavaScript
 - Vite - Build tool and dev server
 - Tailwind CSS - Utility-first CSS framework
 - Radix UI - Accessible component primitives
 - React Router - Client-side routing
 - Axios - HTTP client
 
- Python 3.11 - Runtime
 - Flask 3.0 - Web framework
 - Flask-CORS - Cross-origin resource sharing
 - Vertex AI SDK - Gemini and embeddings
 - Google Cloud Firestore - NoSQL database
 - Google Cloud BigQuery - Data warehouse
 - Google Cloud Storage - Media storage
 - Google Discovery Engine - Search service
 
- Docker - Containerization
 - Docker Compose - Multi-container orchestration
 - Google Cloud Run - Serverless container platform
 - Google Cloud Build - CI/CD pipeline
 - Nginx - Frontend static file serving
 
- Upload: User uploads Excel file with columns: Title, URL, Date, Abstract, CI Comment
 - Analysis: Backend sends data to Gemini for:
- Classification (relevant/not relevant)
 - Similarity scoring (0-100, how similar to existing content)
 - AI commentary (insights about the article)
 
 - Review: UI displays results with:
- Color-coded similarity badges (green = high, red = low)
 - Gemini insights as plain text
 - Checkboxes to select items to keep
 
 - Export: Export selected items to Excel or HTML
 
The system uses Vertex AI text embeddings (text-embedding-005) to calculate similarity between new articles and historical content. The similarity weight (COMPOSE_WEEKLY_SIM_WEIGHT) controls the influence of embedding similarity vs. metadata matching.
Gemini 2.0 Flash analyzes each article for:
- Relevance: Is this competitive intelligence?
 - Novelty: How unique is this compared to existing content?
 - Key Points: What are the main takeaways?
 
News Sources β Cloud Run Job (Daily) β Firestore
                                      β
                                   BigQuery
                                      β
User uploads Excel β Backend API β Gemini Analysis
                                      β
                                 Similarity Check
                                      β
                              Results to Frontend
- All sensitive credentials stored in 
.env(git-ignored) - Service account JSON files excluded via 
.gitignore - CORS configured for localhost and production domains
 - Environment-specific configurations
 - No hardcoded secrets in codebase
 
# Start development environment
./scripts/start_dev.sh
# Stop development environment
./scripts/stop_dev.sh
# Sync BigQuery to Firestore
python scripts/sync_bq_to_firestore.py
# Convert Excel to Compose Weekly format
python scripts/excelfy_compose_weekly.py.env- Environment variables and API keysserver/config/dev.prompt_weekly_compose- Gemini prompt for Compose Weeklydocker/docker-compose.yml- Production container setupdocker/docker-compose.dev.yml- Development overridesdocker/cloudbuild.yaml- CI/CD pipeline configuration
# Check if port 5001 is in use
lsof -ti :5001 | xargs kill -9
# Restart
.venv/bin/python server/app.py# Clear cache and reinstall
cd client
rm -rf node_modules dist
npm install- Verify 
MODEL_FLASHis set correctly in.env - Check service account has Vertex AI permissions
 - Ensure billing is enabled on GCP project
 
# Clean up and rebuild
docker-compose down -v
docker-compose build --no-cache
docker-compose up- DOCKER_DEPLOYMENT.md - Complete Docker deployment guide
 - Google Cloud Documentation
 - Vertex AI Gemini API
 - Flask Documentation
 - React Documentation
 
All rights reserved
Last Updated: October 2025