Project Info
Inspiration
In an era of polarized media, Based News was created to give readers a clearer picture of political news. We believe that informed citizens make better decisions, and informed citizens need access to unbiased information.
What it does
Based News is an AI-driven news aggregate, built to filter out the bias and deceit from mainstream media and other outlets, by conducting deep analysis on all sides of reporting. We offer general summaries of trending headlines, free from political bias, political bias analysis on different news outlets covering a headline, and a view into the public's opinion on a topic through Youtube comments.
How we built it
Our tech stack runs deep. For development of our Full-Stack application, we used Next.js App Router, with Supabase and Prisma, deployed on Vercel. To build our analysis pipelines, we utilized N8N, Parallel Web Systems, Exa.ai, and some custom JS scripts that took FOREVER to get working. We've attached diagrams depicting the systems and pipelines used in this project.
Challenges we ran into
Where do we even start. Firstly, we entered the project with a completely different idea than Based News. Our first five hours of the competition were landing on the idea of Based News and researching how in the world we were going to build it. Another challenge we ran into was honing our N8N skills and building robust workflows that function the way we intended. Additionally, we also faced the challenge of speeding up some of our workflows and API calls. The worst challenge of all was gaining insight on how the public viewed trending news. Ideally, we wanted to scrape Reddit or X, but Reddit API required you to request access and the X api rate-limited after 100 posts (NOT ENOUGH DATA). Hence, we found a workaround... Youtube Comments!!! We built our own API server using the Youtube Data API and a secret Python library to scrape all the popular comments off of videos related to specific headlines.
Accomplishments we're proud of
An accomplishment that we are extremely proud of is the Headline Ingestion and Aggregation pipeline. It took the most time to complete and ended up working (almost) exactly how we wanted it to. Another accomplishment we are extremely proud of is collaborating on the same code base without any conflicts. Not running into any merge conflicts attributes greatly to the completion of this project.
What we learned
We are baffled by the number of technologies and concepts we worked with and learned about over the course of this competition. We want to give a huge shoutout to the boys at OpenNote, who taught us so much about vector stores and web search agents, which were essential to the core functionalities of our project.
What's next
BasedNews is barely an MVP. With the complex nature of the problem we are tackling, there are several bugs and inefficiencies in our systems. Our next steps are to finish and refine the core functions of the software, and optimize where we can.
Based News
A political news aggregator that provides neutral summaries with bias ratings and public opinion analysis. Built for CruzHacks 2026.
Live Demo: https://cruzhacks2026-kappa.vercel.app/
Features
- Neutral Summaries - Direct, politically neutral summaries of the latest US political news
- 7-Point Bias Scale - Every source categorized from Far Left to Far Right
- Public Opinion - Real-time sentiment analysis from YouTube comments
Environment Variables
Create a .env file in the root directory with the following variables:
YOUTUBE_API_KEY=your_youtube_api_key_here
You can obtain a YouTube Data API key from the Google Cloud Console.
Running the Public Opinion API (FastAPI)
The public opinion analysis feature requires running a local FastAPI server exposed via ngrok.
Prerequisites
- Python 3.11+
- ngrok account with a custom domain (or use the free tier)
- OpenAI API key
- install dependencies from
requirements.txt
Start the FastAPI server
In one terminal:
cd python_public_opinion
OPENAI_API_KEY=your_openai_api_key uvicorn main:app --host 0.0.0.0 --port 8000
Start the ngrok tunnel
In another terminal:
ngrok http 8000 --domain=bursting-satyr-genuinely.ngrok-free.app
The FastAPI will now be accessible at https://bursting-satyr-genuinely.ngrok-free.app.
API Endpoints
1. GET /api/headlines
Fetches paginated headlines from the database, ordered by date (newest first).
Query Parameters:
skip(optional, default: 0) - Number of headlines to skiptake(optional, default: 6) - Number of headlines to fetch
Response:
{
"headlines": [...],
"hasMore": true,
"totalCount": 25
}
curl:
curl "https://cruzhacks2026-kappa.vercel.app/api/headlines?skip=0&take=6"
2. POST /api/headline-sources
Forwards a headline to an n8n webhook to fetch related news sources with bias ratings. Used to find additional sources covering the same story.
Request Body:
{
"headline": "string (required)",
"description": "string (required)",
"date": "string (required)"
}
curl:
curl -X POST "https://cruzhacks2026-kappa.vercel.app/api/headline-sources" \
-H "Content-Type: application/json" \
-d '{"headline": "Federal Judge Limits Immigration Enforcement", "description": "A federal judge issued a ruling restricting immigration agents.", "date": "2026-01-17"}'
3. POST /api/ingest/headlines
Ingests articles from 6 hardcoded RSS feeds (CNN, NYTimes, Fox News, ABC News, WSJ, LA Times) into the Article table. Skips duplicates based on link URL.
Request Body: None required
Response:
{
"ok": true,
"totalParsed": 120,
"totalInserted": 15,
"perFeed": [
{ "url": "http://rss.cnn.com/...", "title": "CNN US", "parsed": 20, "inserted": 3 }
]
}
curl:
curl -X POST "https://cruzhacks2026-kappa.vercel.app/api/ingest/headlines"
4. GET /api/headlines/[id]/public-opinion
Returns public opinion analysis for a specific headline. If cached, returns immediately; otherwise, orchestrates calls to YouTube search and FastAPI analysis endpoints, then caches the result.
Path Parameters:
id- The headline UUID
Response:
{
"summary": "Analysis of public sentiment...",
"totalComments": 1500,
"videosProcessed": 5,
"cached": true
}
curl:
curl "https://cruzhacks2026-kappa.vercel.app/api/headlines/<HEADLINE_ID>/public-opinion"
Note: Replace <HEADLINE_ID> with an actual headline UUID from the /api/headlines response.
5. POST /api/publicopinion
Searches YouTube for videos matching a query string. Returns up to 5 most relevant videos. Used internally by the public-opinion endpoint.
Request Body:
{
"query": "string (required)",
"publishedAfter": "ISO 8601 date string (optional)"
}
Response:
{
"videos": [
{
"videoId": "abc123",
"title": "Video Title",
"url": "https://www.youtube.com/watch?v=abc123",
"thumbnail": "https://i.ytimg.com/...",
"publishedAt": "2026-01-17T12:00:00Z"
}
]
}
curl:
curl -X POST "https://cruzhacks2026-kappa.vercel.app/api/publicopinion" \
-H "Content-Type: application/json" \
-d '{"query": "immigration enforcement ruling", "publishedAfter": "2026-01-15T00:00:00Z"}'
6. POST /api/publicopinion/analyze
Forwards YouTube video URLs to a FastAPI backend (Python service) that scrapes comments and generates an AI-powered public sentiment summary.
Request Body:
{
"youtube_urls": ["https://www.youtube.com/watch?v=abc123", "..."]
}
Response:
{
"summary": "Public sentiment analysis...",
"total_comments": 1500,
"videos_processed": 5
}
curl:
curl -X POST "https://cruzhacks2026-kappa.vercel.app/api/publicopinion/analyze" \
-H "Content-Type: application/json" \
-d '{"youtube_urls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"]}'
Architecture
┌─────────────────────────────────────────────────────────────────────────┐
│ Frontend │
│ (React UI) │
└─────────────────────────────┬───────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Next.js API Routes │
├─────────────┬─────────────┬─────────────┬─────────────┬─────────────────┤
│ /headlines │ /headline- │ /ingest/ │ /headlines/ │ /publicopinion │
│ │ sources │ headlines │ [id]/public │ /analyze │
│ │ │ │ -opinion │ │
└──────┬──────┴──────┬──────┴──────┬──────┴──────┬──────┴────────┬────────┘
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────────────┐
│PostgreSQL│ │n8n │ │RSS Feeds │ │YouTube │ │FastAPI (Python) │
│ │ │Webhook │ │ │ │Data API │ │ │
└──────────┘ └──────────┘ └──────────┘ └──────────┘ └─────────────────┘
Tech Stack
- Frontend: Next.js, React, Tailwind CSS
- Backend: Next.js API Routes, Prisma ORM
- Database: PostgreSQL (Supabase)
- External Services: n8n, YouTube Data API, Exa.ai
- ML/AI: FastAPI Python service with OpenAI
Analysis
View
Metric
- 12
- 2
Figures cover GitHub contributors during the hackathon window. A co-authored commit counts in full for each author, so per-member totals add up to more than the whole-team figures.
Technology
- CSSIn code
- FastAPIIn code
- Next.jsIn code
- OpenAIIn code
- PostgreSQLIn code
- PythonIn code
- ReactIn code
- SQLIn code
- Tailwind CSSIn code
- TypeScriptIn code
- SupabaseClaimed
- VercelClaimed
10 of 12 appear in the indexed code. 2 claimed on Devpost could not be matched to code, which may simply mean the tool leaves no trace in the repository.
AI coding agents
No AI coding agent signals were found in this repository.
Detected from committed agent config files and commit authorship. Absence of a signal is not proof an agent was unused.
Codebase size
Source size
94 KB
Source files
27
Counts recognized source files only; vendored directories, binaries and lockfiles are excluded, so this is smaller than the repository on disk.
Repository
leo-kildani/cruzhacks2026
47 files · 478 KB · @ e365660
Structure
Interface
11 files · 23%Screens, components and styles rendered to the user.
API & routing
6 files · 13%Request entry points: routes, handlers and controllers.
Application logic
6 files · 13%Domain rules, services and shared utilities.
Data & schema
5 files · 11%Schema definitions, migrations and data access.
Supporting
Layers are inferred from where files sit in the tree, not from reading the code. A project that names its directories unconventionally will read oddly here — open the file browser to check anything the diagram implies.
Languages
- TypeScript80%
- Markdown8%
- Python6%
- CSS5%
- SQL1%
Share of indexed source by file size. Binary and vendored files are excluded.
Dependencies
package.json
npm · 26- @prisma/adapter-pg
- @prisma/client
- @radix-ui/react-separator
- @radix-ui/react-slot
- class-variance-authority
- clsx
- csv-parse
- dotenv
- lucide-react
- next
- pg
- react
- react-dom
- rss-parser
- tailwind-merge
- +11 more
python_public_opinion/requirements.txt
pypi · 4- fastapi
- openai
- uvicorn[standard]
- youtube-comment-downloader
Declared in the repository’s manifests at the indexed commit. A declared package is not proof it is used, and runtime dependencies are listed first.
This project’s features have not been analysed yet.
Export this project's context (description, README, evidence, key source files) to chat with an AI agent elsewhere.