AI content pipeline with human approval
Scheduled research and drafting with AI, where nothing is published until a person approves it. One Next.js application runs the public site, a private CMS, a Telegram review bot and the scheduled jobs.
- Type
- Automated content platform
- Role
- Software engineer, designer and builder of the full system
- Stack
- Next.js 15, TypeScript, Supabase (Postgres, Auth, Storage), Google Gemini (Flash model, configurable), Zod, Telegram Bot API, Vercel and Vercel Cron
Context
The problem: AI drafts need a human check
Writing useful articles takes research and drafting time. Publishing AI text without review is a risk to quality and reputation.
The system had to automate the routine steps, such as finding topics, avoiding repeats and drafting, and leave the final decision to a person, reachable from both a CMS and a phone.
Why review had to stay fast
Most AI content tools either publish without control or save little time.
The useful middle is automation that does the first pass reliably and makes review fast.
What we built
Inside the AI content pipeline
One Next.js application, two products
The public site and blog, and a private CMS on its own subdomain, separated by host-based routing in middleware. The CMS is never indexed.
Topic research
A weekly scheduled job asks Gemini for candidate topics as structured JSON. Each candidate is validated with Zod, then de-duplicated by exact slug match and by Jaccard similarity of significant words (threshold 0.6), against existing topics, every past article and the rest of the same batch.
A topic queue
Ranked by priority (1 to 10) or a scheduled date, with a cap so the backlog cannot grow without limit.
Drafting
On Monday, Wednesday and Friday, the highest-priority or due topic becomes a draft saved as pending_review. Nothing publishes automatically.
Review from Telegram or the CMS
Every draft arrives in Telegram with Approve, Edit, Regenerate and Reject buttons. The same actions exist in the CMS.
One shared core
The CMS, the Telegram bot and the scheduled jobs all call the same functions (runTopicResearch, generateDraft, publishArticleCore, revalidateArticlePages), so the routes cannot drift apart.
Publishing and cache
Publishing invalidates both Next.js cache layers (the path and the articles tag), so the article, its category and the sitemap update together.
Security
Google OAuth for one authorised admin, server-side authorisation on every action, Postgres row-level security with no public policies (service-role access only), secret-verified Telegram webhooks, bearer-secret scheduled jobs, and constant-time secret comparison.
Storage
Cover images in Supabase Storage, with a public read, a 5 MB limit and PNG, JPEG and WebP only.
Engineering
Key decisions
Structured output, not text parsing.
Gemini returns JSON that matches a schema, and Zod rejects anything that does not, so a malformed response never reaches the database.
Failure-safe state.
A topic is marked as used only after its article exists. If generation fails, the topic stays available for the next run and an error message goes to Telegram.
A race closed by design.
Regenerate discards the old draft before creating the new one, and publishing refuses discarded drafts, so a stale Approve tap can never publish a draft that was replaced.
Re-check before acting.
The CMS button and the Telegram picker can show an out-of-date topic status, so generation re-checks eligibility at the moment it runs.
Results
Results of the AI content pipeline
- Topic research and first drafts run on a schedule without anyone starting them.
- Repeated or near-duplicate topics are filtered out before they reach the queue.
- Nothing goes live without a person approving it, and approval takes one tap.
- A failed generation never loses work or needs manual cleanup.
- The whole system runs on low-cost managed services.
Architecture
The full system
For engineering readers. Everything in the drawing is described in the text above.
One Next.js codebase on Vercel serves the public site and the private CMS. The strip at the bottom is the content lifecycle: AI does the work up to pending_review, and a person decides from there.
Stack
Technology
- Next.js 15
- TypeScript
- Supabase (Postgres, Auth, Storage)
- Google Gemini (Flash model, configurable)
- Zod
- Telegram Bot API
- Vercel and Vercel Cron
For your business
Similar problems Lubili can solve
Any repetitive drafting, classification or data preparation where AI does the first pass and a person approves: product descriptions, support replies, document and invoice intake, lead qualification.
Designed, built and run by Lubili.
Want AI to do the first pass, with your team still in control?
Book a free consultation, and we will look at where a first pass by AI would save time and where a person should stay in charge.
Free. No obligation. You get a one-page written summary.