One content engine. Every product.
Blog and news built once in aumik-agents, reused by every brand through a shared feed widget and a reading portal. Each product gets a content channel to bring in customers — owned posts for SEO & proof, a curated news feed to look current — without per-product CMS code.
See the reader side → Open the editorThe modules
<ContentFeed/> widget..rss out.Same module, every product
| Product | Channel | What it publishes |
|---|---|---|
| aumik-dev | Blog + case studies | Modernization guides, client results |
| aumik-dooh | News ("Pulse") | DOOH / programmatic-OOH industry news |
| aumik-astro | Insight blog | Rituals, Vedic explainers, horoscopes |
| aumik-cleaning | Tips blog | Home-care how-tos & checklists |
| aumik-hospitality | Travel guides | Destination & stays guides |
Switch the product context (top-right) to see the same screens re-skinned & re-themed per brand.
Where it lives
| Layer | Home |
|---|---|
| Engine (posts · ingest · drafts) | aumik-agents · Mastra + Postgres |
| Embeddable UI | @aumik/widgets · <ContentFeed/> |
| Reading shell | @aumik/portal · My reading |
| News ingestion | Mastra workflow (n8n fallback) |
| Newsletter | Novu (infra#19) |
Supersedes per-product news sites. See the content pipeline →
Content pipeline
Two lanes feed one store: owned posts (AI-assisted) and curated news (Mastra-ingested). Mastra orchestrates; n8n is a fallback adapter.
How content gets made
Why Mastra (n8n fallback)
The LLM steps — drafting, dedupe, summarise, classify — are Mastra agents/workflows (TypeScript, inaumik-agents). Where a connector or trigger is awkward in Mastra (a niche scrape, a scheduler quirk), n8n fetches and POSTs the payload back to the Mastra ingest endpoint. One pipeline of record; n8n is an adapter, not a parallel system.
The shape
post = {
brand: "dev"|"dooh"|"astro"|...,
channel: "blog"|"news",
title, dek, body, keyPoints[],
category, audience,
sourceUrl?, sourceName?, // news only
seo:{slug, title, description},
status: "draft"|"scheduled"|"published",
publishAt
}
Editorial desk
aumik-dev · editorial desk
Drafts
Scheduled
Published (30d)
Views (30d)
Needs attention
📰5 news items in the queue awaiting reviewreview ✍"Migrating off WordPress" draft — needs an edit passdraftRecent
Compose
Editorial · AI-assisted draft → human edit → publish (the owned-content lane)
Brief → draft
Maple Street Dental was running WordPress 4.x with seven outdated plugins and a 6-second load time. Here's what we changed — and the result.
[ generated body continues — speed, mobile-first, online booking, the +40% number … ]
News queue
Editorial · items Mastra ingested & classified — approve, edit, or discard (the news lane)
source: AdExchanger · classified → aumik-dooh · 96% relevantEditApprove✕
source: Hacker News · classified → aumik-dev · 88% relevantEditApprove✕
source: MediaPost · classified → aumik-dooh · 91% relevantEditApprove✕
Each item is summarised with source attribution and tagged to the product it's relevant to. Nothing publishes without an approve here.
Sources & schedule
Editorial · what the news lane ingests, how often, and which Mastra tool handles it
| Source | Type | Cadence | Mastra tool |
|---|---|---|---|
| Industry RSS (AdExchanger, Digiday, Smashing Mag…) | RSS | every 30 min | fetchFeed |
| News APIs (NewsAPI / GDELT, per-brand keywords) | API | hourly | newsApi |
| Press releases (PRNewswire / Business Wire) | RSS / scrape | hourly | scrape (n8n fallback) |
| Social (X lists, LinkedIn voices) | API | every 2h | socialFetch (n8n fallback) |
aumik-dev — guides & case studies
aumik-dev · modernization guides & client case studies
Get the guide digest
One email a week for business owners. No spam.
Comments · 2
Join the conversation
My reading
aumik-dev · signed in as Maple Street Dental
Saved
Guide · saved 1d agoRead
Subscriptions
My comments
Same “My reading” shell (@aumik/portal) for every product — only the labels change with the product context.
Join to read & comment
aumik-dev · modernization guides & client case studies
— or —
Signing up subscribes you to the digest and unlocks comments. For business owners, it's also the front door to the product itself.
Embed the feed
Any product drops in one widget — it talks to the shared content engine
One widget, configured per brand
<AumikWidgetProvider
agentsBaseUrl="https://agents.aumik.co"
brand="dev">
<ContentFeed channel="blog" /> {/* or "news" / "all" */}
</AumikWidgetProvider>
Lives in @aumik/widgets. Same component renders the feed, article pages, comment threads and the subscribe box you saw on the reader side.
Where it's used
API contract
What the engine exposes · multi-tenant by {brand}
Content endpoints (aumik-agents)
GET /api/content/{brand}/posts?channel&category&page
GET /api/content/{brand}/posts/{slug}
POST /api/content/{brand}/posts # create draft (editor)
POST /api/content/{brand}/ingest # Mastra/n8n news push
GET /api/content/{brand}/queue # pending news drafts
POST /api/content/{brand}/posts/{id}/comments
POST /api/content/{brand}/subscribe
GET /api/content/{brand}/feed.rss # syndication out
Data model
posts brand, channel, slug, title, body, category,
status, publish_at, source_url?, source_name?
drafts brand, payload, origin: "ai"|"ingest", relevance
sources brand-keywords, type, cadence, tool
comments post_id, author, body, created_at
subscriptions brand, email, channel_prefs (Novu)
Same engine, multi-tenant by brand; the news lane writes drafts with a relevance score, the editor promotes them to posts.