Every problem I found in Publizo, and how I fixed it.

I'm Publizo's founder, product owner, QA lead and release manager. I don't write the code myself: I direct AI as the implementation layer, define what correct means, and hold a release until it gets there. This page is the audit trail.

Role
Founder, product, QA and release
What it does
Writes, fact-checks and publishes SEO articles into a customer's CMS
Runs daily on
Online Magazine News, Luna Zodiac and Laconic ML
Status
Live at publizo.io

What I built

A multi-tenant SaaS, not a landing page with an API call behind it.

Billing, authentication, role separation, rate limiting, audit trails, automated content pipelines and its own SEO surface. Every number below comes from the repository and the live backend.

37backend functions
38database migrations
236source files
36.4klines of code
28public pages
3live properties

Integrations I own end to end

  • Polar as merchant of record for payments
  • Several AI providers behind one fallback chain
  • WordPress REST publishing and multi-CMS output
  • Pexels and Pixabay for editorial images
  • Transactional email, Amazon Associates, Google OAuth and an MCP server

What runs without me

  • Scheduled publishing per tenant on pg_cron
  • Duplicate topic checks before a credit is spent
  • Niche detection for new sites with no posts yet
  • Cron and job health checks, so silence is visible
  • A dead-letter queue for failed email

I built this alone with AI tooling instead of a team, in months rather than the year a small team would need.

The proof isn't the headcount I avoided. It's the guards, audit trails and fixes on the rest of this page.

The selling page

One topic in, a published post out.

The landing page carries the whole promise in one screen and one action. I cut it from seventeen sections to twelve, removed every secondary call to action and every show-more toggle, and left a single input visitors can use before creating an account.

Fewer clicks, on purpose

Example chips, duplicate calls to action and collapsible sections all showed up as friction. The header button becomes a quiet link once the sticky bar appears, so only one primary action is ever visible.

Mobile is not an afterthought

Every marketing page, tool and dashboard flow got a full responsive pass after I found content cut off on phones. At 390px wide, nothing is clipped and nothing scrolls sideways.

The dashboard

It was a settings maze. Now you land inside the tool.

Funnel data showed people signing up and never generating anything. The old dashboard opened on an overview screen that put navigation between the user and the product. Now the first screen after login is the composer: one question, one button.

What I removed

  • The overview screen as the landing page
  • Setup before first value: a free sample runs with no site connected
  • Advanced options for new users, now behind a Simple and Pro switch

What stays visible

  • Which site the article will publish to
  • How many articles are left on the plan
  • One primary button that says what will happen

Onboarding

Connect a site in about two minutes, or skip it entirely.

New accounts go straight to site connection with a progress indicator, not to a settings page. WordPress publishes directly. Every other platform still gets a finished, ready-to-paste article, so nobody is blocked by their CMS.

Conversion fixes that came from real events, not opinion

ProblemFix
People signed up and never generated an articleFunnel instrumentation found the exact drop-off step, and a demo article now delivers value before any setup
Paying intent was lost during account creationThe chosen plan carries through sign-up, so Get started leads straight to checkout
The same promise was repeated three timesSaid once, sections cut, one clear action per screen

Quality in the product

Every article carries its own evidence.

Quality score, target keyword, category, language, word count, image status and publish status all sit on the article row. If an article lands as a draft, the app says why instead of leaving people guessing.

Tiered risk gating

News, finance, politics, health and sport always go to draft for human approval. Evergreen and product content can publish automatically. The policy lives in code, not in a wiki, so it holds when I'm not watching.

Length is a guide, not a quota

Word count has a safety floor and no padding target. Stretching a thin topic to hit a number hurts the whole site, so if a topic can't support the depth, the slot is skipped.

Operating it

I run the same pipeline on my own sites, every day.

Fifty-three articles on this account: forty-two live, eleven held for review. My own sites are the test bed, so if a bug can damage a site, it damages mine before it reaches a customer.

Scheduled publishing went quiet on two of my own sites for weeks, and nothing told me.

The cause was a plan-tier guard misfiring on my own unlimited account, plus a mismatched cron secret returning 401. The fix wasn't only the code. It was a cron health panel, so silence itself now shows up as a failure.

How I ran QA

I was the QA function, not the person hoping it worked.

Production as the test bed

Every feature ran on my own live sites, with my own money, before a customer saw it.

Real behaviour, not guesses

I instrumented the funnel: who signed up, who generated, who connected a site, and who left at which step. Several redesigns came straight from that data.

Adversarial content review

I read output like a hostile editor. That is how I caught the worst class of bug in this product, then turned my checklist into code.

Regression discipline

Every incident left something permanent behind: a guard, a log line, a status check, an audit row or a written rule.

Cross-device sweeps

Full mobile and desktop passes over marketing, pricing, tools and the dashboard, looking for dead ends, not just the happy path.

Observability as a test signal

Structured logging, a failure taxonomy, publish audit trails, a dead-letter view for email and a live status page computed from real failure rates.

The hardest bug wasn't a crash. It was an article that read perfectly and was invented.

No compiler catches that. I caught it by reviewing output adversarially, then encoded the review as automated guards, so the standard holds while I sleep.

Problems and fixes

Content, reliability and security findings, closed.

Content correctness

ProblemFix
Models invented companies, products, rulings and statistics that read as realA fabrication guard with three-pass verification, and a hard block on fabricated citations and invented first-hand experience
Real facts in false context: the right name with the wrong outcomeOutcome-direction checks on every cited result or ruling
Output that was detectable as AI writingHuman-voice constraints, varied sentence rhythm, controlled imperfection and story beats per niche
Duplicate topics republished to the same siteReads the site's existing posts, checks for duplicates before generating and refunds the credit on rejection

Reliability

ProblemFix
Generation failing for some accountsA multi-provider fallback chain, retry logic, a structured failure taxonomy and an incident banner that expires on its own
Publishing failing at the CMS with no explanationA WordPress health check before publishing, a publish audit trail and a clear in-app message when an article lands as a draft
Stock image APIs timing out or returning irrelevant photosRetries with backoff and relevance-scored selection, degrading gracefully instead of breaking the post
Duplicate charges or double generations on retryIdempotency keys on generation and on webhooks

Security

ProblemFix
An unsigned JWT fallback in cron authenticationRemoved and replaced with a verified shared secret
Public database functions callable with any user idRewritten to scope to the signed-in user, and unused ones dropped
Unbounded AI spend, XSS in rendered article HTML and SSRF on user-supplied URLsPer-user rate limits with server-side quotas, HTML sanitisation, and URL validation with an allowlist
Privilege escalation riskRoles moved to a dedicated table behind a security-definer check, never on the profile record
Vulnerable dependenciesDependency scanning in the loop, with upgrades applied
NextPerspecto: designing and building a 3D mockup tool