{
  "schemaVersion": 1,
  "title": "AuditHQ historical Australian website screening study: recorded aggregate query results",
  "studyUrl": "https://audithq.com.au/learn/australian-websites-ai-readiness-study",
  "snapshotDate": "2026-09-14",
  "sampleDates": {
    "first": "2026-06-22",
    "last": "2026-09-10",
    "basis": "Database date-range summary recorded at the time; the cohort queries did not specify an explicit date filter."
  },
  "methodology": {
    "unit": "Exact domain string ending in .au",
    "selection": "Completed Quick Scans with non-null overall_score; latest created_at per exact domain string.",
    "segmentSelection": "One matching prospect segment per domain; four reported segments cover 500 of the 515 domains.",
    "scores": "Historical screening category scores, not measured rankings, visits, AI recommendations or citations.",
    "population": "Non-random prospect-heavy sample; not representative of all Australian businesses."
  },
  "provenance": "Original Supabase aggregate query responses recorded on 14 September 2026, recovered from the archived execution record on 5 October 2026.",
  "reproducibility": "These are recorded aggregate outputs, not a frozen row-level database export. The live database can change through new scans and retention. Re-running the SQL now need not reproduce the full historical cohort. Query outputs contain no individual domains or contacts.",
  "queries": [
    {
      "id": "category-summary",
      "executedAt": "2026-09-14T03:45:15.962Z",
      "sql": "with au as (\n  select distinct on (domain) domain, overall_score, bucket_scores, issue_counts\n  from quick_scans\n  where status='completed' and overall_score is not null and domain like '%.au'\n  order by domain, created_at desc\n), b as (\n  select a.domain, x->>'key' as bucket, (x->>'score')::int as score\n  from au a, jsonb_array_elements(a.bucket_scores) x\n)\nselect bucket,\n       count(*) as sites,\n       round(avg(score),1) as avg_score,\n       count(*) filter (where score < 50) as under_50,\n       round(100.0*count(*) filter (where score < 50)/count(*),1) as pct_under_50,\n       count(*) filter (where score < 30) as under_30\nfrom b group by bucket order by avg_score;",
      "rows": [
        {
          "bucket": "ai_readiness",
          "sites": 515,
          "avg_score": "44.4",
          "under_50": 341,
          "pct_under_50": "66.2",
          "under_30": 141
        },
        {
          "bucket": "reputation_signals",
          "sites": 515,
          "avg_score": "57.9",
          "under_50": 183,
          "pct_under_50": "35.5",
          "under_30": 70
        },
        {
          "bucket": "hiring_signals",
          "sites": 515,
          "avg_score": "61.7",
          "under_50": 133,
          "pct_under_50": "25.8",
          "under_30": 53
        },
        {
          "bucket": "technical_health",
          "sites": 515,
          "avg_score": "65.4",
          "under_50": 78,
          "pct_under_50": "15.1",
          "under_30": 9
        },
        {
          "bucket": "trust",
          "sites": 515,
          "avg_score": "71.4",
          "under_50": 113,
          "pct_under_50": "21.9",
          "under_30": 37
        },
        {
          "bucket": "visibility",
          "sites": 515,
          "avg_score": "73.4",
          "under_50": 78,
          "pct_under_50": "15.1",
          "under_30": 7
        }
      ]
    },
    {
      "id": "headline-summary",
      "executedAt": "2026-09-14T03:45:54.688Z",
      "sql": "with au as (\n  select distinct on (domain) domain, overall_score, bucket_scores\n  from quick_scans\n  where status='completed' and overall_score is not null and domain like '%.au'\n  order by domain, created_at desc\n), p as (\n  select domain, overall_score,\n    max(case when x->>'key'='visibility' then (x->>'score')::int end) as visibility,\n    max(case when x->>'key'='ai_readiness' then (x->>'score')::int end) as ai_readiness,\n    max(case when x->>'key'='technical_health' then (x->>'score')::int end) as tech\n  from au, jsonb_array_elements(bucket_scores) x group by domain, overall_score\n)\nselect count(*) as sites,\n  round(avg(visibility),1) as avg_visibility,\n  round(avg(ai_readiness),1) as avg_ai,\n  round(avg(visibility-ai_readiness),1) as avg_gap,\n  count(*) filter (where visibility>=70 and ai_readiness<50) as strong_search_weak_ai,\n  round(100.0*count(*) filter (where visibility>=70 and ai_readiness<50)/count(*),1) as pct_strong_search_weak_ai,\n  count(*) filter (where ai_readiness < visibility) as ai_below_vis,\n  round(100.0*count(*) filter (where ai_readiness < visibility)/count(*),1) as pct_ai_below_vis,\n  round(avg(overall_score),1) as avg_overall,\n  count(*) filter (where overall_score>=80) as grade_a, count(*) filter (where overall_score<50) as under_50\nfrom p;",
      "rows": [
        {
          "sites": 515,
          "avg_visibility": "73.4",
          "avg_ai": "44.4",
          "avg_gap": "29.0",
          "strong_search_weak_ai": 149,
          "pct_strong_search_weak_ai": "28.9",
          "ai_below_vis": 471,
          "pct_ai_below_vis": "91.5",
          "avg_overall": "62.4",
          "grade_a": 77,
          "under_50": 100
        }
      ]
    },
    {
      "id": "prospect-coverage",
      "executedAt": "2026-09-14T03:46:13.779Z",
      "sql": "with au as (\n  select distinct on (domain) domain from quick_scans\n  where status='completed' and overall_score is not null and domain like '%.au'\n  order by domain, created_at desc\n)\nselect\n  (select count(*) from au) as au_domains,\n  (select count(*) from au a where exists (select 1 from growth_accounts g where g.domain = a.domain)) as from_growth_pipeline,\n  (select count(*) from au a where not exists (select 1 from growth_accounts g where g.domain = a.domain)) as not_in_pipeline;",
      "rows": [
        {
          "au_domains": 515,
          "from_growth_pipeline": 503,
          "not_in_pipeline": 12
        }
      ]
    },
    {
      "id": "segment-counts",
      "executedAt": "2026-09-14T03:46:26.466Z",
      "sql": "with au as (\n  select distinct on (domain) domain from quick_scans\n  where status='completed' and overall_score is not null and domain like '%.au' order by domain, created_at desc\n), j as (\n  select a.domain, g.segment, g.location_state, g.source\n  from au a join lateral (select * from growth_accounts g where g.domain=a.domain limit 1) g on true\n)\nselect coalesce(segment,'(none)') as segment, count(*) n from j group by 1 order by n desc limit 15;",
      "rows": [
        {
          "segment": "marketing-agency",
          "n": 143
        },
        {
          "segment": "real-estate-agent",
          "n": 139
        },
        {
          "segment": "web-developer",
          "n": 135
        },
        {
          "segment": "accountant",
          "n": 83
        },
        {
          "segment": "saas",
          "n": 1
        },
        {
          "segment": "saas-marketing-lead",
          "n": 1
        },
        {
          "segment": "digital marketing agency",
          "n": 1
        }
      ]
    },
    {
      "id": "segment-scores",
      "executedAt": "2026-09-14T03:46:43.373Z",
      "sql": "with au as (\n  select distinct on (domain) domain, overall_score, bucket_scores from quick_scans\n  where status='completed' and overall_score is not null and domain like '%.au' order by domain, created_at desc\n), j as (\n  select a.*, g.segment from au a join lateral (select segment from growth_accounts g where g.domain=a.domain limit 1) g on true\n  where g.segment in ('marketing-agency','real-estate-agent','web-developer','accountant')\n), p as (\n  select domain, segment, overall_score,\n    max(case when x->>'key'='visibility' then (x->>'score')::int end) as vis,\n    max(case when x->>'key'='ai_readiness' then (x->>'score')::int end) as ai\n  from j, jsonb_array_elements(bucket_scores) x group by domain, segment, overall_score\n)\nselect segment, count(*) sites,\n  round(avg(overall_score),1) avg_overall,\n  round(avg(vis),1) avg_visibility,\n  round(avg(ai),1) avg_ai_readiness,\n  round(avg(vis-ai),1) avg_gap,\n  round(100.0*count(*) filter (where ai<50)/count(*),1) pct_ai_under_50,\n  round(100.0*count(*) filter (where ai<vis)/count(*),1) pct_ai_below_vis\nfrom p group by segment order by avg_ai_readiness;",
      "rows": [
        {
          "segment": "accountant",
          "sites": 83,
          "avg_overall": "58.2",
          "avg_visibility": "69.1",
          "avg_ai_readiness": "36.3",
          "avg_gap": "32.8",
          "pct_ai_under_50": "77.1",
          "pct_ai_below_vis": "96.4"
        },
        {
          "segment": "real-estate-agent",
          "sites": 139,
          "avg_overall": "59.9",
          "avg_visibility": "67.9",
          "avg_ai_readiness": "37.1",
          "avg_gap": "30.8",
          "pct_ai_under_50": "78.4",
          "pct_ai_below_vis": "93.5"
        },
        {
          "segment": "web-developer",
          "sites": 135,
          "avg_overall": "62.2",
          "avg_visibility": "75.0",
          "avg_ai_readiness": "47.5",
          "avg_gap": "27.5",
          "pct_ai_under_50": "62.2",
          "pct_ai_below_vis": "92.6"
        },
        {
          "segment": "marketing-agency",
          "sites": 143,
          "avg_overall": "65.7",
          "avg_visibility": "77.7",
          "avg_ai_readiness": "51.4",
          "avg_gap": "26.3",
          "pct_ai_under_50": "56.6",
          "pct_ai_below_vis": "86.0"
        }
      ]
    }
  ]
}
