Watch my work ↗
AI & publishingPROJECT CASE STUDY

Pulse — An AI That Publishes African News Every Morning

An AI news engine I built to solve my own problem: running out of blog ideas and losing an hour every morning to catch-up reading. Pulse researches, writes, and publishes tech, fintech, and business stories — with guaranteed African coverage — before I've had coffee.

Visit Pulse
Pulse — AI news engine project cover
Daily
Publishes automatically every morning
0
Manual editorial steps required
6–10
Original stories per ingestion run
5
African news sources monitored

What is Pulse?

Pulse is a news page that's different every morning. A scheduled Claude AI agent goes out each day, researches what's happening across tech, fintech, and business — with a deliberate, non-negotiable slice being African coverage — writes original 120–220 word summaries (not scraped headlines, not paraphrased ledes), and publishes everything to pulsenews.buzz via an authenticated API, before I've sat down to work.

No CMS. No editorial calendar. No person deciding what runs today. The engineering — the data model, the ingest boundary, the research rules — is what makes the quality consistent. I built this to solve my own problem first, and then realised the engineering story behind it was worth documenting as a portfolio piece in its own right.

What it looks like

A clean, responsive news reader — desktop, tablet, mobile, and even flip phone. No accounts, no tracking, no paywalls.

Pulse news app on MacBook — daily African tech and fintech stories
Pulse mobile app — African fintech news on iPhone
Mobile — responsive layout with the same daily feed
Pulse on mobile and flip phone
Works wherever you read — including the flip phone comeback
Pulse on flip phone — responsive design for all devices

Flip phone view — because good responsive design has no excuses

Why this exists

I write a lot. The bottleneck was never the writing — it was the 45 minutes every morning I'd lose to catch-up reading before I could start. I'd scroll through half a dozen sources trying to remember whether that funding round closed, what the SECZ actually announced, or which startup was in the news this week. By the time I had context, I'd already burned the most productive part of my morning.

The news apps I had didn't solve this. General apps bury African fintech. Fintech newsletters land weekly. X/Twitter is an engagement machine, not a research tool. What I actually needed was a research assistant: something that reads the sources, picks what matters, writes an honest summary, and crucially — shows me exactly where it got the information so I can go deeper when I need to.

How it's built

Pulse is a Next.js 16 app on React 19, with Prisma over PostgreSQL for storage, deployed on Railway. The interesting engineering isn't the framework — it's what happens before anything hits the database.

System design

Every part of the system earns its place. The architecture is designed so that quality is structural, not accidental.

Pulse hosting and deployment architecture on Railway — scheduled agent, ingest API, and Postgres database

Hosting architecture — Railway hosts the app, the Postgres database, and triggers the scheduled ingestion routine

Pulse data model and knowledge graph — how articles, references, votes, and blog posts connect

Data model — five tables, each earning its place. sourceUrl uniqueness enforces deduplication at the database level

The tech stack

Next.js 16 React 19 TypeScript Prisma ORM PostgreSQL Railway Claude AI (Anthropic) Zod validation RSS + Sitemap

Key design decisions

The decisions that separate "a page that updates" from something trustworthy enough to build a research habit on top of.

1
African coverage as a first-class column, not a tag
The region field is an enum (africa | international) stored as a proper column — not a tag, not a filter, not a hope. This guarantees African stories appear every day at the data model level, not because the agent happened to find them. General news APIs (Guardian, NewsAPI, Finnhub) have essentially no African tech/business coverage, so the ingestion routine goes directly to TechCabal, Techpoint Africa, Disrupt Africa, IT News Africa, and Rest of World's Africa desk via targeted search — every single run.
2
Deduplication enforced at the database, not just application logic
sourceUrl carries a unique constraint in the Postgres schema. Even if the ingestion routine forgets its own dedup check, the database rejects the duplicate. Application-level dedup runs first; the DB constraint is the backstop. This means a story can never appear twice — the morning's run can fail halfway through and the partial results are still clean.
3
Authenticated ingest API as the only external write path
Everything the scheduled routine produces goes through one endpoint: POST /api/ingest/articles, bearer-token authenticated. Schema validation runs via Zod before anything touches the database — a bad category enum or missing reference array fails loudly. The secret is environment-specific; a leaked dev token can't touch production. This boundary is what makes it safe to run an AI agent as the sole writer with no human in the approval loop.
4
ReferenceLink taxonomy — primary, related, data, background
Every Pulse story ships with its sources categorized: primary (the original reporting), related (context), data (statistics or datasets cited), background (explanatory reading). This isn't decoration — it's what makes Pulse a research tool rather than a headline aggregator. A reader can go straight to the primary source. A future me writing a blog post can see exactly what the AI was looking at.
5
30-day rolling window — not an archive
A cleanup endpoint runs after every ingestion pass and deletes articles older than 30 days. Pulse is deliberately not an archive — it's a window on what's current. This keeps the database small, keeps every visit relevant, and avoids the "old results polluting new searches" problem that plagues scrapers that accumulate forever.
6
Automated migrations on every deploy
The Railway start command is prisma migrate deploy && next start. Every deploy applies any pending migrations before the app boots. migrate deploy is idempotent — it only runs migrations it hasn't recorded as applied, so a deploy with no schema changes is a no-op. No manual SQL step, no drift between migrations directory and production state.

What this project actually is

Pulse looks like a news site. It's really a demonstration of a specific engineering skill: building an AI-driven pipeline that is trustworthy enough to run unsupervised. That means the quality is structural — enforced by schema constraints, by the authenticated ingest boundary, by the region-first research rules — rather than dependent on someone reviewing each output before it goes live.

The hardest part wasn't getting the AI to write a competent summary. Any capable model can do that. The hard part was specifying, precisely enough, what a good story meant — what sources to trust, how to guarantee African coverage, what "original" means versus plagiarism — such that an autonomous process could apply that judgment correctly, every morning, without me watching.

If you're building something in the African market and want to talk about AI pipelines, scheduled agents, or what it takes to make an AI feature production-ready rather than demo-ready, I'd like to hear from you.

Let's build something together

Building in Africa's digital economy? I'd like to hear what you're working on.

THE CONVERSATION CONTINUES

Come for the ideas.
Leave with clarity.

▶ Watch My Work

Tech, business, and the things I learn building both.