Plan: Athos (Searchspring) Front-End Integration — RBD
Site: SuiteCommerce Standard (NOT SCA, NOT headless, NOT SPA)
Athos account ID: atqzs8
Source docs (read 2026-06-26; re-read 2026-06-29 to confirm mapping & extract DOM detail):
- Integration Instructions — Search, Category: docs.google.com/document/d/1H4KxuRXnL-HCEBJ1kKJfMhEQvlI24zki8VQmPYfsiGM ✅ confirmed
- Integration Instructions — Recommendations: docs.google.com/document/d/12uU6Bkz6okg1MtktnMS7oCfbL1Wu3d4l70DjfimIz88 ✅ confirmed (session-2.md's "Recovered Artifacts" had these swapped — corrected)
- Backend feed:
plans/athos-commerce-feed.md(deployed 2026-05-26). Actual source:~/ai-projects/Riley-Blake-Designs/integrations/athos-integration/athos_product_feed.js— a Suitelet (External Access), account4582045, NOT the "Scheduled Script" the plan doc described. Feed columns: Unique ID (internalid) · SKU (itemid) · Name · Product URL · Price (baseprice) · Thumbnail (SKU-derived) · Inventory · Description · Category External IDs · Categories · Collection · Width · Designer · Color · Release Date · Reorderable · Price Level Map.
What "stock tooling covers it" actually means
Matt's verdict = no NetSuite backend / SuiteScript development needed. Every change below is standard SuiteCommerce front-end customization: theme template overrides + SMT/CMS content blocks + the Configuration record. That is the supported, "stock" customization path — but it is still theme-developer work (editing .tpl templates and re-deploying the theme). "Stock" ≠ "no-code in the admin UI." Set expectations accordingly: this is a theme customization project, not a backend project.
The 6 work items (from the two docs)
1. Global Athos script (head, every page)
Add before closing </head>, site-wide:
<script type="text/javascript" src="https://snapui.athoscommerce.io/atqzs8/bundle.js" id="athos-context"></script>
On category pages only, the same tag must carry a dynamic category id:
<script type="text/javascript" src="https://snapui.athoscommerce.io/atqzs8/bundle.js" id="athos-context">
category = { id: "[category id]" };
</script>
2. Search results page (new page, kept separate for easy revert)
- Create a new search-results page at a URL of our choosing (keep the existing one intact for rollback).
- Body element must get class
ss-shopwhen on this page. - Add the two injection targets — Athos wipes and replaces everything inside them:
<div id="athos-sidebar" style="min-height: 100vh"></div> <!-- filters -->
<div id="athos-content" style="min-height: 100vh"></div> <!-- results -->
- Nothing we want to keep may live inside
athos-sidebar/athos-content. - The doc's "Expanded example" places these inside stock SC Facets.Browse markup —
athos-sidebargoes insidediv.facets-facet-browse-facets(next to.facets-facet-browse-facets-sidebaranddata-cms-area="facet_navigation_bottom"), andathos-contentinsidediv.facets-facet-browse-results. → The integration point is aFacets.Browsetemplate override, not a CMS page (resolves Open Q1's mechanism).
3. Category pages
- Same
athos-sidebar+athos-contentinjection targets as #2 (noss-shopbody class needed — category id comes from the script tag in #1).
4. Search form rewrite (all forms — desktop + mobile)
form→action="/[new-search-page-url]/",method="get"- search
input→name="q" - Remove every
<input type="hidden">inside the form - Disable any native/cart/plugin autocomplete (it will render over Athos Autocomplete)
- Comment out (don't delete) the old form markup for easy revert
5. Recommendation blocks (Home / PDP / Cart / 404)
Drop an athos/recommendations script + a target div on each surface:
| Surface | Profile tag(s) | Target div(s) | Extra globals |
|---|---|---|---|
| Home | home |
.ss__recs__home |
shopper id (if logged in) |
| PDP | bundle, cross-sell, similar, recently-viewed |
.ss__recs__bundle / …__cross-sell / …__similar / …__recently-viewed |
products: ['sku_variable'] + shopper id |
| Cart | view-cart |
.ss__recs__view-cart |
shopper id |
| 404 | 404 |
.ss__recs__404 |
shopper id |
customer_variable→ logged-in customer ID (omit entirely if anonymous).sku_variable(PDP only) → must exactly match theskuvalue in the data feed (see gotcha #1).
6. No-results page
- Nothing to build. Athos already hosts this via their template. Just verify the preview during UAT.
Doc bug (404 block): the Recommendations doc's 404 example
<div>readsclass="ss__recs__[profile name]"(unfilled placeholder) while its script selector is.ss__recs__404. Use.ss__recs__404on the div so the selector matches — otherwise 404 recs render nowhere.
Gap analysis — requirement vs. stock SuiteCommerce Standard
| # | Requirement | Stock SC mechanism (candidate) | Confidence | Notes / risk |
|---|---|---|---|---|
| 1 | Global head script | Theme main template OR Configuration "custom head HTML" OR GTM tag | High | Doc says head is "preferable," not required — GTM (built into SC config) is the zero-theme fallback if head edit is awkward. |
| 1b | Dynamic category = {id} on category pages only |
Theme category template (Facets.Browse) emitting the SC category internal id |
Medium | Must resolve the current category id server/client-side. Must match the feed's category field (gotcha #2). |
| 2 | New search page + ss-shop body class + injection divs |
Theme template override of the search/facets layout (Facets.Browse.View.tpl) |
Medium ⬆ | Doc's Expanded example uses stock facets-facet-browse-facets/-results classes → confirms a Facets.Browse template override (NOT a CMS page). Remaining unknown is only the new-URL routing — confirm with Matt. |
| 3 | Category injection divs | Same facets/browse template override | Medium | Shares the template work with #2. |
| 4 | Search form rewrite (all forms) | Theme header template (SearchHistory/Header.Search form markup) |
High | Straightforward template edit. Watch for SC's own type-ahead — must be disabled. |
| 5 | Home recs block | SMT/CMS custom-HTML merchandising zone | High | Home is the easiest — pure CMS content. |
| 5 | Cart / 404 recs blocks | Theme templates (cart + 404 are app-rendered, not CMS) | Medium | Likely template edits, not CMS. |
| 5 | PDP recs (dynamic SKU) | PDP template (ProductDetails.Full.View.tpl) injecting the item's feed-SKU |
Medium | Dynamic SKU binding is the correctness-critical part (gotcha #1). |
| 6 | No-results | Athos-hosted | N/A | Verify only. |
| — | customer_variable binding |
SC session/profile model (SC.getSessionInfo().user or profile model) |
Medium | Confirm the field that maps to the customer id used by Athos. |
Bottom line: items 1, 4, 5-home are low-risk stock work. Items 2/3 (search + category injection) and the dynamic bindings (category id, PDP sku, customer id) are where the real work and the only real uncertainty live. None require backend dev — consistent with Matt's verdict.
Critical correctness gotchas
- PDP
sku_variable= the item'sitemid. ✅ CONFIRMED from source (athos_product_feed.jsline 38:sku: 'itemid'; CSV shows values like01666401A,01666401A-ROT). The PDP rec script must emit the viewed item'sitemid— NOT the internal id (60410), NOTrbd_item_id, NOT a matrix parent.itemidis available in the SC PDP item model. Mismatch = blank recs on every PDP. - Category
id= the category's NetSuite External ID (numeric, e.g.1191). ✅ CONFIRMED — the feed's "Category External IDs" column = saved search 988's External ID (athos_product_feed.jslines 91/197). Athos indexes on that. The category-page script must emit the External ID, NOT the category name (Emily Belle) and NOT the SC commerce-category internal id. - ⚠️ OPEN BINDING RISK: SC's front-end category model exposes the commerce-category internal id and URL fragment readily; whether it exposes the External ID client-side is unverified. If not: either add External ID to the SC category model, or re-key the feed's category column to the SC internal id. Verify before building the category binding — this is now the hardest front-end item. athos-content/athos-sidebarare destructive zones. Athos removes all existing markup inside them. Don't nest anything we need to keep (e.g., existing SC merchandising/CMS zones) inside those divs.- Kill native autocomplete. SuiteCommerce ships its own search type-ahead; if not disabled it renders over Athos Autocomplete. Applies to every form (desktop header, mobile, any hidden duplicates).
- Revert-safety is baked into the docs — new search page kept separate, old search form commented (not deleted). Honor this so a rollback is a config flip, not a redeploy.
- Logged-out shoppers — omit
customer_variableentirely; don't emitid: ''orid: 'undefined'. - 404 rec div placeholder bug — Athos's doc ships
class="ss__recs__[profile name]"on the 404 div; its selector is.ss__recs__404. Use.ss__recs__404or 404 recs never render. - Feed data gap — 29% of rows have no category. 8,237 / 28,530 feed rows have an empty "Category External IDs", systematically all
-ROT(and similar) variant SKUs — base SKU01666401Agets1191|1192, its-ROTvariant gets nothing (saved search 988 doesn't categorize variants). Effect: those products search fine but won't appear in category browsing or category-scoped recs. Feed-side fix (have variants inherit parent categories in search 988) should be decided before UAT, or category pages will look like they're "missing products."
Recommended staging sequence (build in this order)
- Theme dev branch / staging theme — isolate all changes; never touch the live theme until UAT passes.
- Add global Athos script (item 1) → verify
bundle.jsloads site-wide (Network tab, 200). - Search form rewrite (item 4) + new search results page (item 2) → first point Athos "becomes functional" per the doc (results + filters + autocomplete).
- Category pages (items 1b + 3) → verify category id resolves and filters render.
- Recommendations (item 5): Home (CMS) → PDP (dynamic sku) → Cart → 404.
- Commit to version control (action item #1 from Katie's email).
- Hand staging URL + any password to Searchspring (action item #2).
- Full UAT via Rocketlane "Complete UAT" task; log issues in "Submit Your Revisions Here" (action items #3).
- Add-to-Cart wiring — only AFTER staging integration confirmed (action item #4).
- Second revisions round → launch (action item #5).
UAT checklist (pre-handoff smoke test)
- ☐
bundle.js(atqzs8) loads with 200 on every page type - ☐ Search from header → lands on new search page,
ss-shopon<body>, Athos results + filters render - ☐ Old search page still reachable (revert path intact)
- ☐ Category page → correct products, correct filters, category id correct
- ☐ PDP → all 4 rec rows populate (bundle / cross-sell / similar / recently-viewed) — confirms sku match
- ☐ Cart → "You may also like" populates
- ☐ 404 → "More ideas" populates
- ☐ No-results page → Athos-hosted template shows
- ☐ Native SC autocomplete fully suppressed (no double dropdown)
- ☐ Logged-in vs. logged-out both behave (customer_variable present/omitted)
- ☐ Filters match feed data exactly — no duplicate/typo facets (color, designer, category)
Open questions for Cole / Matt / Athos
- ~~Search page mechanism (item 2)~~ — RESOLVED via docs (2026-06-29): the Expanded example targets stock
Facets.Browsemarkup → it's a theme template override, not a CMS page. Only remaining sub-question for Matt: how to route the new search-results URL (separate facets template + route) while leaving the old search page intact for rollback. - Head-script placement — theme template, Configuration custom-head field, or GTM? Pick the one RBD already uses for tag injection.
- ~~Feed field confirmation~~ — RESOLVED (2026-07-10) from
athos_product_feed.js+ CSV output:sku=itemid; category match value = category External ID (numeric). See gotchas #1/#2. Two follow-ons opened: (a) is the category External ID available in the SC front-end model? (gotcha #2 binding risk); (b) 29% of feed rows uncategorized — variant SKUs (gotcha #8, feed-side fix). - ~~Who does the theme dev~~ — RESOLVED (2026-07-10): Cole, guided by Claude. Claude writes setup runbook + override files; Cole runs NetSuite Sandbox auth +
gulp deploy. - ~~Staging environment~~ — RESOLVED (2026-07-10): a NetSuite Sandbox account is the first deploy target (not a staging theme on live). Code deploys to Sandbox → test on the Sandbox SC site → hand that URL to Searchspring.
Prerequisite before ANY theme code can deploy (found 2026-07-10)
There is no local SuiteCommerce Theme Developer Tools checkout — only the backend feed Suitelets exist locally. SC Standard front-end customization requires the SC Theme Developer Tools (Node/Gulp toolchain) authenticated to the Sandbox account, then clone the currently-active RBD theme to get the base templates to override (Facets.Browse.View.tpl, header search form, ProductDetails.Full.View.tpl, cart, 404). This one-time setup + the gulp deploy step need Cole's NetSuite Sandbox credentials/TBA — can't be done from this agent. Claude produces the override files + setup steps; Cole authenticates and deploys.
Status / next action
- This plan is the deliverable for the "read the docs → staging plan" step.
- Next: resolve Open Questions 1–3 (Matt + the feed), then start the staging theme at sequence step 1.
~/ai-projects/mission-control/plans/athos-frontend-integration.md