Zodiac Tech CRM Docs

QA Reviewer

The launch gate of the agency panel — run the 12-point QA checklist, pass or fail campaign drafts with a real fix note, and verify campaigns actually go live.

ad-specialist Medium ⏱ 12 min Updated 2026-10-05

QA Reviewer

You are the gate between a built campaign and real money being spent. Nothing reaches Meta without your Pass QA — you are the only agency role that holds meta.campaign.launch, and the platform enforces the gate outside the UI too. Your job is not to click through fastest; it is to be the last honest check.

Who this is for

Zodiac Tech agency staff with the qa_reviewer role, signing in at /agency/login. A super admin grants it at /super-admin/meta-ads/agency-team via the Enable launch access toggle — that toggle adds or removes only the qa_reviewer role.

Prerequisites: your agency account exists and campaigns are reaching the QA queue.

Your permissions in plain language

From AgencyRolesSeeder::ROLE_PERMISSIONS['qa_reviewer']:

Granted Meaning
meta.view See the agency panel and open client records.
meta.campaign.launch The QA Queue and everything on it — Start QA, Checklist, Pass QA, Fail QA, Verify Launch.

Not granted, deliberately: meta.campaign.create/edit/pause (building campaigns is the Ads Specialist), meta.creative.manage, meta.setup, meta.connect, meta.support.manage, meta.client.manage, meta.performance.view.

The QA Queue workflow

Open Meta Ads → QA Queue (/agency/meta-ads/qa-queue). The nav badge counts drafts currently In QA. The table shows Client, Campaign, Draft status, Checklist progress (done / 12), QA state (Not started, In QA, Passed, Failed), Submitted, Reviewer and Launch Check; filter by QA state and Draft status.

1. Start QA

On a draft that has not been reviewed yet (Start QA), the system records the submission time and moves QA to In QA. That is your claim on the review — do it when you are actually about to look.

2. Walk the 12-point checklist

Open Checklist on the In-QA row. The 12 items are:

Item How it is judged
Campaign Name, Objective, Budget, Location, Audience, Creative, Copy Derived from the draft's own data — these must be complete before QA can pass at all.
Placements, Lead Form, Tracking, Destination, Correct Creative Selected Validated by you against what the campaign actually needs.

3. Pass or fail — no third option

  • Pass QA only becomes usable when all 12 items are done ("All 12 checklist items must be done before QA can pass."). Passing sets qa_status = passed and records you as the reviewer.
  • Fail QA requires "What needs fixing?" — a note is mandatory (up to 1000 characters) and it is the only thing the ads side gets. Be specific enough to act on.

4. Launch — and then verify reality

The launch itself runs in the client's campaign flow once the draft is approved; the platform's CampaignBriefService::launch() refuses anything without qa_status = passed, so a campaign without your pass cannot go live. Launched campaigns are created PAUSED on Meta and are activated deliberately in Meta Ads Manager.

After the campaign launches, come back and run Verify Launch. It is a deterministic check that reads synced Meta data — no guesses, no live API calls:

  1. Campaign found in synced data.
  2. Status active — actually running.
  3. Spend seen — money is moving.
  4. Leads seen — CRM-attributed leads exist.

The result is stored on the draft and audited.

Expected result: every campaign that is live has a passed 12-point checklist behind it and a launch check confirming it exists, runs, spends and produces leads.

Common mistakes

  • Ticking checklist items you have not actually verified. The gate only works if the pass is honest; QA is the last human check before spend.
  • Failing with a useless note. "Needs work" fixes nothing — name the item and the problem.
  • Passing a draft that is about to change. If the brief is still moving, wait; the checklist is snapshotted against the draft you reviewed.
  • Stopping at the pass. Run Verify Launch after go-live — "launched" in the CRM and "delivering on Meta" are not the same thing.

Technical details

  • Page: MetaQaQueue, $metaPermission = 'meta.campaign.launch' (super admins bypass via User::hasMetaPermission()); queue and badge drop the tenant scope explicitly.
  • Draft statuses: draft, approved, launched, failed, rejected; QA states: in_qa, passed, failed (MetaCampaignDraft).
  • The 12 items live in MetaCampaignDraft::QA_ITEMS (items marked auto + mandatory gate the send-to-QA step; the rest are reviewer-validated).
  • Audit trail: meta_ops.qa_started, meta_ops.qa_checklist, meta_ops.qa_passed, meta_ops.qa_failed, meta_ops.launch_verified.
  • LaunchVerifier reads stored/synced rows only — checks are campaign_found, status_active, spend_seen, lead_seen.

Was this page helpful?