Use this prompt in a new Antigravity session to implement all fixes identified in the BFS audit (docs/opus-analysis-may16.md).
Read docs/opus-analysis-may16.md for the full audit. FlexiBar scored 74/100 with 5 P0 blockers and 5 P1 high-risk items. This prompt covers implementing all fixes.
You can get the Shopify skills from /home/polymath/.gemini/extensions/shopify-plugin
Files to modify:
app/shopify.server.js(line 32 —afterAuthhook)app/shop.server.js(line 188 —ensureHeymantleIdentified)
What to do:
Both files call https://${shop}/admin/api/2025-07/shop.json via REST fetch. This violates BFS requirement 2.2.4 (GraphQL only for new apps since April 2025).
Replace with GraphQL. The challenge is afterAuth doesn't have admin.graphql directly. Options:
- In
afterAuth: useunauthenticated.admin(shop)to get a GraphQL client - Or restructure to do the Heymantle identify in the first authenticated route loader instead
For shop.server.js:ensureHeymantleIdentified: it receives { shop, session } — use the session to create an authenticated admin client or pass admin as a parameter from the calling loader.
The existing getShopDetails(graphql) function already demonstrates the correct GraphQL pattern:
query shopInfo {
shop { name email id }
}Validation: After fixing, run grep -rn "admin/api" app/ — should return zero results.
File: extensions/inument-flexibar/blocks/inument-flexibar.liquid (line 77)
What to do:
Replace the single <link> that loads ALL 6 Google Font families synchronously with:
- Load ONLY the font selected by the merchant (via
fs.fontFamily) - Use
display=optionalto prevent FOUT/CLS - Use non-blocking loading pattern:
<link rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'"> - Skip the font link entirely if
fs.fontFamily == 'system'
Also remove the two <link rel="preconnect"> tags on lines 75-76 and make them conditional (only when a Google Font is actually used).
Validation: Lighthouse audit on storefront should show no render-blocking font requests from the bar.
File: extensions/inument-flexibar/blocks/inument-flexibar.liquid (line 79)
What to do:
<!-- BEFORE -->
{{ 'countdown-templates.js' | asset_url | script_tag }}
<!-- AFTER -->
<script src="{{ 'countdown-templates.js' | asset_url }}" defer></script>Validation: Use the shopify-liquid skill's validate.mjs to confirm the Liquid is valid.
File: extensions/inument-flexibar/blocks/inument-flexibar.liquid (lines 1-7)
What to do: Add presets to the schema block so merchants can discover and add the block from the theme editor:
{% schema %}
{
"name": "Flexibar",
"target": "body",
"settings": [],
"presets": [
{
"name": "Flexibar"
}
]
}
{% endschema %}File: app/routes/webhooks.shop.redact.jsx
What to do: The handler currently logs and returns 200 but doesn't delete any data. Per GDPR, within 48 hours of uninstall, all merchant data must be purged.
Implement a $transaction that deletes from these tables for the shop:
message_translations(via store_bar relation)ai_messagesstore_barsstore_bar_templatessubscription_historywebhook_logsheymantlestore_informationSession(should already be deleted by uninstall, but clean up any orphans)
Use the store_domain from shop.split(".")[0] to find the store. Wrap in try/catch. Prefix all logs with [Webhook].
IMPORTANT: This is a real deletion (not soft-delete) because this is the GDPR data erasure webhook. This is the ONE exception to the "soft delete only" rule in GEMINI.md.
File: extensions/inument-flexibar/blocks/inument-flexibar.liquid
Add a {% doc %} tag BEFORE the {% schema %} tag:
{% doc %}
Renders Flexibar announcement bars on the storefront.
Reads bar configuration from shop.metafields.flexibar.settings.
Supports single, multiple (slider), and running (marquee) bar types.
{% enddoc %}File: app/components/FlexibarEmbedStatus.jsx
Replace the custom <span> with hardcoded colors (#1a9e6e, #8c9196) with Polaris Badge component:
- Enabled →
<Badge tone="success">Enabled</Badge> - Disabled →
<Badge>Disabled</Badge> - Unknown →
<Badge tone="attention">Unknown</Badge>
Files:
app/routes/webhooks.app.uninstalled.jsx— lines 9, 15 missing[Webhook]prefixapp/routes/webhooks.app_subscriptions.update.jsx— multiple lines missing prefixapp/routes/webhooks.app.scopes_update.jsx— line 7 missing prefix
Add [Webhook] prefix to all console.log/console.error calls in these files.
File: extensions/inument-flexibar/blocks/inument-flexibar.liquid
Add a CSS rule that reserves space for the bar before JS runs:
#{{ bar_dom_id }}.fb-bar {
/* existing styles... */
min-height: 44px; /* prevents CLS by reserving space before content renders */
contain: layout style; /* improves rendering performance */
}File: app/routes/app._index.jsx (DraggableBarRow component)
Replace hardcoded pixel values with Polaris CSS custom properties where possible:
padding: "10px 16px"→ usevar(--p-space-300)andvar(--p-space-400)gap: "12px"→ usevar(--p-space-300)fontSize: "14px"→ use Polaris Text component
This is lower priority but shows BFS reviewers you follow Polaris conventions.
- Extract inline JS from Liquid template into a separate
flexibar-runtime.jsasset file loaded withdefer - Reduce
z-index: 999999to9999in the.fb-barCSS - Review if
read_productsscope is truly needed — it's only used for collection listing in page targeting - Add error handling for
getShopGidinmetafield.service.js
- Run
grep -rn "admin/api" app/— should return 0 results - Run
grep -rn "script_tag" extensions/— should return 0 results - Run Lighthouse on storefront with bar active — target < 10 point drop
- Test full flow: install → onboard → create bar → publish → verify on storefront
- Verify all GDPR webhooks work correctly
- Re-read
docs/opus-analysis-may16.mdand confirm each P0/P1 item is resolved