Skip to content
NewClientOS is live — the self-hosted client portal for agencies.
work/ucontents

Product · Social media publishing

uContents

Write, schedule, publish and measure content across nine social networks from one place.

  • SaaS · Multi-tenant platform
  • 2026 · v1 then a full v2 rewrite
uContents — Product · Social media publishing

About uContents

Introduction

Creators and agencies make plenty of content. What eats their week is everything after: writing a caption for each platform, picking the page, choosing the date, re-uploading the same file nine times — then doing it again tomorrow. uContents turns that into a publishing system. Upload once, set the rules, and it keeps publishing across Facebook, Instagram, Threads, YouTube, TikTok, X, LinkedIn, Pinterest and Bluesky, then reads the analytics back. The version live today is a ground-up rewrite of an earlier Laravel product, rebuilt as a multi-tenant platform with workers, queues and an AI layer that looks at the media before it writes a word.

Details

Project
uContents
Timeframe
2026 · v1 then a full v2 rewrite
Type
SaaS · Multi-tenant platform
Stack
  • Next.js
  • NestJS
  • PostgreSQL
  • Redis
  • BullMQ
  • Drizzle
  • Stripe
  • Docker
Problem
Posting the same content to many networks is manual, repetitive work: separate apps, repeated uploads, captions written without looking at the media, and analytics scattered across dashboards.
What we built
A multi-network publishing platform with bulk campaigns from a folder or CSV, recurring schedules and automatic reposts, AI captions drafted from sampled video frames, a visual builder for comment auto-replies, and brand workspaces with roles and 2FA.
Outcome
Live at ucontents.com. Version two replaced the original Laravel application with a NestJS and Next.js platform built for multiple brands and background publishing at scale.
networks published to, with analytics read back from each
9
background queues, split across five groups of workers
16
tools behind the AI agent and the MCP server
36
AI chat providers, with failover between them
12

Inside the customer app.

The dashboard a brand works in every day, rebuilt here in code from its own screens. It opens on a workflow; pick another screen, or click the sidebar.

uContents — Workflows

Comments answered on a canvas

A visual builder of triggers, conditions, branches, actions and delays. A workflow starts on a new Facebook or Instagram comment, or on a schedule.

  • Conditions on sentiment, intent, language and more
  • AI reply, like, hide, notify
  • Generate and publish posts
  • An approvals panel for anything risky

Recreated from the product’s interface. Labels and options are the app’s own; the brand, posts and numbers are samples.

The parts, up close.

Pieces of the app that carry the most weight, at full size.

What went into it.

  1. 01

    Publishing engine

    Nine network integrations, scheduled and bulk publishing through BullMQ workers, with analytics read back from each platform.

  2. 02

    AI layer

    Captions, titles and hashtags drafted from frames sampled across each video, paid for in credits, with automatic failover between AI providers.

  3. 03

    Workflows & workspaces

    A visual workflow builder that answers comments, multi-brand workspaces with roles and 2FA, plus an MCP server for Claude.

How it is built.

The running parts

API and realtime
One NestJS codebase split into libraries, running as an API and a separate WebSocket gateway.
Workers and scheduler
BullMQ workers in five groups — core, media, AI, publishing and engagement — each its own service, plus a scheduler that elects a single leader.
Three web apps
The customer app, the marketing site and the admin, all on Next.js.
Data
PostgreSQL through Drizzle with row-level security, one Redis for queues and one for cache, and S3-compatible storage for media.
Deployment
Docker Compose on Dokploy. A migration step runs once and every other service waits for it.

The hard parts

  1. 01

    Tenant isolation lives in the database

    Every query runs inside a transaction that names the brand, and PostgreSQL row-level security does the filtering. With no brand in context the call fails instead of returning everything, and a check script fails when a brand table has no policy.

  2. 02

    A post is never published twice

    Due posts are claimed by a single atomic status change, so two workers cannot pick up the same one. A reaper resets anything stuck in publishing for over fifteen minutes, and every campaign slot has a stable key.

  3. 03

    Retries that respect the network

    Publishing gets four attempts, backing off for as long as the network asks and a little more. Failures are classified, and only account or channel failures count towards switching a channel off after three strikes.

  4. 04

    Tokens renewed before they expire

    A scan every ten minutes renews any access token that is past half of its remaining life, so a scheduled post does not fail on a login that expired overnight.

  5. 05

    One brand cannot starve the rest

    Campaign preparation shares a queue, so each brand holds a limited number of leases, taken atomically in Redis. A lease expires by itself if the worker holding it dies.

Start here

Have a problem worth solving?

Tell us what is slow, manual or missing. You will hear back within one working day — then get a written scope and a fixed quote, or an honest no.

brief.md
  1. # New project brief
  2. ## What is slow, manual or missing?
  3. - [x] Written scope
  4. - [x] Fixed quote
  5. - [x] Or an honest no
Reply within one working daySend brief
Message Us