SRS: Marketing Website — Utility Suite (UC_1.9.1 – UC_1.9.4)
| Field | Value |
|---|---|
| BA in Charge / Author | Trang Nguyen / Antigravity |
| Date Created | 2026-07-26 |
| Version | v1 |
| Document References | RFQ_ Website and Dashboard Implementation V7.pdf; line 142 (Template System — "Utility Suite" row); WBS rows 28, 29, 30, 31 (UC_1.9.1–UC_1.9.4);docs/BA/UC_1.1-1.9/UC_1.9/QnA_init_docs.md (A-01..A-24); Marketing Site — CMS Editability Scope (Overall) (Ref:MKT_PRICING_DISPLAY_SCOPE); Wireframes: References/Wireframe/Marketing website/Utility Suite/ |
UC Index
| UC_ID | Use Case Name | Business Description |
|---|---|---|
| UC_1.9.1 | Privacy Policy Page | Visitor navigates to/privacy-policy → sees mandatory Privacy Policy using the Utility Suite clean text layout template. Legal content managed via Sanity CMS. |
| UC_1.9.2 | Terms of Service Page | Visitor navigates to/terms-of-service → sees mandatory Terms of Service using the Utility Suite clean text layout template. Legal content managed via Sanity CMS. |
| UC_1.9.3 | Risk Disclosure Page | Visitor navigates to/risk-disclosure → sees mandatory Risk Disclosure using the Utility Suite clean text layout template. Legal content managed via Sanity CMS. |
| UC_1.9.4 | 404 Error Page | User navigates to a non-existent route → sees custom 404 Error Page using the Utility Suite clean text layout template. Hardcoded (not Sanity-managed). |
Changelog
| Date | Version | Updated item | Before | After | Notes |
|---|---|---|---|---|---|
| 2026-07-26 | v1 | Initial creation | — | Created SRS for UC_1.9.1–UC_1.9.4 (Utility Suite: Privacy Policy, Terms of Service, Risk Disclosure, 404 Error Page) | User request 2026-07-26; ran Auditor → Challenger → Architect chain persystem_init_workflow.md |
| 2026-07-29 | v1 | UC_1.9.1/1.9.2/1.9.3 §2 Trigger, §5 Basic Flow, §8 Business Rule; UC_1.9.4 §5 Basic Flow, §10 Screen Description | Trigger/flow text had no same-tab/new-tab annotation; UC_1.9.2 Trigger listed only 2 entry points | Added "(same tab)" to all footer legal-link mentions; added BR-1.9.1-03/BR-1.9.2-04/BR-1.9.3-03 documenting link target; added UC_1.9.2 Trigger entry points (Homepage/Rules Page ToS button, Help Center ToS link, Partners form ToS/Privacy hyperlinks) with cross-refs to UC_1.8.md; added UC_1.9.1 Trigger cross-ref to Partners form Privacy Policy hyperlink; added "(same tab)" to UC_1.9.4 "Back to homepage" | User request: audit all UCs for missing same-tab/new-tab annotation and incomplete Trigger entry points |
| 2026-07-29 | v1.1 | UC_1.9.1 §2/§8 (BR-1.9.1-03), UC_1.9.2 §2/§8 (BR-1.9.2-04) | Partners Page application form's Terms of Service/Privacy Policy hyperlinks were documented as opening in a new tab, the sole exception among all other entry points | Client confirmed both hyperlinks open in the same tab, consistent with every other entry point (Global Footer, Homepage/Rules Page CTA, Help Center card); BR-1.9.1-03 and BR-1.9.2-04 updated to drop the new-tab exception; corresponding Open Notes in UC_1.8.md §5.2 item 5 and §4.8 resolved | User confirmation: "ToS/Privacy đều sẽ là same tab" |
| 2026-07-30 | v1.2 | UC_1.9.3 §1 (new scope note) | Risk Disclosure page body's "Corporate Structure and Registration" section had no documented NFA ID value | Added confirmed-content note quoting the wireframe's Section 1 text, which now shows the real NFA ID (0580183) instead of a placeholder, cross-referenced to the same confirmed value in UC_1.1.1/UC_1.3.1/UC_1.6.1 | Client confirmation (Slack, Adrian, 2026-07-30) |
| 2026-08-13 | v1.3 | Header Document References; UC Index rows 1.9.1/1.9.2/1.9.3/1.9.4; Shared Component: Utility Page Template (Content source, Last Updated indicator, Impact — content update process, new Sanity-fetch-failure bullet); UC_1.9.1/1.9.2/1.9.3 §1 Description + new CMS Editability row, §4 Post-conditions, §5 Basic Flow step 2, §7 Exceptional Flow (new E-1.9.x-01), §8 BR-…-01 + BR-…-02, §9 wireframe note, §10 items 1–2; UC_1.9.4 §1 (new hardcode scope note) | All three legal pages (Privacy Policy, Terms of Service, Risk Disclosure) were documented as hardcoded, no CMS — body copy taken from the approved wireframe and baked into the codebase (A-01, A-06, A-11), with "Last Updated" tied to the last content-changing code deploy (A-03, A-08, A-13) and every legal-copy change therefore requiring a deploy (A-24). §7 Exceptional Flow was N/A on all three. This also contradicted index.md, which already classified all three pages as Layout = Sanity / Other Content = Sanity per MKT_PRICING_DISPLAY_SCOPE | All three pages' body content is now fully configured through Sanity CMS — no hardcoded legal copy. Legal/Marketing team edits and publishes the copy in Sanity; no code deploy is required for a content change. "Last Updated" now reflects the Sanity document's last-published timestamp, not a deploy timestamp. Wireframes are demoted from "authoritative source of exact copy" to the initial content seed + layout reference; Sanity becomes the runtime source of truth for the copy. A Sanity-fetch-failure exceptional flow (ISR last-good-payload fallback) was added to each of the three UCs, mirroring the site-wide pattern in E_1.1.1.3. UC_1.9.4 (404) is explicitly NOT in scope — its illustration and message stay hardcoded per A-15/A-16, matching index.md's Hardcode row. Supersedes A-01, A-06, A-11, A-24 and the deploy-linked half of A-03/A-08/A-13 | User confirmation (BA session, 2026-08-13): "3 phần Utilities Page (Privacy Policy, Risk of Disclosure, Terms of Service) đều sẽ được config hết qua Sanity, chứ không làm hardcode nữa". Also resolves the pre-existing UC ↔ index.md conflict. ⚠️ 2 open items flagged in §Shared Component — exact Sanity schema/field names not supplied, and content-approval ownership (who may publish legal copy) not defined |
| 2026-08-13 | v1.4 | UC_1.9.4 §8 Business Rule (was N/A → 4 new BRs); §10 table (new Illustration row, CTA row extended) | UC_1.9.4 §10 cited BR-1.9.4-02 and BR-1.9.4-04, but §8 was N/A — both cross-references were dead links, so the rules they pointed to (fixed hardcoded content; homepage CTA target) existed nowhere in the document. The confirmed rules from A-15/A-16/A-17/A-18/A-20 were only implicit in §4/§5 prose, never stated as rules. §10 also had no row for the illustration despite it being a documented screen element | Wrote BR-1.9.4-01 (server must return a real HTTP 404, not a 200 soft-redirect — A-20), BR-1.9.4-02 (illustration + message are fixed hardcoded assets, explicitly excluded from the v1.3 Sanity migration — A-15/A-16), BR-1.9.4-03 (single CTA only; no search bar or suggested-links block — A-18), BR-1.9.4-04 (Back to homepage → / in the same tab, consistent with BR-1.9.1-03/BR-1.9.2-04/BR-1.9.3-03 — A-17). The two pre-existing §10 references now resolve to semantically correct rules. Added an Illustration row to §10 and a no-search-bar note to the CTA row | Follow-up fix in the same BA session (2026-08-13), user-approved. Documentation-integrity fix only — no behaviour change: all 4 rules restate answers already confirmed in QnA_init_docs.md, nothing new was invented |
Glossary
For all shared project terminology, please refer to the single source of truth: Project Glossary.
Shared Component: Utility Page Template
Per BA confirmation (A-23), UC_1.9.1, UC_1.9.2, and UC_1.9.3 share one structural layout template ("Utility Suite clean text layout," Source: RFQ_ Website and Dashboard Implementation V7.pdf; line 142). This section documents the shared layout once; each UC section below documents only the body-content specifics that differ. UC_1.9.4 (404 Error Page) reuses the same Global Header/Footer but has a structurally distinct body — it is documented separately in full under its own UC section.
- Global Header/Footer: Reused from UC_01 — Navigation & Footer (Global Layout, WBS row 2). No standalone UC_01 SRS exists yet in
docs/BA/— header dropdown menus and footer link/newsletter behavior are not re-described here; refer to WBS row 2 until a UC_01 SRS is authored. (A-04, A-09, A-14, A-19: Confirmed) - Body layout: Single continuous scroll with numbered sections. No table-of-contents / anchor-jump sidebar. (A-02, A-07, A-12: Confirmed)
- Content source — Sanity CMS (Confirmed 2026-08-13, supersedes A-01 / A-06 / A-11): The body content of all three legal pages (Privacy Policy, Terms of Service, Risk Disclosure) is configured entirely through Sanity CMS — it is not hardcoded. The Legal/Marketing team authors and publishes the copy in Sanity, and the frontend renders whatever the CMS returns. The approved wireframe for each page (see per-UC §9) remains the initial content seed and the layout reference — it defines the section structure, numbering, and the first published version of the copy — but once published, Sanity is the runtime source of truth for the text. Where a specific legal value is separately confirmed elsewhere (e.g., the NFA ID
0580183in UC_1.9.3 §1), the Sanity content must carry that same confirmed value. - Last Updated indicator: Each page displays a "Last Updated" date/time. This value is system-generated from the real timestamp of the last content change — it is not the current date on every page load. Following the Sanity migration, that timestamp is the Sanity document's last-published timestamp, no longer the timestamp of a code deploy. (A-03, A-08, A-13: Confirmed for the "real timestamp of last content change" principle; the deploy-linkage half is superseded by the 2026-08-13 confirmation.)
- Impact — Content update process (supersedes A-24): A legal-copy change (e.g., a regulatory update to the Risk Disclosure text) is now performed by editing and publishing the document in Sanity — no code deploy is required. QC should verify that (a) a Sanity publish is reflected on the live page without any deployment, and (b) the "Last Updated" value moves in lockstep with the Sanity publish. Only structural/layout changes to the template itself still require a deploy.
- Sanity fetch failure: These pages are CMS-driven, so a Sanity API failure/timeout on page load is now a real scenario. Behaviour follows the site-wide pattern already documented for CMS-driven content: Next.js falls back to the last successfully cached ISR payload, so the visitor still sees the page in full — only the newest unpublished changes are missing (Ref: E_1.1.1.3). Documented per-UC as E-1.9.1-01 / E-1.9.2-01 / E-1.9.3-01.
- Not in scope — UC_1.9.4 (404 Error Page): The 404 page's illustration and message remain hardcoded static assets (A-15, A-16: Confirmed) and are unaffected by this migration, consistent with the
Hardcodeclassification for the 404 Error Page in the CMS Editability Scope table.
⚠️ Open items (flagged, not assumed) — raised 2026-08-13:
- Sanity schema not supplied. The exact document type / field names / field types for the three legal documents (e.g., a single rich-text/Portable Text body vs. a repeatable array of numbered sections, and how the "Last Updated" value is exposed) have not been specified by the client or FE team. Per the project's existing practice for Sanity migrations (Ref: CR-20260731-001, CR-20260731-002), this SRS documents the behaviour without inventing a schema. To be confirmed with the FE team.
- Publishing authority undefined. No approval/permission rule was given for who may publish legal copy in Sanity. Because a Sanity publish now pushes legal text live with no deploy gate, the previous implicit review checkpoint (code review + deploy) disappears. Whether a Compliance/Legal sign-off step or a restricted Sanity role is required is an open question for the client — compare BR_1.6.1.1/BR_1.6.1.2, where the About Us NFA credential card was deliberately kept hardcoded so that a change requires deploy + Compliance review.
UC_1.9.1 — Privacy Policy Page
1. Overview
| Field | Content |
|---|---|
| ID | UC_1.9.1 |
| Use Case | Privacy Policy Page |
| Description | Visitor navigates to/privacy-policy and sees the mandatory Privacy Policy page, built on the shared Utility Page Template (see above). Body content is legal text managed via Sanity CMS (Confirmed 2026-08-13 — no longer hardcoded). |
| Zapier Flow | - |
| Zapier Table | - |
| Related WBS Row | 28 |
| 3rd Party | Sanity CMS (page body content + Last Updated timestamp) |
| CMS Editability | Privacy Policy row in Marketing Site — CMS Editability Scope (Overall): Layout = Sanity; Other Content = Sanity; Pricing Data / FAQ / Insight Hub / Mode Waitlist = N/A. |
2. Trigger
The visitor navigates to the /privacy-policy route — either by direct URL entry, or by clicking a "Privacy" link in the Global Layout footer (UC_01) (same tab). It can also be reached by clicking the Privacy Policy hyperlink in the Partners Page application form's compliance checkbox (Ref: UC_1.8.7 §5.2 item 5) (same tab).
3. Pre-conditions
- The visitor is on any page of the marketing website (or arrives directly via URL/external link).
4. Post-conditions
- The Privacy Policy page is rendered with the currently published Sanity legal content and its associated "Last Updated" timestamp.
5. Basic Flow
- The visitor clicks the "Privacy Policy" link in the Global Footer (UC_01) (same tab) — or navigates directly to
/privacy-policy. - The system fetches the Privacy Policy document from Sanity CMS and displays the full page: Global Header (UC_01) + body content (numbered legal sections, single continuous scroll, rendered from the published Sanity content — see §9) + "Last Updated" timestamp (reflecting the Sanity document's last-published timestamp) + Global Footer (UC_01).
6. Alternative Flow
- N/A
7. Exceptional Flow
| ID | Scenario | Condition | System Behaviour |
|---|---|---|---|
| E-1.9.1-01 | Sanity CMS Fetch Failure (Privacy Policy body) | The page body is CMS-driven (Ref: BR-1.9.1-01). The Sanity API fails or times out on page load. | Next.js falls back to the last successfully cached ISR payload, so the visitor still sees the complete Privacy Policy — only changes published after that cached version are missing. The page must never render empty or partial legal text. Mirrors the site-wide CMS-failure pattern (Ref: E_1.1.1.3). |
8. Business Rule
BR-1.9.1-01: Content Source and Editability — Sanity CMS
The Privacy Policy body content is configured and published through Sanity CMS; it is not hardcoded and does not require a code deploy to change. The approved wireframe (§9) supplies the initial content and the section structure, but the published Sanity document is the runtime source of truth for the copy. (Source: User confirmation, BA session 2026-08-13 — supersedes A-01/A-06/A-11 and aligns with the Privacy Policy row in the CMS Editability Scope table. Shared rule, identical to UC_1.9.2 BR-1.9.2-01 and UC_1.9.3 BR-1.9.3-01)
BR-1.9.1-02: Last Updated Timestamp
The "Last Updated" date/time shown on the page reflects the real system timestamp of the most recent content change — i.e., the Sanity document's last-published timestamp — and is not the page-load date. (Source: A-03, A-08, A-13 for the principle; deploy-linkage superseded by the 2026-08-13 Sanity confirmation — shared rule, identical to UC_1.9.2 BR-1.9.2-02 and UC_1.9.3 BR-1.9.3-02)
BR-1.9.1-03: Link Target — Same Tab
Every entry point to this page opens in the same browser tab: the footer "Privacy Policy" link (UC_01), consistent with the other Global Footer legal links (Ref: UC_1.1.1), and the Partners Page application form's Privacy Policy hyperlink (Ref: UC_1.8.7 §5.2 item 5).
9. Wireframe / UI
- Screen: Privacy Policy — Utility Page Template_Privacy Policy.png
Note: this wireframe file is the layout reference and the source of the initial legal copy and section numbering (A-01). Once published, the Sanity document is the runtime source of truth for the text (Ref: BR-1.9.1-01). This SRS does not reproduce the full legal text inline.
10. Screen Description and Business Rules
| No. | Field Name | Field Type | Validation Rule / Behaviour |
|---|---|---|---|
| 1 | Page Body (Privacy Policy text) | Label (Sanity-driven) | Display rule:- Read-only to the visitor; rendered in numbered sections, single continuous scroll.- Content is fetched from the published Sanity document and rendered as-is — editable via Sanity CMS, no code deploy needed (Ref: BR-1.9.1-01). Initial content/section numbering per the approved wireframe (Ref: §9 above).- Overflow: Wrap text (no truncation; full legal text always fully visible via normal page scroll).Failure: Sanity unreachable → last cached ISR payload (Ref: E-1.9.1-01). |
| 2 | Last Updated | Label | Display rule:- Displays the real system timestamp of the most recent content change — the Sanity document's last-published timestamp (Ref: BR-1.9.1-02).- Not tied to page-load date.Impact: A change to the legal body text is made by publishing in Sanity (no deploy); the displayed timestamp must update to match that publish (Ref: BR-1.9.1-01). |
END OF UC_1.9.1
UC_1.9.2 — Terms of Service Page
1. Overview
| Field | Content |
|---|---|
| ID | UC_1.9.2 |
| Use Case | Terms of Service Page |
| Description | Visitor navigates to/terms-of-service and sees the mandatory Terms of Service page, built on the shared Utility Page Template (see above). Body content is legal text managed via Sanity CMS (Confirmed 2026-08-13 — no longer hardcoded). |
| Zapier Flow | - |
| Zapier Table | - |
| Related WBS Row | 29 |
| 3rd Party | Sanity CMS (page body content + Last Updated timestamp) |
| CMS Editability | Terms of Service row in Marketing Site — CMS Editability Scope (Overall): Layout = Sanity; Other Content = Sanity; Pricing Data / FAQ / Insight Hub / Mode Waitlist = N/A. |
⚠️ Scope note (A-10, Confirmed): This page (
/terms-of-service) is a different document from the "Terms of Service for the Data Processing and Performance Evaluation Service (Associate Track)" consent text shown inside the checkout flow (seedashboard_v7_full.txt, Step 5 checkout consent checkbox — UC_49 territory). The two must not be conflated; this UC covers only the public/termsmarketing page.
2. Trigger
The visitor navigates to the /terms-of-service route — either by direct URL entry, or by clicking a "Terms of Service" link in the Global Layout footer (UC_01) (same tab). Other entry points that route to this same page (all same tab): the Read the Full Terms & Conditions button on the Homepage (Ref: UC_1.3.1 §5) and on The Rules Page (Ref: UC_1.8.1 §5 item 6 / BR_1.8.1.5); the "Terms of Service" link on the Help Center's "Still Have a Question?" card (Ref: UC_1.8.8 §4.8); and the Terms of Service hyperlink in the Partners Page application form's compliance checkbox (Ref: UC_1.8.7 §5.2 item 5).
3. Pre-conditions
- The visitor is on any page of the marketing website (or arrives directly via URL/external link).
4. Post-conditions
- The Terms of Service page is rendered with the currently published Sanity legal content and its associated "Last Updated" timestamp.
5. Basic Flow
- The visitor clicks the "Terms of Service" link in the Global Footer (UC_01) (same tab) — or navigates directly to
/terms-of-service. - The system fetches the Terms of Service document from Sanity CMS and displays the full page: Global Header (UC_01) + body content (numbered legal sections, single continuous scroll, rendered from the published Sanity content — see §9) + "Last Updated" timestamp (reflecting the Sanity document's last-published timestamp) + Global Footer (UC_01).
6. Alternative Flow
- N/A
7. Exceptional Flow
| ID | Scenario | Condition | System Behaviour |
|---|---|---|---|
| E-1.9.2-01 | Sanity CMS Fetch Failure (Terms of Service body) | The page body is CMS-driven (Ref: BR-1.9.2-01). The Sanity API fails or times out on page load. | Next.js falls back to the last successfully cached ISR payload, so the visitor still sees the complete Terms of Service — only changes published after that cached version are missing. The page must never render empty or partial legal text. Mirrors the site-wide CMS-failure pattern (Ref: E_1.1.1.3). |
8. Business Rule
BR-1.9.2-01: Content Source and Editability — Sanity CMS
(Identical to UC_1.9.1 BR-1.9.1-01 — shared rule.) The Terms of Service body content is configured and published through Sanity CMS; it is not hardcoded and does not require a code deploy to change. The approved wireframe (§9) supplies the initial content and section structure; the published Sanity document is the runtime source of truth. (Source: User confirmation, BA session 2026-08-13 — supersedes A-06)
BR-1.9.2-02: Last Updated Timestamp
(Identical to UC_1.9.1 BR-1.9.1-02 — shared rule.) The "Last Updated" date/time shown on the page reflects the real system timestamp of the most recent content change — the Sanity document's last-published timestamp. (Source: A-08 for the principle; deploy-linkage superseded 2026-08-13)
BR-1.9.2-03: Document Identity — Distinct from Checkout ToS
The /terms-of-service page is a distinct legal document from the "Terms of Service for the Data Processing and Performance Evaluation Service (Associate Track)" consent shown during checkout. The two documents are managed and versioned independently; a change to one does not imply a change to the other. (Source: A-10, Confirmed) The 2026-08-13 Sanity migration (BR-1.9.2-01) applies only to this public /terms-of-service page — it makes no statement about how the checkout consent text is stored or maintained (UC_49 territory).
BR-1.9.2-04: Link Target — Same Tab for All Entry Points
The footer "Terms of Service" link (UC_01), the Homepage/Rules Page Read the Full Terms & Conditions button, the Help Center "Terms of Service" link (Ref: UC_1.8.8 §4.8), and the Partners Page application form's Terms of Service hyperlink (Ref: UC_1.8.7 §5.2 item 5) all navigate to /terms-of-service in the same tab.
9. Wireframe / UI
- Screen: Terms of Service — Utility Page Template_Terms of Services.png
Note: this wireframe file is the layout reference and the source of the initial legal copy and section numbering (A-06). Once published, the Sanity document is the runtime source of truth for the text (Ref: BR-1.9.2-01).
10. Screen Description and Business Rules
| No. | Field Name | Field Type | Validation Rule / Behaviour |
|---|---|---|---|
| 1 | Page Body (Terms of Service text) | Label (Sanity-driven) | Display rule:- Read-only to the visitor; rendered in numbered sections, single continuous scroll.- Content is fetched from the published Sanity document and rendered as-is — editable via Sanity CMS, no code deploy needed (Ref: BR-1.9.2-01). Initial content/section numbering per the approved wireframe (Ref: §9 above).- Overflow: Wrap text (no truncation; full legal text always fully visible via normal page scroll).Failure: Sanity unreachable → last cached ISR payload (Ref: E-1.9.2-01). |
| 2 | Last Updated | Label | Display rule:- Displays the real system timestamp of the most recent content change — the Sanity document's last-published timestamp (Ref: BR-1.9.2-02).- Not tied to page-load date.Impact: A change to the legal body text is made by publishing in Sanity (no deploy); the displayed timestamp must update to match that publish (Ref: BR-1.9.2-01). |
END OF UC_1.9.2
UC_1.9.3 — Risk Disclosure Page
1. Overview
| Field | Content |
|---|---|
| ID | UC_1.9.3 |
| Use Case | Risk Disclosure Page |
| Description | Visitor navigates to/risk-disclosure and sees the mandatory Risk Disclosure page, built on the shared Utility Page Template (see above). Body content is legal text managed via Sanity CMS (Confirmed 2026-08-13 — no longer hardcoded). |
| Zapier Flow | - |
| Zapier Table | - |
| Related WBS Row | 30 |
| 3rd Party | Sanity CMS (page body content + Last Updated timestamp) |
| CMS Editability | Risk Disclosure row in Marketing Site — CMS Editability Scope (Overall): Layout = Sanity; Other Content = Sanity; Pricing Data / FAQ / Insight Hub / Mode Waitlist = N/A. |
⚠️ Scope note (A-11, Confirmed): The legally-required performance-disclosure snippet used inside the checkout flow ("HYPOTHETICAL OR SIMULATED PERFORMANCE RESULTS HAVE CERTAIN LIMITATIONS...",
dashboard_v7_full.txtStep 5) is treated as a separate checkout-only item and is not assumed to be part of this page's body — the wireframe (§9) is the sole authoritative source for this page's content.⚠️ Confirmed content note (2026-07-30): Per the approved wireframe's Section 1 "Corporate Structure and Registration," the page body confirms the real NFA ID (no longer a placeholder): "Stack Trading Brokerage LLC, a subsidiary of Stack Trading C Corp, is a registered Introducing Broker with the Commodity Futures Trading Commission (CFTC) and a Member of the National Futures Association (NFA ID: 0580183). Stack Trading Brokerage LLC introduces live trading accounts to registered Futures Commission Merchants (FCMs) for execution and clearing." This is the same confirmed NFA ID used consistently across the Marketing Site Footer (UC_1.1.1 §6), Homepage (UC_1.3.1 §5), and About Us (UC_1.6.1 §3 item 6) (Source: Client Slack confirmation, Adrian, 2026-07-30).
⚠️ Consistency risk after the Sanity migration (2026-08-13): this Section 1 text now lives in Sanity and is editable without a deploy (Ref: BR-1.9.3-01), whereas the same NFA ID on the Footer, Homepage, and About Us credential card is hardcoded (Ref: BR_1.6.1.1). There is no automatic sync between the two, so a Sanity edit here could silently diverge from the hardcoded value elsewhere. QC should treat the NFA ID as a cross-page consistency check; whoever edits this section in Sanity must keep the value identical to
0580183unless the hardcoded occurrences are changed in the same release.
2. Trigger
The visitor navigates to the /risk-disclosure route — either by direct URL entry, or by clicking a "Risk Disclosure" link in the Global Layout footer (UC_01) (same tab).
3. Pre-conditions
- The visitor is on any page of the marketing website (or arrives directly via URL/external link).
4. Post-conditions
- The Risk Disclosure page is rendered with the currently published Sanity legal content and its associated "Last Updated" timestamp.
5. Basic Flow
- The visitor clicks the "Risk Disclosure" link in the Global Footer (UC_01) (same tab) — or navigates directly to
/risk-disclosure. - The system fetches the Risk Disclosure document from Sanity CMS and displays the full page: Global Header (UC_01) + body content (numbered legal sections, single continuous scroll, rendered from the published Sanity content — see §9) + "Last Updated" timestamp (reflecting the Sanity document's last-published timestamp) + Global Footer (UC_01).
6. Alternative Flow
- N/A
7. Exceptional Flow
| ID | Scenario | Condition | System Behaviour |
|---|---|---|---|
| E-1.9.3-01 | Sanity CMS Fetch Failure (Risk Disclosure body) | The page body is CMS-driven (Ref: BR-1.9.3-01). The Sanity API fails or times out on page load. | Next.js falls back to the last successfully cached ISR payload, so the visitor still sees the complete Risk Disclosure — only changes published after that cached version are missing. The page must never render empty or partial legal text; this page carries regulatory disclosures, so a blank body is treated as a compliance-impacting defect. Mirrors the site-wide CMS-failure pattern (Ref: E_1.1.1.3). |
8. Business Rule
BR-1.9.3-01: Content Source and Editability — Sanity CMS
(Identical to UC_1.9.1 BR-1.9.1-01 — shared rule.) The Risk Disclosure body content is configured and published through Sanity CMS; it is not hardcoded and does not require a code deploy to change. The approved wireframe (§9) supplies the initial content and section structure; the published Sanity document is the runtime source of truth. The Sanity content must preserve the confirmed regulatory values quoted in §1 (notably NFA ID 0580183). (Source: User confirmation, BA session 2026-08-13 — supersedes A-11)
BR-1.9.3-02: Last Updated Timestamp
(Identical to UC_1.9.1 BR-1.9.1-02 — shared rule.) The "Last Updated" date/time shown on the page reflects the real system timestamp of the most recent content change — the Sanity document's last-published timestamp. (Source: A-13 for the principle; deploy-linkage superseded 2026-08-13)
BR-1.9.3-03: Link Target — Same Tab
The footer "Risk Disclosure" link (UC_01) is internal navigation and opens in the same browser tab, consistent with the other Global Footer legal links (Ref: UC_1.1.1).
9. Wireframe / UI
- Screen: Risk Disclosure — Utility Page Template_Risk Disclosures.png
Note: this wireframe file is the layout reference and the source of the initial legal copy and section numbering (A-11). Once published, the Sanity document is the runtime source of truth for the text (Ref: BR-1.9.3-01).
10. Screen Description and Business Rules
| No. | Field Name | Field Type | Validation Rule / Behaviour |
|---|---|---|---|
| 1 | Page Body (Risk Disclosure text) | Label (Sanity-driven) | Display rule:- Read-only to the visitor; rendered in numbered sections, single continuous scroll.- Content is fetched from the published Sanity document and rendered as-is — editable via Sanity CMS, no code deploy needed (Ref: BR-1.9.3-01). Initial content/section numbering per the approved wireframe (Ref: §9 above); Section 1 must keep the confirmed NFA ID 0580183 (Ref: §1 consistency note).- Overflow: Wrap text (no truncation; full legal text always fully visible via normal page scroll).Failure: Sanity unreachable → last cached ISR payload (Ref: E-1.9.3-01). |
| 2 | Last Updated | Label | Display rule:- Displays the real system timestamp of the most recent content change — the Sanity document's last-published timestamp (Ref: BR-1.9.3-02).- Not tied to page-load date.Impact: A change to the legal body text is made by publishing in Sanity (no deploy); the displayed timestamp must update to match that publish (Ref: BR-1.9.3-01). |
END OF UC_1.9.3
UC_1.9.4 — 404 Error Page
1. Overview
| Field | Content |
|---|---|
| ID | UC_1.9.4 |
| Use Case | 404 Error Page |
| Description | User navigates to a non-existent route and sees a custom 404 Error Page, reusing the Global Header/Footer (UC_01) but with a structurally distinct body (custom illustration + message + single CTA), built on the shared Utility Page Template family. |
| Zapier Flow | - |
| Zapier Table | - |
| Related WBS Row | 31 |
| 3rd Party | - |
| CMS Editability | 404 Error Page row in Marketing Site — CMS Editability Scope (Overall): Layout = Hardcode; all other columns = N/A. |
⚠️ Scope note (Confirmed 2026-08-13): The Sanity migration of the three legal pages (UC_1.9.1/1.9.2/1.9.3) does not apply to this page. The 404 illustration and message remain hardcoded static assets (A-15, A-16: Confirmed) — changing them still requires a code deploy.
2. Trigger
The user navigates (via direct URL entry, stale/broken link, or typo) to a route that does not resolve to any defined page on the marketing website.
3. Pre-conditions
- The requested route does not match any defined route in the marketing website.
4. Post-conditions
- The 404 Error Page is rendered with the fixed illustration, heading/body text, and "Back to homepage" CTA.
- The server responds with an actual HTTP 404 status code (not a 200 status with a soft-redirect), consistent with standard SEO/technical practice for error pages.
5. Basic Flow
- The user's browser requests a non-existent route on the marketing website.
- The system displays the full 404 Error Page: Global Header (UC_01) + the fixed illustration + message "404 - Page not found or has been removed." (hardcoded per the approved wireframe — see §9) + the "Back to homepage" button + Global Footer (UC_01).
- [If the user clicks "Back to homepage"] → the system navigates the user to the site homepage (
/) (same tab).
6. Alternative Flow
- N/A
7. Exceptional Flow
- N/A
8. Business Rule
BR-1.9.4-01: HTTP Status Code
When a visitor requests a route that does not resolve to any defined page, the server responds with an actual HTTP 404 status code while rendering this page. It must not be a 200 response or a soft-redirect to a /404 route — the status code is an SEO/indexing requirement, not a UI concern. (Source: A-20, Confirmed)
BR-1.9.4-02: Fixed Content — Hardcoded, Not CMS-Managed
The 404 page's illustration and message text are fixed static assets hardcoded in the codebase, exactly as shown in the approved wireframe (§9): the illustration is a fixed image and the message is the fixed string 404 - Page not found or has been removed. Neither is editable via Sanity CMS — changing either requires a code deploy. This page is explicitly excluded from the 2026-08-13 Sanity migration that applies to UC_1.9.1/1.9.2/1.9.3 (Ref: §1 Scope note; Hardcode row for the 404 Error Page in the CMS Editability Scope table). (Source: A-15, A-16, Confirmed; scope boundary confirmed by user, BA session 2026-08-13)
BR-1.9.4-03: Single CTA Only — No Search or Suggested Links
The 404 page body contains exactly one CTA (Back to homepage). It does not include a search bar, a "suggested links"/"popular pages" block, or any other recovery mechanism. (Source: A-18, Confirmed)
BR-1.9.4-04: Back to Homepage — Destination and Link Target
The Back to homepage button navigates to the site homepage (/) in the same browser tab, consistent with all other internal navigation across the Utility Suite (Ref: BR-1.9.1-03, BR-1.9.2-04, BR-1.9.3-03). (Source: A-17, Confirmed)
9. Wireframe / UI
- Screen: 404 Error Page — 404 Not Found.png
Note: this wireframe file is the authoritative source for the exact illustration and text (A-15, A-16).
10. Screen Description and Business Rules
| No. | Field Name | Field Type | Validation Rule / Behaviour |
|---|---|---|---|
| 1 | Illustration | Image | Display rule:- Fixed static asset exactly as shown in the approved wireframe (Ref: §9 above).- Hardcoded — not editable via CMS. (Ref: BR-1.9.4-02) |
| 2 | Error Message | Label | Display rule:- Fixed text: 404 - Page not found or has been removed.- Read-only, hardcoded. (Ref: BR-1.9.4-02)- Overflow: Wrap text. |
| 3 | Back to homepage | Button (Primary) | Display rule:- Label: Back to homepage.- Single CTA on the page; no search bar or suggested-links block (Ref: BR-1.9.4-03).Behaviour:- On click: navigates the user to the site homepage (/) in the same tab. (Ref: BR-1.9.4-04) |
END OF UC_1.9.4