Deep-dive case study
AI can draft. A person still owns the publish button.
Nothing reaches a public account without a person reviewing it and choosing to publish. This dashboard turns AI-generated candidates into a clear, human-owned queue for X and LinkedIn.
It is also built for the uncomfortable moment when a system crashes or times out. A second run cannot send the same thing twice, and an uncertain result tells your team what to verify before they try again.
At a glance
A publishing workflow with a memory.
The dashboard is not the generator. It is the dependable place where a suggested post becomes reviewed, confirmed, and traceable public work.
Destinations
X and LinkedIn
One review queue, with publishing behavior that respects each channel.
Human approval
Required
Nothing reaches a public account until a person reviews the words and chooses publish.
Reliable record
Neon-backed
Every post keeps its draft, review, status, error, and confirmed destination history.
Scheduled intake
Daily sync
A protected routine checks for new source content at 09:00 without blocking the review screen.
The problem
Generated does not mean ready to publish.
A good draft can still lose its review decision in a chat thread or inbox.
A timeout at the send step creates the worst ambiguity: the post may already be public.
Multiple tabs, background checks, and external responses can compete to change the same post.
The approach
Separate AI assistance from public permission.
The dashboard keeps an operational record separate from the generator.
A person edits and explicitly starts a channel-specific publish action.
The public result counts only when the destination confirms it with a real link.
What your team experiences
AI can make the first draft faster. Your team still has a calm, visible process for deciding what represents the business publicly—and for knowing exactly what happened when a channel has a problem.
The lifecycle
Five saved states make the next action clear.
A post moves through a small set of durable states. The labels show whether it needs review, has one send underway, is confirmed, needs recovery, or was deliberately set aside.
pendingReady for a person
New content waits in the active review queue. It is a candidate, not an approval.
postingOne send in progress
The system temporarily gives one publish attempt ownership, so another tab cannot send the same post too.
postedPublic outcome confirmed
The record changes only after the publisher returns the actual destination link.
failedNeeds a careful next step
The draft and review work remain available, together with a message explaining what to check before retrying.
skippedIntentionally set aside
A person can remove an item from the active queue without losing the record of that decision.
The exact saved lifecycle and review ruleshow
The Neon-backed lifecycle is pending, then posting, then posted, with failed and skipped as durable alternate states. The active publishing backlog uses pending; it does not invent an invisible approval record.
reviewed_text is stored separately from the generated draft. It is promoted to the recorded published copy only after the publisher confirms a destination URL; a confirmed posted record is terminal and later synchronization cannot downgrade it.
A reviewer can skip a pending item, preserving that local decision unless a later upstream response confirms the item actually published. The saved ledger includes status, created and updated times, sent and posted times, error text, and live destination URLs.
How it works
From draft to confirmed public post.
Every step spells out who owns the work, what gets saved, and what the system does when a channel does not respond cleanly.
Bring new drafts into a working queue
When
A daily schedule, a refresh action, or a background check finds source content.
What happens
The dashboard shows its saved queue first, then looks for new material in the background.
Your result
Reviewers can keep working even when the content source is slow.
If something goes wrong
A source problem cannot erase or hide posts already saved for review.
Match incoming content to its existing record
When
A source post arrives from the shared content service.
What happens
The system matches the source item to one durable record and refreshes only what is safe to refresh.
Your result
One post retains its draft, edits, status, links, and useful context across repeated checks.
If something goes wrong
A partial source response cannot wipe details that the dashboard already knows.
Let a person make the final edit
When
A reviewer opens an item that is ready or needs another attempt.
What happens
The reviewer can change the proposed copy, check it for the selected channel, and save that review work before any public action starts.
Your result
The final words are human-owned and survive a refresh or later retry.
If something goes wrong
An old browser view cannot save over a post that has already moved into an active send.
Claim the send before contacting a public account
When
A reviewer presses the publish control.
What happens
The system checks access and target, then records that one send owns this post before making an outside request.
Your result
A double-click, second browser, or overlapping sync cannot create a second send.
If something goes wrong
A competing publish attempt gets a clear conflict instead of releasing duplicate content.
Record success only when there is proof
When
The channel publisher replies with a successful destination URL.
What happens
The dashboard records the URL and time, then promotes the reviewed words into the recorded published copy.
Your result
A published status means a real public destination was confirmed, not merely that someone clicked a button.
If something goes wrong
A timeout or server problem is preserved as an uncertain failure and asks the reviewer to verify the account before retrying.
Keep each destination understandable
When
A channel callback or companion destination reports an outcome.
What happens
The system checks the response before recording it and keeps distinct destinations in their own fields.
Your result
A team can see what happened on X and LinkedIn without confusing a company page, article, or thread.
If something goes wrong
Unexpected callback data has no shortcut into a confirmed public state.
The important promise
The system never treats a button click as proof of publication. It waits for the public destination to confirm success, and it refuses to let a crash or second run silently create the same public post twice.
How the dashboard prevents a double-sendshow
The publish route confirms authorization, validates the selected target, and atomically changes only pending or failed rows to posting before the outbound request begins. This atomic claim prevents another browser or concurrent sync from releasing the same draft.
The exact reviewed copy is passed to the corresponding channel publisher. Before a review save or publish is accepted, the dashboard validates non-empty text and the selected channel character limit. A second publish request receives a conflict. Saving review text accepts only pending or failed rows, and a stale client cannot save into a row that has moved out of a reviewable state.
The record behind the queue
Why a durable ledger changes the operating model.
A content generator is good at creating candidates. It is not automatically a trustworthy record for editorial decisions, public confirmation, or recovery from a network problem.
One home for each post
The same item remains traceable across intake, review, a failed attempt, recovery, and later reporting.
Status is not guesswork
The dashboard shows what is waiting, sending, confirmed, failed, or intentionally skipped from saved records—not from a temporary browser view.
Your reviewed words have a safe lane
The review version is protected until a real publish confirmation arrives, so uncertainty cannot overwrite the original record.
Changed content gets fresh guidance
If draft content changes, the system knows that earlier publishing advice may no longer fit.
One package can have several outcomes
A company-page post, an article, and a companion thread can each keep their own evidence.
Operational follow-through can repeat safely
The system records what was already written back to connected operations, avoiding repeated side effects during a retry.
How synchronization preserves the work already doneshow
The posts table uses post_id as its primary key. Sync uses post-ID upserts plus a SHA-256 content hash built from the channel and draft payload. The hash invalidates cached publishing-insight fields only when draft text, thread, or article content changes, so advice does not pretend to describe a different draft.
The update preserves terminal posted records, posting work, saved review work, in-flight research, and non-null enrichment fields when incoming data omits article, media, organization, or publishing information. Writes are batched to the database pool size, and downstream bookkeeping markers and attempt counts make write-back idempotent.
How the pieces fit together
Separate responsibilities make the process easier to trust.
Review experience
Queue views, channel tabs, category groups, and an edit workspace
People see reviewable work and its status before they are asked to take a public action.
Durable record
Neon Postgres, typed records, post matching, and status indexes
The publishing history remains available when a browser, generator, or remote channel has a temporary problem.
Content intake
Shared skills API, protected sync route, content fingerprinting, and a daily schedule
Generation stays separate while the dashboard owns review status and publishing evidence.
Destination controls
Channel-aware publishing routes, X and LinkedIn flows, and response checks
Each network gets the handling it needs without turning every post into an ad hoc manual process.
The implementation stack behind the review experienceshow
The review experience is built with Next.js and React, channel tabs, category groups, and a draft-rewrite workspace. The durable record uses Neon Postgres, a typed ledger model, post-ID upserts, and status indexes.
Content intake uses the shared skills API, a protected sync route, content hashing, and a Vercel Cron entry that calls the sync route daily at 09:00. X and LinkedIn use channel-aware publishing routes with validated callbacks.
Safeguards
The hard parts are handled before the public post.
A publish button is the last step, not the first. The software protects reviewed work, prevents duplicated intent, and makes uncertain remote outcomes visible.
Only authorized actions can change a post
Intake, edit, publish, skip, and external confirmation routes check permission before changing the saved record.
Old screens cannot win
An action is accepted only when the post is in the right state, preventing an outdated tab from undoing in-progress work.
Confirmed posts stay confirmed
A late source update cannot quietly put a confirmed public post back into the active queue.
Uncertainty is shown, not hidden
If a public channel times out or returns a server error, the reviewer keeps the draft and gets a verify-before-retry message.
Public destinations are checked
The system validates the configured target and key details from external responses before it calls a post successful.
Sync does not erase ongoing work
A background refresh preserves confirmed, in-progress, reviewed, and enriched information when the incoming source has less detail.
Why this is safer
If the channel does not answer cleanly, the dashboard does not guess. It keeps the exact review work, marks the attempt as recoverable, and tells the person to verify the destination before attempting another send.
Timeouts, callbacks, and channel-specific outcomesshow
The publish route gives the channel publisher room to respond, but a timeout or server-side outcome becomes a recoverable failed record carrying a verify-before-retry message. The reviewed text remains available; the system never silently assumes the post did not publish.
Callback handling validates the post, channel, destination URL, and timestamp before accepting outside evidence. LinkedIn organization-page publishing is tracked separately from the profile result, while native articles keep their own URL alongside companion-thread outcomes. X single-post mode and LinkedIn publishing each use channel-aware handling. Unexpected callback data has no free path into a published state.
What it replaces
A review process that remembers, recovers, and explains.
Before
AI-generated drafts are scattered across email, chat, and temporary service responses.
After
One durable queue keeps the draft, human edit, status, error, timestamp, and confirmed destination together.
Before
A team can approve copy in theory but still lose the exact version that was intended to publish.
After
The reviewed version is stored separately and becomes the recorded published copy only after a confirmed public result.
Before
A network timeout leaves people guessing whether they should press publish again.
After
The record retains the review work and tells the reviewer to check the account before a safe retry.
Before
Repeated refreshes or extra browser tabs can overwrite decisions or send duplicate content.
After
Protected matching, in-progress claims, and confirmed-state protection make repeat runs safe by design.
What this means for your business
AI leverage without giving away editorial control.
- Founder-led content programs that want AI drafting but retain a human voice and explicit final decision.
- Marketing teams posting to several social channels that need one reliable review queue rather than ad hoc handoffs.
- Reputation-sensitive or executive communications where publication proof and a clear history matter.
- Operations teams that need a calm recovery path after timeouts, stale tabs, source failures, or delayed external responses.
Plain-language glossary
Every technical term used on this page, explained without jargon.
- Atomic claim
- One all-or-nothing update that gives a single publish attempt ownership.
- Callback
- A message from another service confirming a result or sending an update.
- Content hash
- A fingerprint that changes when the underlying draft content changes.
- Durable state
- Saved workflow information that remains available after a refresh or crash.
- Neon Postgres
- A hosted SQL database used here as the long-lived publishing record.
- Post-ID upsert
- A save that creates or updates the same record using its source post identifier.
- reviewed_text
- The human-edited version kept apart from the original generated draft.
- SHA-256
- A standard method for producing a content fingerprint from text.
- Terminal state
- A protected final status that a routine update should not undo.
- Vercel Cron
- A scheduled trigger that starts a protected backend route at a planned time.
Need an AI-enabled workflow that stays human-owned?
Build a content approval system your team can trust.
Turn generation into a clear operating process with durable records, thoughtful recovery, and an explicit human decision before anything goes public.