Review output, then:
QA Audit Report

Review output, then:

4 blocker · 19 important · 26 recommended · 23 passing · 86 total findings across 10 categories.

2026-05-06 https://pybar.121group.dev/ WordPress (detected)
4
Blockers
19
Important
26
Recommended
23
Already Good
86
Total Items
Executive summary

Executive summary

This report covers the mandatory 10 audit categories required for every 121 Group pre-launch review. Each finding is classified by severity and assigned a short ID for tracking.

| Severity | Count | Meaning | |---|---|---| | Blocker | 4 | Must be fixed before launch. Real risk to security, accessibility, or basic function. | | Important | 19 | Should be fixed before launch if possible. Noticeable impact on quality. | | Recommended | 26 | Nice to have. Hardening or polish items. | | Already good | 23 | Verified passing. Recorded for transparency. |

Security & hardening

Security & hardening

Automated security audit covering both the public surface (headers, exposed files, auth surface) and authenticated filesystem-level checks via cPanel (WP core version, wp-config.php hardening, installed plugin/theme versions, debug.log review). WP install located at /home/gr21ou1p/public_html/Pybar.

I1X-Powered-By header leaks tech stack: `PHP/8.4.20`
Important

Response header X-Powered-By: PHP/8.4.20 reveals the PHP version, helping attackers target known CVEs.

Fix: Add to .htaccess or php.ini:

Header unset X-Powered-By

Or in php.ini: expose_php = Off

Assigned to:
I26 of 6 recommended security headers are missing
Important

The site does not set the following security headers:

  • Strict-Transport-Security (HSTS) (strict-transport-security) — Enforces HTTPS for returning visitors. Recommended: max-age=31536000; includeSubDomains; preload
  • X-Content-Type-Options (x-content-type-options) — Should be nosniff to prevent MIME-type confusion attacks.
  • X-Frame-Options (x-frame-options) — Should be SAMEORIGIN or DENY to prevent clickjacking.
  • Referrer-Policy (referrer-policy) — Should be strict-origin-when-cross-origin or stricter.
  • Permissions-Policy (permissions-policy) — Should restrict unused browser features (camera, microphone, geolocation).
  • Content-Security-Policy (CSP) (content-security-policy) — Advanced: restricts which scripts/styles can load. Complex to configure — add after launch once site is profiled.

Fix: Add a combined header block to .htaccess:

<IfModule mod_headers.c>
 Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" env=HTTPS
 Header always set X-Content-Type-Options "nosniff"
 Header always set X-Frame-Options "SAMEORIGIN"
 Header always set Referrer-Policy "strict-origin-when-cross-origin"
 Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
</IfModule>

Defer CSP until post-launch.

Assigned to:
R3WordPress version publicly disclosed: `6.9.4`
Recommended

The meta generator tag reveals the WordPress version. Attackers use this to match known CVEs.

Fix: Remove via functions.php:

remove_action('wp_head', 'wp_generator');
add_filter('the_generator', '__return_empty_string');
Assigned to:
B4readme.html is publicly accessible and leaks the WordPress version
Blocker

https://pybar.121group.dev/readme.html returns HTTP 200 with full WP version info.

Fix: Block via .htaccess:

<FilesMatch "^(readme|license|CHANGELOG)\.(txt|html|md)$">
 Require all denied
</FilesMatch>

Or simply delete the file (it is recreated on core updates — add deletion to post-update runbook).

Assigned to:
B55 plugin readme files publicly expose exact versions
Blocker

Attackers use these to match against CVE databases and run targeted exploits.

| Plugin | Version | |---|---| | spectra-pro | 1.2.10 | | ultimate-addons-for-gutenberg | 2.19.25 | | astra-addon | 4.13.1 | | ewww-image-optimizer | 8.5.0 | | mailchimp-for-wp | 4.12.2 |

Fix: Block via .htaccess at site root:

<FilesMatch "^(readme|license|changelog|CHANGELOG)\.(txt|html|md)$">
 Require all denied
</FilesMatch>

A good security plugin (Wordfence / SolidWP / All In One WP Security) handles this automatically.

Assigned to:
B6/wp-admin/install.php is publicly accessible (HTTP 200)
Blocker

Although the site is already installed (page shows "Already Installed"), the endpoint itself should be blocked. If the DB is ever corrupted, an attacker who reaches install.php can take over the installation.

Fix: Block via .htaccess:

<Files install.php>
 Require all denied
</Files>
Assigned to:
G7No sensitive files exposed
Already Good

All tested sensitive paths return 403 or 404.

Assigned to:
I8Author enumeration leaks admin username slug: `121-josh`
Important

GET /?author=1 redirects to /author/121-josh/, exposing the first registered user's slug (usually an Administrator).

Fix (pick at least one):

  1. Block ?author=N via functions.php:
add_action('template_redirect', function () {
 if (isset($_GET['author'])) { wp_safe_redirect(home_url(), 301); exit; }
});
  1. In phpMyAdmin, edit wp_users and set user_nicename to something other than the username.
  1. Use a security plugin with "disable user enumeration" option.
Assigned to:
G9REST API user enumeration blocked or protected
Already Good
Assigned to:
R10xmlrpc.php is reachable (HTTP 405)
Recommended

xmlrpc.php is a historical WP feature used by Jetpack and some mobile apps. It is also a common brute-force target via system.multicall.

If unused, disable via functions.php: ``php add_filter('xmlrpc_enabled', '__return_false'); ``

Or block via .htaccess: ``apache <Files xmlrpc.php> Require all denied </Files> ``

Assigned to:
R11wp-login.php is publicly reachable
Recommended
  • Login is at the default URL, which is the first target of automated brute-force attacks. Consider:
  • Rate limiting via a security plugin (Wordfence, SolidWP)
  • Changing the login URL via "WPS Hide Login" or similar
  • Requiring 2FA for all Administrator and Editor roles
Assigned to:
G12WP_DEBUG is correctly disabled
Already Good
Assigned to:
I13`DISALLOW_FILE_EDIT` is not set in wp-config.php
Important

Without this constant, a compromised Administrator account can edit PHP files directly from wp-admin → Appearance → Theme File Editor, turning a credential leak into remote code execution.

Fix in wp-config.php:

define( 'DISALLOW_FILE_EDIT', true );

Also consider DISALLOW_FILE_MODS (blocks theme/plugin installs via UI entirely).

Assigned to:
G14Database uses custom table prefix `pb_`
Already Good
Assigned to:
G15All 8 salts are set and not boilerplate
Already Good
Assigned to:
R16`FORCE_SSL_ADMIN` is not set
Recommended

Enforces HTTPS for wp-admin and login. Usually fine without it if the site already redirects HTTP → HTTPS at the server level, but explicit is safer.

Fix in wp-config.php:

define( 'FORCE_SSL_ADMIN', true );
Assigned to:
N17WordPress core version (authenticated): **6.9.4**
Info

Read directly from wp-includes/version.php. Compare against the latest stable release at https://wordpress.org/download/ — if a minor version is behind, update as part of launch prep.

Assigned to:
N1811 plugins installed (authenticated file-system scan)
Info

Exact versions from plugin PHP header blocks (more reliable than readme.txt leak detection):

| Plugin slug | Version | Name | |---|---|---| | astra-addon | 4.13.1 | Astra Pro | | custom-fonts | 2.1.17 | Custom Fonts | | ewww-image-optimizer | 8.5.0 | EWWW Image Optimizer | | mailchimp-for-wp | 4.12.2 | MC4WP: Mailchimp for WordPress | | meta-box-lite | 2.5.0 | Meta Box Lite | | seo-by-rank-math | 1.0.268 | Rank Math SEO | | spectra-pro | 1.2.10 | Spectra Pro | | ultimate-addons-for-gutenberg | 2.19.25 | Spectra | | wp-grid-builder | 2.3.2 | WP Grid Builder | | wp-grid-builder-map-facet | 2.0.4 | WP Grid Builder - Map Facet | | wp-grid-builder-meta-box | 1.2.0 | WP Grid Builder - Meta Box |

For CVE checking, paste this list into https://wpscan.com/ or https://patchstack.com/database/ (both offer free lookups).

Assigned to:
R193 default WordPress themes left installed but unused
Recommended

Unused themes still receive security updates but also widen the attack surface if any have vulnerabilities. Keep ONE as a fallback, delete the rest:

  • twentytwentyfive v1.4
  • twentytwentyfour v1.4
  • twentytwentythree v1.6

Fix (WP admin): Appearance → Themes → hover on each → Theme Details → Delete.

Assigned to:
Performance & Core Web Vitals

Performance & Core Web Vitals

Automated performance audit via Google Lighthouse in mobile-simulated mode (Moto G4, 4G). Score: 96/100. CrUX real-user data unavailable (see info finding below). Full Lighthouse report stored in ctx.shared.lighthouse for reference.

G1Lighthouse Performance score: 96/100
Already Good

Mobile throttled test (simulated Moto G4 / 4G). Excellent.

Assigned to:
G2Largest Contentful Paint (LCP): 2.16s
Already Good

Below 2.5s — good.

Assigned to:
G3Cumulative Layout Shift (CLS): 0.000
Already Good

Below 0.1 — good.

Assigned to:
G4Total Blocking Time (TBT): 92ms
Already Good

Proxy for real-world INP. Under 200ms is good.

Assigned to:
G5Server response (TTFB): 140ms
Already Good

Good.

Assigned to:
G6Total page weight: 397KB
Already Good

Lean page. Good.

Assigned to:
R1Unused JavaScript: ~241KB could be removed
Recommended

Review plugin output. Lighthouse identified JS that is loaded but not executed on the homepage. Consider conditionally loading scripts only where needed.

Assigned to:
N1Real-user CrUX data not fetched (Google API quota exhausted)
Info

The shared PageSpeed Insights API quota is exhausted. To enable real-user Core Web Vitals in future audits:

  1. Go to https://console.cloud.google.com/apis/credentials
  2. Create a free API key (no billing account needed for CrUX/PSI)
  3. Restrict the key to Chrome UX Report API + PageSpeed Insights API
  4. Save it to C:/Users/Joshua/.pi-secrets/crux.env as:
GOOGLE_CRUX_API_KEY=AIza…

Future audits will then include real-user LCP / INP / CLS / FCP / TTFB percentile data from millions of real Chrome users — the actual signal Google uses for SEO ranking.

Assigned to:
Accessibility (WCAG 2.2 AA)

Accessibility (WCAG 2.2 AA)

Automated scan failed for this category: net::ERR_CONNECTION_TIMED_OUT at https://pybar.121group.dev/. Needs manual review.

E1Automated scan error: net::ERR_CONNECTION_TIMED_OUT at https://pybar.121group.dev/
Important

Re-run the audit or perform this category manually.

Assigned to:
SEO

SEO

Automated SEO audit: meta tags, canonical, robots, sitemap, Open Graph, Twitter Card, schema.org, mixed content, link inventory. Checked the homepage deeply and 11 additional crawled page(s) for consistency. A full SEO audit should also cover keyword research, internal linking depth, and competitor analysis — human-judgement tasks beyond this scan.

G1Page title length OK (55 chars)
Already Good

"Underground Mining Contractor - Mining Services | PYBAR"

Assigned to:
G2Meta description length OK (152 chars)
Already Good
Assigned to:
R1Missing canonical URL
Recommended

Add a canonical link to prevent duplicate-content issues.

<link rel="canonical" href="https://example.com/page/">

(Yoast and RankMath do this automatically.)

Assigned to:
G3Staging site correctly marked `noindex, nofollow`
Already Good

Prevents staging content from being indexed by Google.

Assigned to:
R2No robots.txt file found
Recommended

WordPress serves a default dynamic robots.txt if no physical file exists, but adding an explicit one is best practice.

Assigned to:
I1No XML sitemap found
Important

Install/activate Yoast or RankMath to auto-generate one. Sitemaps accelerate search-engine indexing.

Assigned to:
R3Some Open Graph tags missing: og:image
Recommended
Assigned to:
G4Schema.org types detected: GeneralContractor, Organization, WebSite, ImageObject, WebPage, Person, Article
Already Good
Assigned to:
R441 unique outbound/internal links found on homepage
Recommended

Link validation is performed in the Content Quality category. See there for broken-link findings.

Assigned to:
G5No mixed-content (HTTP) resources
Already Good

All scripts, styles, images, iframes use HTTPS.

Assigned to:
N1Multi-page SEO scan: checked 12 page(s)
Info

Pages crawled:

  • https://pybar.121group.dev/
  • https://pybar.121group.dev/case-studies/
  • https://pybar.121group.dev/news/
  • https://pybar.121group.dev/contact/
  • https://pybar.121group.dev/contact-us/
  • https://pybar.121group.dev/news-resources/news/
  • https://pybar.121group.dev/our-services/
  • https://pybar.121group.dev/our-credentials/
  • https://pybar.121group.dev/projects/
  • https://pybar.121group.dev/our-approach/
  • https://pybar.121group.dev/resource-centre/
  • https://pybar.121group.dev/gallery/
Assigned to:
I21 of 12 pages missing meta description
Important

Write a unique 140-160 char meta description for each key page. Missing pages:

  • https://pybar.121group.dev/contact-us/
Assigned to:
R511 page(s) missing canonical URL
Recommended
  • https://pybar.121group.dev/case-studies/
  • https://pybar.121group.dev/news/
  • https://pybar.121group.dev/contact/
  • https://pybar.121group.dev/contact-us/
  • https://pybar.121group.dev/news-resources/news/
  • https://pybar.121group.dev/our-services/
  • https://pybar.121group.dev/our-credentials/
  • https://pybar.121group.dev/projects/
  • https://pybar.121group.dev/our-approach/
  • https://pybar.121group.dev/resource-centre/
Assigned to:
I3Duplicate <title> tags detected across 1 title string(s)
Important

Every page should have a unique title for SEO. Duplicates cause Google to pick one and ignore the others.

  • "News | PYBAR" shared by 2 pages:
  • https://pybar.121group.dev/news/
  • https://pybar.121group.dev/news-resources/news/
Assigned to:
R6Duplicate meta descriptions across 1 description string(s)
Recommended
  • Description shared by 2 pages: "Founded in 1993, PYBAR is the third largest underground hard…"
Assigned to:
Content quality

Content quality

Content-quality scan across the homepage and 11 additional crawled page(s). Checks: placeholder text, stale dates, broken links, NAP consistency, word count, caps-lock usage, plaintext email exposure. A full content audit (tone, grammar, SEO-keyword mapping) still requires human review.

G1No placeholder text markers found on homepage
Already Good

Checked for: Lorem ipsum, TBD, Coming soon, [insert …], etc.

Assigned to:
R1Multiple phone numbers found on homepage (2 unique)
Recommended

Found: 0263616400, 060589433

Ensure each is intentional. Inconsistent NAP (Name/Address/Phone) data across the site hurts local SEO.

Assigned to:
I133 broken link(s) on homepage (tested 41)
Important

Broken links hurt user trust and SEO. Fix or remove:

  • https://pybar.121group.dev/ — timeout
  • https://pybar.121group.dev/our-services/ — timeout
  • https://pybar.121group.dev/our-services/mine-development/ — timeout
  • https://pybar.121group.dev/our-services/mine-production/ — timeout
  • https://pybar.121group.dev/our-services/cable-bolting-and-production-drilling/ — timeout
  • https://pybar.121group.dev/our-services/raise-boring/ — timeout
  • https://pybar.121group.dev/our-services/shotcreting/ — timeout
  • https://pybar.121group.dev/our-services/fleet/ — timeout
  • https://pybar.121group.dev/our-credentials/ — timeout
  • https://pybar.121group.dev/our-credentials/company-profile/ — timeout
  • https://pybar.121group.dev/our-credentials/our-history/ — timeout
  • https://pybar.121group.dev/our-credentials/our-team/ — timeout
  • https://pybar.121group.dev/projects/ — timeout
  • https://pybar.121group.dev/case-studies/ — timeout
  • https://pybar.121group.dev/our-credentials/testimonials/ — timeout

_…and 18 more_

Assigned to:
G2Homepage word count: 1866
Already Good
Assigned to:
B1Placeholder text detected on 1 additional page(s)
Blocker

These pages contain Lorem ipsum, TBD, or similar markers:

  • https://pybar.121group.dev/our-services/ — Lorem ipsum placeholder
Assigned to:
I23 page(s) have very little content (<80 words)
Important

Thin content rarely ranks and may indicate incomplete pages:

  • https://pybar.121group.dev/news/ — 12 words
  • https://pybar.121group.dev/contact-us/ — 21 words
  • https://pybar.121group.dev/news-resources/news/ — 12 words
Assigned to:
N1Average page length across 11 additional page(s): 350 words
Info

_Reasonable content depth._

Assigned to:
UI / UX

UI / UX

Automated scan failed for this category: net::ERR_CONNECTION_TIMED_OUT at https://pybar.121group.dev/. Needs manual review.

E1Automated scan error: net::ERR_CONNECTION_TIMED_OUT at https://pybar.121group.dev/
Important

Re-run the audit or perform this category manually.

Assigned to:
Images & media

Images & media

Scanned 12 <img> element(s) on the homepage. Checked: alt text, explicit dimensions, lazy-loading, responsive srcset, file sizes, Open Graph image, favicon set, logo format.

R15 image(s) don't have loading attribute
Recommended

WordPress adds loading="lazy" automatically via wp_get_attachment_image(). Themes that manually output <img> tags bypass this. Add loading="lazy" to below-the-fold images (and fetchpriority="high" to the LCP image).

Assigned to:
G1All 12 images have alt attributes
Already Good

12 are decorative (empty alt).

Assigned to:
I1No Open Graph image set
Important

Links shared on Facebook, LinkedIn, Slack, WhatsApp, etc. will show without a preview image, reducing click-through rates.

Assigned to:
G23 favicon/icon tag(s) set
Already Good
Assigned to:
R2Logo served as WEBP
Recommended

If the logo is vector, serve as SVG for perfect scaling across screen densities.

Assigned to:
Forms, integrations & conversion

Forms, integrations & conversion

Automated form inspection limited to what's visible in the page HTML. End-to-end form testing (submit → email delivery → CRM sync → thank-you page → analytics event) still requires manual or Cypress/Playwright testing before launch.

N11 form(s) detected on homepage
Info
Assigned to:
I1Form #1 (action: (not set)) has no CSRF nonce
Important
  • Form #1: action=(not set) method=POST
  • 7 input(s), 1 label(s)
  • Nonce/CSRF token: NO
  • Honeypot: detected
  • reCAPTCHA/Turnstile/hCaptcha: not detected

Fix: WordPress forms must include wp_nonce_field(). Third-party form plugins (Gravity Forms, WPForms, Contact Form 7, Mailchimp for WP) handle this automatically — if one is missing, it usually means a hand-rolled form needs hardening.

Assigned to:
R1Form #1: 1 labels for 7 inputs
Recommended

Placeholder text is not a replacement for <label>. Every form field should have a visible associated label for accessibility and usability.

Assigned to:
R2Form #1: 2 input(s) missing autocomplete hints
Recommended

Adding autocomplete="email", autocomplete="tel", autocomplete="name" lets browsers pre-fill, improving conversion. Especially important on mobile.

Assigned to:
R3No SMTP plugin detected in page source
Recommended

WordPress's native wp_mail() uses the server's mail() function which is notoriously unreliable for deliverability (spam folder, bounces). Install WP Mail SMTP, FluentSMTP, or similar and route through a transactional provider (SendGrid, Postmark, Mailgun, Amazon SES).

  • Also verify DNS records:
  • SPF TXT record authorising the sender domain
  • DKIM for email signing
  • DMARC policy for anti-spoofing

Use https://mxtoolbox.com/domain/ to audit.

Assigned to:
N2Newsletter signup detected — needs end-to-end test
Info
  1. Submit a test email and verify:
  2. Subscriber lands in the correct Mailchimp / ActiveCampaign / HubSpot list
  3. Confirmation email is received (double opt-in configured)
  4. Welcome automation triggers
  5. Unsubscribe link works
Assigned to:
Launch readiness & infrastructure

Launch readiness & infrastructure

Launch-readiness items combine automated checks with manual verification tasks. The automated items below are flagged; the manual items are included as checklist entries for the team to tick off in-browser.

N1SSL/TLS details
Info

Cert validation handled by the edge server (Cloudflare or LiteSpeed). Verify the certificate auto-renews and that includeSubDomains HSTS is configured across all production subdomains.

Assigned to:
N2Staging → production URL checklist
Info

Current staging host: pybar.121group.dev

Before launch, run a search-and-replace across the entire database replacing the staging URL with the production URL:

```bash wp search-replace 'https://pybar.121group.dev' 'https://example.com' --all-tables --dry-run

Assigned to:
R1Backup strategy — verify before launch (manual)
Recommended

Confirm at least ONE of the following is configured and tested:

  • Synergy JetBackup (cPanel → JetBackup 5) — verify last backup ran successfully and restoration has been tested
  • UpdraftPlus / BlogVault / ManageWP — scheduled offsite backups
  • Host-level snapshots — confirm retention policy

Do a restoration test on staging before launch. An untested backup is not a backup.

Assigned to:
R2DNS cutover plan — verify before launch (manual)
Recommended

Before launch day:

  1. Lower TTL on production A/CNAME records to 300s (5 min) at least 24 hours before cutover. This allows a fast rollback.
  2. Document the old DNS configuration (screenshots + export) in case we need to revert.
  3. Prepare the redirect map (see next item).
  4. Lock a launch window outside peak traffic hours; inform stakeholders.
  5. After launch: monitor real-user traffic and errors for 2 hours minimum before raising TTL back to 3600s.
Assigned to:
R3301 redirect map — verify before launch (manual)
Recommended

If any URLs have changed between the old and new site (permalink structure, page slugs, category paths), you MUST provide 301 redirects to preserve SEO equity.

  1. Crawl the OLD production site (e.g. using Screaming Frog) and export the URL list.
  2. Map every old URL to its new equivalent.
  3. Implement redirects via Rank Math Redirections, Redirection plugin, or in .htaccess.
  4. Test 20 random old URLs post-launch and confirm 301 (not 404 or 302).
Assigned to:
R4Documented rollback plan — verify before launch (manual)
Recommended
  1. A one-page document shared with the team, answering:
  2. Who authorises a rollback? (RACI)
  3. How do we restore the previous site? (DNS revert + DB restore)
  4. How long does it take? (target < 30 mins)
  5. What communications go out during a rollback?
Assigned to:
R5Uptime + error monitoring — verify configured (manual)
Recommended

Post-launch, at minimum:

  • Uptime monitor hitting the homepage every 1-5 minutes: UptimeRobot (free), Better Uptime, Pingdom
  • Error monitoring for custom PHP/JS: Sentry, Rollbar, or at least enable WP's WP_DEBUG_LOG in production (carefully)
  • Analytics real-time view open on launch day
  • Search Console coverage report checked daily for first week
Assigned to:
I1Launch-day action: remove noindex/nofollow from production
Important

The current site at pybar.121group.dev is correctly noindex, nofollow. When cloning / pushing to production, you MUST:

  1. In WP admin → Settings → Reading, uncheck "Discourage search engines".
  2. In Rank Math / Yoast, ensure the "noindex" toggle is off for production.
  3. Verify with curl -I https://production.example.com/ | grep -i robots returns nothing, or the page source has no <meta name="robots" content="noindex">.
Assigned to:
R6No CDN detected in front of the site
Recommended

Both LiteSpeed QUIC.cloud (free, included with LiteSpeed Cache) and Cloudflare (free tier sufficient for most) dramatically improve perceived performance and block many attacks at the edge. Consider enabling before launch.

Assigned to:
G1Hosting disk usage: 15.74 GB / 50 GB (31%)
Already Good

Disk at 31% of quota. Plenty of headroom.

Assigned to:
N323 MySQL database(s) on the cPanel account totalling 629 MB
Info

All databases on this cPanel (including non-WordPress ones):

| Database | Size | |---|---| | gr21ou1p_121db | 2 MB | | gr21ou1p_burrowsbuilt-db | 46 MB | | gr21ou1p_cairns_db | 12 MB | | gr21ou1p_capitalhoist_db | 15 MB | | gr21ou1p_careers_phmc | 2 MB | | gr21ou1p_eslbioscience | 6 MB | | gr21ou1p_evolvedb | 82 MB | | gr21ou1p_heavydieselgoup_db | 12 MB | | gr21ou1p_hill_blume_db | 25 MB | | gr21ou1p_jobfit_db | 30 MB | | gr21ou1p_kdewa_db | 36 MB | | gr21ou1p_ldhmf_db | 15 MB | | gr21ou1p_nqresources_db | 19 MB | | gr21ou1p_okeeffes_db | 55 MB | | gr21ou1p_oryan_db | 11 MB | | gr21ou1p_ozgoldenrush_db | 71 MB | | gr21ou1p_ph_medical_centres | 56 MB | | gr21ou1p_piccolo_db | 22 MB | | gr21ou1p_pybar_db | 28 MB | | gr21ou1p_qresources_db | 15 MB |

_… and 3 more._

Assigned to:
N4WordPress core version (authenticated): **6.9.4**
Info

Compare against https://wordpress.org/download/ — if a minor patch is available, update as part of launch prep. Major version upgrades (e.g. 6.8 → 7.0) should be tested on staging first.

Assigned to:
N5Post-launch checklist (48 hours)
Info

Work through within 48 hours of cutover:

  • [ ] Submit the XML sitemap to Google Search Console
  • [ ] Submit to Bing Webmaster Tools
  • [ ] Verify GA4 is receiving data (real-time view)
  • [ ] Verify conversion events fire (test each form/CTA)
  • [ ] Test 20 random old URLs → confirm 301 to new URL
  • [ ] Run PageSpeed Insights on 5 key pages → save baseline
  • [ ] Test all forms end-to-end (email delivery, CRM sync)
  • [ ] Check 404 page still works
  • [ ] Verify backup runs successfully on the new site
  • [ ] Stakeholder sign-off captured in writing
Assigned to:
Mobile-first readiness

Mobile-first readiness

Mobile-first readiness: viewport meta tag, CSS mobile-first heuristic, base font size, input-type appropriateness, horizontal overflow at 320px (iPhone SE), content parity with Googlebot-Mobile, plus real-device tests on iPhone 15 / Pixel 8 / Galaxy S24 / iPad Pro 12.9 via BrowserStack Automate.

G1Viewport meta tag is correctly set
Already Good

width=device-width, initial-scale=1

Assigned to:
R1No responsive CSS media queries detected
Recommended

Accessible CSS queries may be loaded after first paint, but this heuristic suggests the page may not be responsive at all. Verify manually at multiple breakpoints.

Assigned to:
I1Body font-size is 14px (below 16px)
Important

iOS Safari auto-zooms when a user taps an input with font-size <16px. This causes visual jank and can trap the user at the wrong zoom level. Fix by setting body font-size to at least 16px, or specifically for inputs:

input, select, textarea { font-size: 16px; }
Assigned to:
G2No horizontal overflow at 320px viewport
Already Good

Fits iPhone SE / small Android screens.

Assigned to:
I2Googlebot-Mobile sees 3% of the desktop content (mobile-first indexing risk)
Important

Googlebot indexes your site using the mobile version. If content is hidden/stripped on mobile, Google won't see it.

  • Desktop: ~1175 words of body text
  • Googlebot-Mobile: ~35 words

Common causes: display:none on mobile, content-gating behind "Show more" buttons that aren't fully expanded for bots, tabbed content loaded via JS.

Fix: Use CSS to reflow, not hide. Use progressive disclosure that remains in the DOM.

Assigned to:
N1Real-device test results (BrowserStack)
Info

Tested on 4 real devices via BrowserStack Automate. Screenshots captured from real hardware — click to enlarge:

iPhone 15 (iOS 17, Safari)

iPhone 15 (iOS 17, Safari) screenshot
  • Viewport: 393×659
  • Body font-size: 14.6px
  • Horizontal overflow: no
  • Page title: "Underground Mining Contractor - Mining Services | PYBAR"

Google Pixel 8 (Android 14, Chrome)

Google Pixel 8 (Android 14, Chrome) screenshot
  • Viewport: 411×784
  • Body font-size: 14.6px
  • Horizontal overflow: no
  • Page title: "Underground Mining Contractor - Mining Services | PYBAR"

Samsung Galaxy S24 (Android 14, Chrome)

Samsung Galaxy S24 (Android 14, Chrome) screenshot
  • Viewport: 360×647
  • Body font-size: 14.6px
  • Horizontal overflow: no
  • Page title: "Underground Mining Contractor - Mining Services | PYBAR"

iPad Pro 12.9 (iOS 17, Safari)

iPad Pro 12.9 (iOS 17, Safari) screenshot
  • Viewport: 1024×1292
  • Body font-size: 16px
  • Horizontal overflow: no
  • Page title: "Underground Mining Contractor - Mining Services | PYBAR"
Assigned to:
Saved