Case Study · Solo Build · QA & Security · 2026

Publizo, hardened.
The problems I found
and fixed.

I am the founder, product owner, QA lead and release manager on Publizo. I do not write the code myself — I direct AI as the implementation layer, decide what correct means, and refuse to ship when it is not there yet. This is the audit trail.

Role
Founder, Product, QA, Release
What it does
Writes, fact-checks and publishes SEO articles into a customer's CMS
Live on
Online Magazine News, Luna Zodiac, Laconic ML
Status
Full Case Study The Problems I Found & Fixed

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

Billing, auth, 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.

37
Backend functions
38
DB migrations
236
Source files
36.4k
Lines of code
28
Public pages
3
Live properties

Integrations I own end to end

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

What runs without me

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

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

That is the honest version of the claim. The proof is not a headcount I avoided, it is the guards, the audit trails and the fixes in 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 CTA and every show-more toggle, and left a single input a visitor can use before creating an account.

Publizo selling page

Fewer clicks, on purpose

Example chips, duplicate CTAs and collapsible sections all tested as friction. The header button turns into a quiet link once the sticky bar appears, so there is never more than one primary action visible.

Mobile is not an afterthought

Every marketing page, tool page and dashboard flow got a full responsive pass after I found content cut off across the app on a phone. Same page, 390 pixels wide — nothing clipped, nothing scrolling sideways.

The dashboard 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, with navigation between the user and the product. I rebuilt it so the first screen after login is the composer itself: one question, one button.

Publizo composer dashboard

What I removed

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

What I kept visible

  • Which site the article publishes to, at all times
  • Remaining articles on the plan
  • A single primary button that says what will happen

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

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

Connect a site
Connect your blog — platform first, credentials second, read-only until publishing is allowed
Composer on mobile
The composer on a phone — touch targets sized for thumbs
Conversion fixes that came out of real events, not opinion
Users signed up and never generated
Funnel instrumentation identified the exact drop step, then a demo article flow delivered value before setup
Paying intent lost during account creation
Pending checkout persisted across signup, so Get Started leads straight to payment
Too much text, the same promise repeated three times
Stated once, sections cut, one clear action per screen

Every article carries its own evidence.

Quality score, target keyword, category, language, word count, whether an image was attached and publish status all sit on the article row. If something landed as a draft, the user is told why in the app rather than left guessing.

My articles

Tiered risk gating

News, finance, politics, health and sport always route to draft for human approval. Evergreen and product content can auto-publish. The policy lives in code, not in a wiki, so it holds when I am 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 degrades the whole site, so if a topic cannot support the depth, the slot is skipped.

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

Fifty-three articles on this account, forty-two live, eleven held for review. That is the test bed: if a bug damages a site, it damages mine before it reaches a customer.

Editorial overview

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

I root-caused it to a plan-tier guard misfiring on my own unlimited account, plus a mismatched cron secret returning 401. The fix was not only the code, it was a cron health panel, so silence itself is now a visible failure.

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

Production as the test bed, on my own money

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

Real-user forensics instead of guessing

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

Adversarial content review

I read output as a hostile editor. That is how I caught the worst class of bug in this product: an article that read perfectly and was invented. Then I turned my checklist into code.

Regression discipline

Every incident produced a permanent artifact: a guard, a log line, a status check, an audit row or a written rule, so the same mistake could not come back later.

Cross-device sweeps

Full mobile and desktop passes over marketing, pricing, tools and dashboard, looking for dead ends rather than only testing 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 system status computed from real failure rates.

The hardest bug here was not a crash. It was an article that read perfectly and was factually invented.

No compiler catches that. I caught it by reviewing output adversarially, then encoded my review criteria as automated guards, so the standard held without me being awake.

Content correctness and reliability.

Content Correctness
Models invented companies, products, rulings and statistics that read as real
Fabrication guard plus three-pass verification, and a hard block on fabricated citations and invented first-hand experience
Real facts placed in false context: right name, wrong outcome
Outcome-direction verification on every cited result or ruling
Output detectable as AI writing
Human-voice constraints, burstiness and archetype gates, controlled imperfection, per-niche story beats
Duplicate topics republished to the same site
Reads the connected site's existing posts, pre-flight duplicate check, credit refunded on rejection
Reliability
Generation failing for some accounts
Multi-provider fallback chain, retry logic, structured failure taxonomy, incident banner that expires by itself
Publishing failing at the CMS with no explanation
Pre-flight WordPress health check, publish audit trail, and clear in-app messaging when an article lands as a draft and why
Stock image APIs timing out or returning irrelevant photos
Retry with backoff plus relevance-scored selection, graceful degradation instead of a broken post
Duplicate charges or double generations on retry
Idempotency keys on generation and on webhooks

Security findings, closed.

Security
Unsigned JWT fallback in cron auth
Removed, replaced with a verified shared secret
Public database functions callable with an arbitrary user id
Rewritten to scope to the authenticated user, unused ones dropped
Unbounded AI spend, XSS on rendered article HTML, SSRF on user-supplied URLs
Per-user rate limiting and server-side quota enforcement, HTML sanitisation, URL validation and allowlisting
Privilege escalation risk
Roles in a dedicated table behind a security-definer check function, never on the profile record
Vulnerable dependencies
Dependency scanning in the loop, upgrades applied

In my own words.

One line

I designed, tested and shipped a production multi-tenant AI SaaS on my own by directing AI engineering, and I owned QA, security review and release decisions myself.

CV bullets
  • Built and operate Publizo, a multi-tenant AI publishing SaaS: 37 backend services, 38 database migrations, roughly 36,000 lines of production code, live billing and automated daily publishing on three production properties.
  • Directed AI engineering as a non-coding operator across content generation, payments, product, integrations, platform security and growth.
  • Owned QA end to end: production-first testing on my own properties, funnel analysis on real user events, adversarial content review, tiered risk gating and regression prevention built as automated guards.
  • Found and fixed a content-fabrication defect class, shipping a fabrication guard plus three-pass verification that protects customer sites from search spam-policy exposure.
  • Resolved security findings including unsigned-JWT cron auth, unscoped database functions, XSS, SSRF and unbounded AI spend.
  • Rebuilt onboarding and the dashboard around measured drop-off, cutting the path to a first published article to a single screen.
The answer to "but you don't code"

My job is the part that does not get automated: deciding what to build, defining what correct means, and refusing to ship when it is not there. The hardest bug in this product was not a crash, it was an article that read perfectly and was invented. No compiler catches that. I caught it by reviewing output adversarially, then turned my review criteria into automated guards, so the standard held without me. That is engineering judgement and QA ownership, applied through AI as the implementation layer.

Try It

Publizo is live. Every screenshot here is the real application.

Five free articles every month. No credit card. Full editorial quality.