DEV Community

Chad Dyar
Chad Dyar

Posted on

Tony had to help me get dressed last Tuesday morning.

Tony had to help me get dressed last Tuesday morning.

I have rheumatoid arthritis. When it flares, it goes for the hands. By the time I made it to my laptop, the content system had already posted to LinkedIn and Mastodon. Nine items published over three days while I was mostly down.

This is the architecture behind that.

The Stack

The pipeline runs on three components: a Supabase marketing_queue table, a local Python publisher process called Clawbot, and a weekly Sunday approval workflow I run in a Cowork session.

The queue table is the central object. Every piece of content lives there as a row with these key columns: platform, title, body, status, week_of, day_of_week, source.

The Status Flow

Items move through these statuses: pending, ready, approved, published.

The publisher only touches items with status = approved or ready_to_publish. It never touches pending, ready, or human_required. This is the key architectural decision. Approved is the gate. Nothing publishes without my explicit sign-off.

The Validation Layer

Before any content goes into the queue as ready, it passes two database functions:

SELECT public.is_publishable_content(body, title) as passes,
public.content_validation_reason(body, title) as reason;

The validation catches: body under 200 characters, metadata prefixes in the body field, brief-format content that was never expanded into finished copy, and a biographical accuracy check that rejects content with specific phrases that would be factually wrong for my situation.

Last week I had 22 items rejected. The failure mode: batch content submitted as planning briefs instead of finished copy. The system caught it. I still have to clean it up manually.

The Sunday Workflow

Sunday evenings I run a content batch process. It generates fresh content for the current week, validates it, and inserts it with status ready. Then I do a manual approval pass: reading each item, improving anything that needs work, and updating to approved. Clawbot clears the approved queue on its schedule throughout the week.

When I cannot do the Sunday review, the prior week's approved queue continues clearing. The gap is visible in the metrics but the output does not completely stop.

What I Would Do Differently

The biggest gap right now: the 22 rejected items represent a failure in the content generation step. The validator caught them correctly. But they represent wasted generation cost and manual cleanup work. I am adding a stricter pre-validation pass to the Sunday generation workflow so rejected items never make it into the queue in the first place.

Second gap: long-form content has no automated path to published. It parks at ready and waits for me to manually post it. That is intentional for quality reasons, but it means long-form has a higher abandonment rate. Working on a simpler handoff that reduces friction without removing human review.

The thing that surprised me most: the system does not know it is impressive. It just runs. Tuesday morning when the arthritis was bad, it published at 8:47 AM the same as any other Tuesday. No acknowledgment, no notice. Just the work.

I find that oddly reassuring.

Top comments (0)