diff --git a/frontend/src/__tests__/lib/epcis-upload.test.ts b/frontend/src/__tests__/lib/epcis-upload.test.ts index 799d71410..816779618 100644 --- a/frontend/src/__tests__/lib/epcis-upload.test.ts +++ b/frontend/src/__tests__/lib/epcis-upload.test.ts @@ -82,6 +82,6 @@ describe('epcisErrorMessage', () => { it('falls back to the error message and then to a default', () => { expect(epcisErrorMessage(new Error('Network Error'))).toBe('Network Error'); - expect(epcisErrorMessage(null)).toBe('EPCIS upload failed'); + expect(epcisErrorMessage(null)).toBe('EPCIS upload (Preview) failed'); }); }); diff --git a/frontend/src/__tests__/pages/homepage.test.tsx b/frontend/src/__tests__/pages/homepage.test.tsx index f75a5b2c4..a0044f6fa 100644 --- a/frontend/src/__tests__/pages/homepage.test.tsx +++ b/frontend/src/__tests__/pages/homepage.test.tsx @@ -13,7 +13,7 @@ describe("HomePage Compliance OS foundation", () => { }), ).toBeInTheDocument(); expect( - screen.getByText(/ingest supply-chain data through webhooks, csv, epcis, or edi/i), + screen.getByText(/send records by csv upload or the json events api\. epcis 2\.0 is in preview\./i), ).toBeInTheDocument(); }); diff --git a/frontend/src/app/about/page.tsx b/frontend/src/app/about/page.tsx index 3b8ebb178..f6cbf25ed 100644 --- a/frontend/src/app/about/page.tsx +++ b/frontend/src/app/about/page.tsx @@ -22,7 +22,7 @@ import { Card } from "@/components/ui/card"; export const metadata: Metadata = { title: "About RegEngine | FSMA 204 Compliance Infrastructure", description: - "RegEngine was built by Christopher Sellers — AmeriCorps alum, former Senate staffer, and solo technical founder — to make FSMA 204 compliance accessible to mid-market food companies without six-figure platforms.", + "RegEngine was built by Christopher Sellers (AmeriCorps alum, former Senate staffer, and solo technical founder) to make FSMA 204 compliance accessible to mid-market food companies without six-figure platforms.", openGraph: { title: "About RegEngine | FSMA 204 Compliance Infrastructure", description: @@ -103,7 +103,7 @@ export default function AboutPage() { description={ <> RegEngine is FSMA 204 compliance infrastructure built for mid-market - food companies—by someone who saw the gap from inside government, + food companies, by someone who saw the gap from inside government, enterprise sales, and the regulatory stack itself. } @@ -135,8 +135,8 @@ export default function AboutPage() { 204 compliance tools priced for enterprises, sold through six-month procurement cycles, and designed for teams with dedicated compliance departments. The companies that actually - needed help—regional distributors, mid-size processors, - growing food brands—were stuck choosing between + needed help (regional distributors, mid-size processors, + growing food brands) were stuck choosing between spreadsheets and software they couldn't afford.

@@ -186,7 +186,7 @@ export default function AboutPage() {

RegEngine is built by one person leveraging modern AI tooling as - a development multiplier. This isn't a limitation—it's + a development multiplier. This isn't a limitation; it's a feature.

@@ -258,7 +258,7 @@ export default function AboutPage() {

Book a free gap analysis call. We'll review your current FSMA 204 posture, identify coverage gaps, and show you exactly what RegEngine - handles—no commitment required. + handles. No commitment required.

@@ -202,7 +202,7 @@ export default function FDAFoodTraceabilityRequirements() { ))}

- Not every CTE applies to every business — you only record CTEs that occur at your operation. A farm typically records Harvesting and Cooling (§1.1325) and possibly Initial Packing (§1.1330). A manufacturer records Receiving (§1.1345), Transformation (§1.1350), and Shipping (§1.1340). A seafood receiver from a fishing vessel records First Land-Based Receiving (§1.1335) — non-seafood importers record Receiving instead. Use RegEngine's CTE Mapper to walk through which CTEs apply to your role. + Not every CTE applies to every business; you only record CTEs that occur at your operation. A farm typically records Harvesting and Cooling (§1.1325) and possibly Initial Packing (§1.1330). A manufacturer records Receiving (§1.1345), Transformation (§1.1350), and Shipping (§1.1340). A seafood receiver from a fishing vessel records First Land-Based Receiving (§1.1335). Non-seafood importers record Receiving instead. Use RegEngine's CTE Mapper to walk through which CTEs apply to your role.

diff --git a/frontend/src/app/blog/food-traceability-software/page.tsx b/frontend/src/app/blog/food-traceability-software/page.tsx index ec1131292..bdd315334 100644 --- a/frontend/src/app/blog/food-traceability-software/page.tsx +++ b/frontend/src/app/blog/food-traceability-software/page.tsx @@ -53,7 +53,7 @@ export default function FoodTraceabilitySoftwarePage() {

The Selection Challenge

- Food traceability software ranges from basic Excel-based tracking to enterprise-grade platforms with automated supply chain visibility. Some vendors pitch themselves as FSMA 204 specialists. Others are generic supply chain tools retrofitted with compliance features. Many promise integration with your ERP—until you learn the integration costs $50K+ and takes six months. + Food traceability software ranges from basic Excel-based tracking to enterprise-grade platforms with automated supply chain visibility. Some vendors pitch themselves as FSMA 204 specialists. Others are generic supply chain tools retrofitted with compliance features. Many promise integration with your ERP, until you learn the integration costs $50K+ and takes six months.

The problem: most vendor comparison tools are written by vendors. They highlight features that make their product look best, not features that matter most for FDA's July 2028 enforcement date or your budget. @@ -120,7 +120,7 @@ export default function FoodTraceabilitySoftwarePage() {

2. Integration: Will It Connect to Your Existing Systems?

- A food traceability platform doesn't live in isolation. It needs to pull data from your ERP, WMS, inventory system, or supplier networks—and push compliance data to FDA systems, retailers, or auditors. + A food traceability platform doesn't live in isolation. It needs to pull data from your ERP, WMS, inventory system, or supplier networks, and push compliance data to FDA systems, retailers, or auditors.

@@ -128,11 +128,11 @@ export default function FoodTraceabilitySoftwarePage() {

Tier 1: Native Connectors (Low Cost)

-

Pre-built integrations to popular ERPs (SAP, NetSuite, Salesforce). Usually $0–$5K setup, 2–4 weeks implementation.

+

Pre-built integrations to popular ERPs (SAP, NetSuite, Salesforce). Usually $0 to $5K setup, 2 to 4 weeks implementation.

Tier 2: API-Based Integration (Medium Cost)

-

RESTful or SOAP APIs requiring custom development. $10K–$30K, 4–8 weeks. Your IT team or a consultant builds the bridge.

+

RESTful or SOAP APIs requiring custom development. $10K to $30K, 4 to 8 weeks. Your IT team or a consultant builds the bridge.

Tier 3: Manual Data Entry or Middleware (High Cost)

@@ -159,7 +159,7 @@ export default function FoodTraceabilitySoftwarePage() {

3. Compliance Feature Depth: Does It Enforce FSMA 204 Requirements?

- Not all platforms enforce FSMA 204 compliance equally. Some are passive trackers—they record what you tell them to record. Better platforms actively enforce data validation, deviation tracking, and 24-hour response requirements. + Not all platforms enforce FSMA 204 compliance equally. Some are passive trackers: they record what you tell them to record. Better platforms actively enforce data validation, deviation tracking, and 24-hour response requirements.

@@ -209,11 +209,11 @@ export default function FoodTraceabilitySoftwarePage() {
  • Setup & Onboarding - Configuration, data migration, user training: $5K–$50K depending on platform and complexity. + Configuration, data migration, user training: $5K to $50K depending on platform and complexity.
  • Integration Development - Connecting to your ERP or supplier systems: $10K–$100K+ if custom development is required. + Connecting to your ERP or supplier systems: $10K to $100K+ if custom development is required.
  • Per-User or Per-Transaction Fees @@ -221,7 +221,7 @@ export default function FoodTraceabilitySoftwarePage() {
  • Custom Development & Support - Premium support tiers, custom reporting, or feature development: $100–$500/hour or flat retainers. + Premium support tiers, custom reporting, or feature development: $100 to $500/hour or flat retainers.
  • Data Storage & Archival @@ -245,12 +245,12 @@ export default function FoodTraceabilitySoftwarePage() {
  • Improved supplier relationships and transparency

- If the platform saves your team 5–10 hours/week in compliance work, that alone justifies the cost. + If the platform saves your team 5 to 10 hours/week in compliance work, that alone justifies the cost.

- Request a detailed cost breakdown from every vendor. Ask for references—especially from companies of similar size—and ask them directly about hidden costs. + Request a detailed cost breakdown from every vendor. Ask for references (especially from companies of similar size) and ask them directly about hidden costs.

@@ -272,7 +272,7 @@ export default function FoodTraceabilitySoftwarePage() {
  • 2.
    -

    Shortlist 3–5 Vendors

    +

    Shortlist 3 to 5 Vendors

    Request demos focused on your specific use cases, not generic feature tours.

  • @@ -287,7 +287,7 @@ export default function FoodTraceabilitySoftwarePage() { 4.

    Contact References

    -

    Speak to 2–3 companies using each platform. Ask about implementation reality vs. promises, hidden costs, and support quality.

    +

    Speak to 2 or 3 companies using each platform. Ask about implementation reality vs. promises, hidden costs, and support quality.

  • @@ -317,7 +317,7 @@ export default function FoodTraceabilitySoftwarePage() {
  • diff --git a/frontend/src/app/blog/fsma-204-compliance-checklist-2026/page.tsx b/frontend/src/app/blog/fsma-204-compliance-checklist-2026/page.tsx index 17109ff19..f12753ffb 100644 --- a/frontend/src/app/blog/fsma-204-compliance-checklist-2026/page.tsx +++ b/frontend/src/app/blog/fsma-204-compliance-checklist-2026/page.tsx @@ -69,7 +69,7 @@ export default function FSMA204ComplianceChecklist() { { task: 'Document your supply chain', detail: 'List all suppliers, distributors, and customers. Where does data flow today?', done: false }, { task: 'Assess your IT systems', detail: 'What ERP, WMS, or other systems do you use? Can they be integrated with a traceability platform?', done: false }, { task: 'Estimate implementation cost and timeline', detail: 'Get quotes from 2-3 FSMA 204 platform vendors. Build a budget for 2026-2027', done: false }, - { task: 'Assign a compliance lead', detail: 'Designate one person to own FSMA 204 implementation. This is a significant role—don\'t dilute it', done: false }, + { task: 'Assign a compliance lead', detail: 'Designate one person to own FSMA 204 implementation. This is a significant role, so don\'t dilute it', done: false }, ].map((item, idx) => (
    diff --git a/frontend/src/app/blog/fsma-204-compliance-guide/page.tsx b/frontend/src/app/blog/fsma-204-compliance-guide/page.tsx index 2fdaca063..f2eeab7f3 100644 --- a/frontend/src/app/blog/fsma-204-compliance-guide/page.tsx +++ b/frontend/src/app/blog/fsma-204-compliance-guide/page.tsx @@ -60,7 +60,7 @@ export default function FSMA204ComplianceGuide() { What Is FSMA 204?

    - FSMA 204 is the FDA's Food Traceability Rule. It requires covered food businesses to keep records identifying the immediate previous sources and immediate recipients of their products. When the FDA needs your traceability data—due to a foodborne illness outbreak, contamination, or suspected intentional adulteration—you have 24 hours to provide it. + FSMA 204 is the FDA's Food Traceability Rule. It requires covered food businesses to keep records identifying the immediate previous sources and immediate recipients of their products. When the FDA needs your traceability data (due to a foodborne illness outbreak, contamination, or suspected intentional adulteration), you have 24 hours to provide it.

    The rule applies to foods specifically listed on the FDA's Food Traceability List (FTL), including leafy greens, berry crops, bivalve mollusks, soft cheeses, and more. If your business handles an FTL product, FSMA 204 traceability obligations may apply. @@ -119,27 +119,27 @@ export default function FSMA204ComplianceGuide() {

    @@ -247,7 +247,7 @@ export default function FSMA204ComplianceGuide() { 2. Standardize Your Traceability Lot Code

    - Implement a consistent, unique TLC format across your supply chain. This doesn't need to be complex—it just needs to identify the product, lot, and date. Work with your suppliers and customers to ensure compatibility. + Implement a consistent, unique TLC format across your supply chain. This doesn't need to be complex. It just needs to identify the product, lot, and date. Work with your suppliers and customers to ensure compatibility.

    @@ -296,7 +296,7 @@ export default function FSMA204ComplianceGuide() {
  • @@ -333,7 +333,7 @@ export default function FSMA204MidMarketGuide() {
  • - An audit trail and chained hashing won't certify your data is correct — only your operation can do that — but they make it materially easier to show how a record was entered, by whom, and whether it changed after ingest. A standalone spreadsheet generally cannot. + An audit trail and chained hashing won't certify your data is correct (only your operation can do that), but they make it materially easier to show how a record was entered, by whom, and whether it changed after ingest. A standalone spreadsheet generally cannot.

    @@ -114,9 +114,9 @@ export default function RegEngineVsSpreadsheets() {
    • • People forget to fill in fields or enter them incorrectly
    • -
    • • Date and time formats vary—is that 3/5 or 5/3?
    • +
    • • Date and time formats vary: is that 3/5 or 5/3?
    • • Typos in supplier or customer names break traceability links
    • -
    • • No validation—data that doesn't make sense (e.g., receiving before shipping) is accepted
    • +
    • • No validation: data that doesn't make sense (e.g., receiving before shipping) is accepted
    • • At 100+ transactions per day, error rates are significant
    @@ -242,7 +242,7 @@ export default function RegEngineVsSpreadsheets() {
  • • Suppliers filling out templates incorrectly
  • • You manually entering supplier data into your spreadsheet
  • • No visibility into what's missing until you need it
  • -
  • • Supplier compliance is low—they don't see why it matters
  • +
  • • Supplier compliance is low because they don't see why it matters
  • @@ -253,7 +253,7 @@ export default function RegEngineVsSpreadsheets() {
    • • Supplier portal: suppliers log in and submit traceability data directly
    • -
    • • Simple templates: no expertise needed—suppliers fill in basic fields
    • +
    • • Simple templates: no expertise needed, since suppliers fill in basic fields
    • • Automatic validation: the system checks data before it's submitted
    • • Real-time visibility: you see what you're missing and who hasn't responded
    • • Fewer support emails: suppliers get instant feedback on what's needed
    • @@ -276,7 +276,7 @@ export default function RegEngineVsSpreadsheets() { Spreadsheet Total Cost of Ownership

      - Illustrative line items, not a forecast — model your own operation against your actual labor and recall-history baseline. + Illustrative line items, not a forecast. Model your own operation against your actual labor and recall-history baseline.

      • • Staff time to maintain spreadsheets and reconcile lot codes
      • @@ -292,11 +292,11 @@ export default function RegEngineVsSpreadsheets() { RegEngine Total Cost of Ownership
          -
        • • RegEngine subscription (priced against volume — contact us for a quote)
        • +
        • • RegEngine subscription (priced against volume; contact us for a quote)
        • • One-time implementation and team onboarding
        • • Less staff time spent on manual reconciliation once ingestion is wired in
        • • Pre-formatted §1.1455(c) export rather than ad-hoc preparation
        • -
        • • Audit trail and chained hashing to support — not replace — your compliance program
        • +
        • • Audit trail and chained hashing to support, not replace, your compliance program
    @@ -349,7 +349,7 @@ export default function RegEngineVsSpreadsheets() {
    • • FTL by that date; other products ASAP

    - We do not make you Walmart-ready, transmit ASN on Retail Link, certify labels, or assess chargebacks. EDI 856 / ASN mapping is scoped work. + We do not make you Walmart-ready, transmit ASN on Retail Link, certify labels, or assess chargebacks.

    @@ -137,7 +137,7 @@ export default function BuyerProgramsPage() {
  • • Advisory coverage/completeness checklist
  • • Append-only commit
  • • FDA-oriented sortable spreadsheet
  • -
  • • EPCIS/CSV where enabled
  • +
  • • CSV upload, JSON events API (EPCIS export)
  • • Hash manifest re-checkable at /verify
  • diff --git a/frontend/src/app/case-studies/page.tsx b/frontend/src/app/case-studies/page.tsx index 890547a3e..324e1e589 100644 --- a/frontend/src/app/case-studies/page.tsx +++ b/frontend/src/app/case-studies/page.tsx @@ -74,7 +74,7 @@ const NORMALIZATION_EXAMPLES = [ }, ]; -/** Identifiers and sample values are recorded data — mono, on the inset well. */ +/** Identifiers and sample values are recorded data - mono, on the inset well. */ const chipClass = 'rounded-sm bg-re-surface-inset px-1.5 py-0.5 font-mono text-[0.8125rem] text-re-text-primary'; const cellClass = 'px-4 py-3 align-middle text-re-text-secondary'; const headClass = 'px-4 py-3 text-left align-middle text-label text-re-text-tertiary'; @@ -103,12 +103,12 @@ export default function CaseStudy() { Product validation · synthetic data modeled on industry patterns. Not a named-customer case study.

    - These metrics are reproducible — try the same recall drill at{' '} + These metrics are reproducible. Try the same recall drill at{' '} /proof/recall-drill.

    - We ran a synthetic validation workflow modeled on leafy-greens supply chains — from Salinas Valley - harvest to grocery DC receiving — and measured every step. These are not customer ROI, SLA, + We ran a synthetic validation workflow modeled on leafy-greens supply chains (from Salinas Valley + harvest to grocery DC receiving) and measured every step. These are not customer ROI, SLA, or production-performance commitments.

    @@ -314,7 +314,7 @@ export default function CaseStudy() {

    OCR artifacts where O/0 or I/1 swap could change lot identity. - System flags but doesn't auto-correct — lot codes are too critical. + System flags but doesn't auto-correct, because lot codes are too critical.

    @@ -324,7 +324,7 @@ export default function CaseStudy() {

    Records where a required field (e.g., origin location) was blank. - Cannot be inferred — requires source data correction. + Cannot be inferred; requires source data correction.

    @@ -347,7 +347,7 @@ export default function CaseStudy() {

    We intentionally don't auto-correct lot codes. A wrong lot code - in an FDA trace means tracing the wrong product — the cost of + in an FDA trace means tracing the wrong product, and the cost of a false positive exceeds the cost of a human review. @@ -486,7 +486,7 @@ export default function CaseStudy() { }, { title: 'Short Shelf Life', - description: '7-14 day product life means recall speed is existential. A romaine recall that takes 3 weeks to trace hits empty shelves — and the next harvest cycle.', + description: '7-14 day product life means recall speed is existential. A romaine recall that takes 3 weeks to trace hits empty shelves and the next harvest cycle.', metric: '< 1 second full trace latency', }, { @@ -534,7 +534,7 @@ export default function CaseStudy() {

    Run This Validation on Your Data

    Upload a sample CSV. See your auto-normalization rate, KDE completeness score, - and time to FDA-oriented sortable export — measured on your actual supply chain data. + and time to FDA-oriented sortable export, measured on your actual supply chain data.

    diff --git a/frontend/src/app/compliance/traceability-plan/page.tsx b/frontend/src/app/compliance/traceability-plan/page.tsx index 2e7475e01..3bce508fb 100644 --- a/frontend/src/app/compliance/traceability-plan/page.tsx +++ b/frontend/src/app/compliance/traceability-plan/page.tsx @@ -195,7 +195,7 @@ export default function TraceabilityPlanPage() {
    diff --git a/frontend/src/app/dashboard/compliance/page.tsx b/frontend/src/app/dashboard/compliance/page.tsx index 2bd2458c6..e19b9b195 100644 --- a/frontend/src/app/dashboard/compliance/page.tsx +++ b/frontend/src/app/dashboard/compliance/page.tsx @@ -33,6 +33,7 @@ import { useAuth } from '@/lib/auth-context'; import { useTenant } from '@/lib/tenant-context'; import { fetchComplianceScore, fetchWorkbenchReadinessSummary } from '@/lib/api-hooks'; import { experimentalFeaturesEnabled, filterExperimentalLinks } from '@/lib/experimental-features'; +import { NO_DATA_YET } from '@/lib/empty-values'; /* ── Types matching ComplianceScoreResponse from backend ── */ @@ -79,7 +80,7 @@ function scoreColor(score: number) { return 'var(--re-danger)'; } -/** For DOM nodes — a class keeps the colour out of an inline style (SPEC §4). */ +/** For DOM nodes - a class keeps the colour out of an inline style (SPEC §4). */ function scoreTextClass(score: number) { if (score >= 80) return 'text-re-brand'; if (score >= 60) return 'text-re-warning'; @@ -102,20 +103,20 @@ const STATUS_CONFIG = { 'compliant': { icon: Shield, label: 'FSMA 204 Ready', - desc: "Your traceability data meets RegEngine's readiness checks — an advisory indicator, not a legal determination.", + desc: "Your traceability data meets RegEngine's readiness checks. This is an advisory indicator, not a legal determination.", bg: 'bg-re-brand-muted border-re-brand/30', text: 'text-re-brand', }, 'at-risk': { icon: ShieldAlert, - label: 'At Risk — Action Needed', + label: 'At Risk: Action Needed', desc: 'Gaps in your traceability data could cause issues during an FDA inspection.', bg: 'bg-re-warning-muted0/10 border-re-warning/30', text: 'text-re-warning', }, 'critical': { icon: ShieldX, - label: 'Critical — Not Compliant', + label: 'Critical: Not Compliant', desc: 'Significant gaps exist. Prioritize the actions below before your next audit.', bg: 'bg-re-danger-muted0/10 border-re-danger/30', text: 'text-re-danger', @@ -531,7 +532,7 @@ export default function ComplianceDashboardPage() {
    - {workbenchSummary?.score ?? '—'} + {workbenchSummary?.score ?? NO_DATA_YET}

    {workbenchSummary?.label ?? 'No saved preflight run yet'} @@ -777,7 +778,7 @@ export default function ComplianceDashboardPage() { )} - {/* Empty state — no score and not loading */} + {/* Empty state - no score and not loading */} {!score && !loading && !error && isLoggedIn && ( { throw new Error( - 'Export job scheduling is not yet available — records remain exportable on demand.', + 'Export job scheduling is not yet available. Records remain exportable on demand.', ); }, }); @@ -131,7 +131,7 @@ export default function ExportJobsPage() { icon={Link2Off} title={"Scheduled export jobs aren't available on this workspace yet."} > - Recurring archive scheduling is still in development — no amount of connected data unlocks it today. Your records stay exportable on demand from FDA Export, and this page will activate when scheduling ships. + Recurring archive scheduling is still in development. No amount of connected data unlocks it today. Your records stay exportable on demand from FDA Export, and this page will activate when scheduling ships. ) : ( diff --git a/frontend/src/app/dashboard/heartbeat/page.tsx b/frontend/src/app/dashboard/heartbeat/page.tsx index 74e8e016a..90007beed 100644 --- a/frontend/src/app/dashboard/heartbeat/page.tsx +++ b/frontend/src/app/dashboard/heartbeat/page.tsx @@ -37,6 +37,7 @@ import { FileText, ShieldCheck, } from 'lucide-react'; +import { NO_DATA_YET } from '@/lib/empty-values'; // ── Types ── @@ -503,7 +504,7 @@ function HeartbeatPageContent() {

    -

    {error} — showing cached data if available.

    +

    {error}. Showing cached data if available.

    @@ -680,13 +681,13 @@ function HeartbeatPageContent() { = 80 ? 'good' : 'warn'} /> 0 ? 'good' : 'neutral'} /> inflow_lab'], ['Dashboard source', 'Tagged as Inflow Lab'], ]; @@ -100,7 +100,7 @@ const ROUTE_GUIDANCE = [ }, { title: 'Inflow Lab', - description: 'Run FSMA event simulations and webhook replay without mixing test traffic into normal imports.', + description: 'Run FSMA event simulations and event replay without mixing test traffic into normal imports.', href: '/dashboard/inflow-lab', icon: FlaskConical, }, @@ -431,7 +431,7 @@ export default function DashboardIntegrationsPage() { loading={profilesStatus === 'loading'} >

    - Reusable mappings for CSV, spreadsheet, API, EDI-style, and supplier portal feeds. + Reusable mappings for CSV, spreadsheet, API, and supplier portal feeds.

    - - + diff --git a/frontend/src/app/dashboard/issues/page.tsx b/frontend/src/app/dashboard/issues/page.tsx index bc61539af..aa1b2761e 100644 --- a/frontend/src/app/dashboard/issues/page.tsx +++ b/frontend/src/app/dashboard/issues/page.tsx @@ -27,6 +27,7 @@ import { import { useAuth } from '@/lib/auth-context'; import { fetchWithCsrf } from '@/lib/fetch-with-csrf'; import { useTenant } from '@/lib/tenant-context'; +import { NOT_SET } from '@/lib/empty-values'; /* ── Types ── */ @@ -172,7 +173,7 @@ export default function IssuesPage() { header: 'Case', cell: (c) => ( - {c.requesting_party} — {c.scope_description || c.package_status} + {c.requesting_party}: {c.scope_description || c.package_status} ), }, @@ -224,7 +225,7 @@ export default function IssuesPage() { header: 'Citation', width: '12rem', mono: true, - cell: (b) => b.citation ?? '—', + cell: (b) => b.citation ?? NOT_SET, }, ]; @@ -232,7 +233,7 @@ export default function IssuesPage() { 0 && (

    - Blocking Defects — Must Fix Before Submission + Blocking Defects: Must Fix Before Submission

    0 && ( - Warnings — Non-Blocking + Warnings (Non-Blocking)
      diff --git a/frontend/src/app/dashboard/layout.tsx b/frontend/src/app/dashboard/layout.tsx index aaf3fe664..be73786f2 100644 --- a/frontend/src/app/dashboard/layout.tsx +++ b/frontend/src/app/dashboard/layout.tsx @@ -153,7 +153,7 @@ const COLLAPSIBLE_SECTIONS: CollapsibleSection[] = [ }, ]; -/** Mobile nav — the 5 always-visible items only */ +/** Mobile nav - the 5 always-visible items only */ const MOBILE_NAV_ITEMS = TOP_ITEMS; function isNavItemVisible(item: NavItem, isSysadmin: boolean): boolean { @@ -183,7 +183,7 @@ function saveExpandedSections(state: Record) { try { localStorage.setItem(STORAGE_KEY, JSON.stringify(state)); } catch { - // silent – quota exceeded, private browsing, etc. + // silent - quota exceeded, private browsing, etc. } } @@ -301,7 +301,7 @@ function CollapsibleNavSection({ return (
      - {/* Section header — clickable toggle */} + {/* Section header - clickable toggle */}
      {/* Nav sections */} - {/* MEDIUM #12: Keyboard navigation — arrow keys traverse nav items */} + {/* MEDIUM #12: Keyboard navigation - arrow keys traverse nav items */}
    diff --git a/frontend/src/app/dashboard/receiving/page.tsx b/frontend/src/app/dashboard/receiving/page.tsx index 871c56713..0fcd19d80 100644 --- a/frontend/src/app/dashboard/receiving/page.tsx +++ b/frontend/src/app/dashboard/receiving/page.tsx @@ -30,6 +30,7 @@ import { useToast } from '@/components/ui/use-toast'; import { parseGS1 } from '@/lib/gs1-parser'; import { scanMatchesItem } from '@/lib/scan-match'; import { notifyDashboardRefresh } from '@/hooks/use-dashboard-refresh'; +import { NOT_SET } from '@/lib/empty-values'; /* ─── Types ─── */ interface LineItem { @@ -65,9 +66,9 @@ const EXPECTED_FIELD_HINTS: readonly (readonly [string, string])[] = [ ]; const RECEIPT_COLUMNS: DataTableColumn[] = [ - { key: 'productName', header: 'Product', cell: (item) => item.productName || '—' }, - { key: 'gtin', header: 'Barcode', mono: true, cell: (item) => item.gtin || '—' }, - { key: 'lotCode', header: 'Lot', mono: true, cell: (item) => item.lotCode || '—' }, + { key: 'productName', header: 'Product', cell: (item) => item.productName || NOT_SET }, + { key: 'gtin', header: 'Barcode', mono: true, cell: (item) => item.gtin || NOT_SET }, + { key: 'lotCode', header: 'Lot', mono: true, cell: (item) => item.lotCode || NOT_SET }, { key: 'quantity', header: 'Qty', align: 'right', cell: (item) => item.quantity }, ]; @@ -124,7 +125,7 @@ export default function ReceivingDockPage() { const scannedGtin = parsed.gtin || ''; const scannedLot = parsed.tlc || ''; // The input invites typing a bare GTIN or lot code, but parseGS1 only - // extracts values from AI-encoded / Digital Link strings — so a user + // extracts values from AI-encoded / Digital Link strings - so a user // typing exactly what the Expected Items list displays never matched // and every scan landed in Unexpected Items. scanMatchesItem also // compares the raw string directly (matrix unit-tested in @@ -149,7 +150,7 @@ export default function ReceivingDockPage() { } if (!matched) { - // Unexpected scan — add to unexpected list + // Unexpected scan - add to unexpected list updated.unexpectedScans.push({ id: `unx-${Date.now()}`, gtin: scannedGtin, @@ -278,7 +279,7 @@ export default function ReceivingDockPage() { /* ─── Render ─── */ return ( - {/* Back link — the shell owns the breadcrumb; this stays as the + {/* Back link - the shell owns the breadcrumb; this stays as the dock's own return affordance. */}
    diff --git a/frontend/src/app/dashboard/scan/page.tsx b/frontend/src/app/dashboard/scan/page.tsx index cb93551ef..9ff06e0cc 100644 --- a/frontend/src/app/dashboard/scan/page.tsx +++ b/frontend/src/app/dashboard/scan/page.tsx @@ -22,7 +22,7 @@ import { } from 'lucide-react'; /* ------------------------------------------------------------------ */ -/* QR Code generator — renders inline SVG via the `qrcode` package */ +/* QR Code generator - renders inline SVG via the `qrcode` package */ /* ------------------------------------------------------------------ */ let qrcodeLib: typeof import('qrcode') | null = null; const SAFE_SCAN_TENANT_ID = /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/; @@ -60,7 +60,7 @@ function useQRCodeSvgDataUrl(text: string) { } /* ------------------------------------------------------------------ */ -/* Detect viewport — show scanner on mobile, QR share on desktop */ +/* Detect viewport - show scanner on mobile, QR share on desktop */ /* ------------------------------------------------------------------ */ const MOBILE_MEDIA_QUERY = '(max-width: 768px)'; @@ -90,7 +90,7 @@ const HOW_IT_WORKS = [ { step: '2', title: 'Select event type & scan item', - detail: 'Choose what you\'re doing: Receiving, Shipping, or Transforming. Point your camera at the barcode — product number, lot code, expiry, and serial are extracted automatically.', + detail: 'Choose what you\'re doing: Receiving, Shipping, or Transforming. Point your camera at the barcode; product number, lot code, expiry, and serial are extracted automatically.', }, { step: '3', @@ -195,7 +195,7 @@ function ScanPageContent() {

    - Display this QR code on a tablet or print it. Floor operators scan it with their phone to open the capture tool — no app install required. + Display this QR code on a tablet or print it. Floor operators scan it with their phone to open the capture tool. No app install required.

    {/* QR Code */} @@ -282,7 +282,7 @@ function ScanPageContent() { ))}

    - Barcodes are parsed automatically — product number, lot code, serial, expiry, and pack date are extracted and mapped to the required data fields. + Barcodes are parsed automatically: product number, lot code, serial, expiry, and pack date are extracted and mapped to the required data fields.

    diff --git a/frontend/src/app/dashboard/settings/page.tsx b/frontend/src/app/dashboard/settings/page.tsx index 3faf2f70b..c653229e4 100644 --- a/frontend/src/app/dashboard/settings/page.tsx +++ b/frontend/src/app/dashboard/settings/page.tsx @@ -39,7 +39,7 @@ const ACCOUNT_LINKS = [ ]; /* ── Available Integrations Catalog ── */ -// Integration catalog — status is updated from API if available +// Integration catalog - status is updated from API if available const INTEGRATIONS = [ { id: 'sensitech', name: 'Sensitech TempTale', category: 'IoT', status: 'available', desc: 'Cold-chain temperature monitoring' }, { id: 'tive', name: 'Tive Trackers', category: 'IoT', status: 'available', desc: 'Real-time shipment visibility' }, @@ -47,8 +47,8 @@ const INTEGRATIONS = [ { id: 'netsuite', name: 'Oracle NetSuite', category: 'ERP', status: 'available', desc: 'Cloud ERP and financials' }, { id: 'walmart', name: 'Walmart GDSN', category: 'Retailer', status: 'coming_soon', desc: 'Global Data Synchronization' }, { id: 'kroger', name: 'Kroger 84.51\u00b0', category: 'Retailer', status: 'coming_soon', desc: 'Retailer data exchange' }, - { id: 'epcis', name: 'EPCIS 2.0 Gateway', category: 'Standards', status: 'available', desc: 'GS1 event format bridge' }, - { id: 'webhook', name: 'Custom Webhooks', category: 'Custom', status: 'available', desc: 'Push events to your endpoints' }, + { id: 'epcis', name: 'EPCIS 2.0 Gateway', category: 'Standards', status: 'epcis_preview', desc: 'GS1 event format bridge; ingest in Preview' }, + { id: 'webhook', name: 'Custom Webhooks', category: 'Custom', status: 'preview', desc: 'Push events to your endpoints' }, ]; /** * Integration status. `state` promotes the operational statuses to the @@ -61,6 +61,8 @@ const STATUS_CONFIG: Record available: { label: 'Available' }, disconnected: { label: 'Available' }, coming_soon: { label: 'Coming Soon' }, + preview: { label: 'Preview / contact us' }, + epcis_preview: { label: 'Preview' }, }; const TABS = [ @@ -226,7 +228,7 @@ export default function SettingsPage() { return ( {/* The dashboard shell owns the breadcrumb and the service-health - badge — this page only renders its own header. */} + badge: this page only renders its own header. */} setProfile({ ...profile, fei_number: e.target.value })} - placeholder="Optional — used in FDA exports" + placeholder="Optional, used in FDA exports" /> diff --git a/frontend/src/app/dashboard/suppliers/page.tsx b/frontend/src/app/dashboard/suppliers/page.tsx index e69fe7c9c..95aee7ecc 100644 --- a/frontend/src/app/dashboard/suppliers/page.tsx +++ b/frontend/src/app/dashboard/suppliers/page.tsx @@ -333,7 +333,7 @@ export default function SupplierDashboardPage() { setInviteSupplierEmail(''); setInviteProfileId(''); setShowInviteForm(false); - // Auto-copy the link — best-effort only. clipboard.writeText + // Auto-copy the link - best-effort only. clipboard.writeText // rejects whenever the document is unfocused or permission is // denied; sharing the API call's catch made a SUCCESSFUL link // creation render as "Unable to create portal link", inviting @@ -478,7 +478,7 @@ export default function SupplierDashboardPage() {
    - {workbenchSummary?.score ?? '—'} + {workbenchSummary?.score ?? NO_DATA_YET}
    Inflow Workbench readiness
    @@ -506,7 +506,7 @@ export default function SupplierDashboardPage() { - {/* Portal Links — Invite Suppliers */} + {/* Portal Links - Invite Suppliers */}
    @@ -822,7 +822,7 @@ export default function SupplierDashboardPage() { )} - {/* Facility List — hairline ledger rows */} + {/* Facility List - hairline ledger rows */} {!loading && facilities.length > 0 && ( - {/* — CTA — */} + {/* - CTA - */}

    @@ -454,13 +454,13 @@ export default async function CTELandingPage({

    Upload a sample {data.name.toLowerCase()} file to the RegEngine - sandbox and get an instant validation report — free, no signup + sandbox and get an instant validation report. Free, no signup required.

    @@ -471,7 +471,7 @@ export default async function CTELandingPage({
    - {/* — OTHER CTEs NAV — */} + {/* - OTHER CTEs NAV - */}

    Other Critical Tracking Events diff --git a/frontend/src/app/fsma-204/page.tsx b/frontend/src/app/fsma-204/page.tsx index eb144f70a..3b8e9a9e8 100644 --- a/frontend/src/app/fsma-204/page.tsx +++ b/frontend/src/app/fsma-204/page.tsx @@ -9,11 +9,11 @@ import { Callout } from "@/components/ui/callout"; import { Card } from "@/components/ui/card"; export const metadata: Metadata = { - title: "FSMA 204 Compliance Guide — What Your Farm Needs to Know | RegEngine", + title: "FSMA 204 Compliance Guide: What Your Farm Needs to Know | RegEngine", description: - "Plain-English guide to the FDA Food Traceability Rule. Learn what FSMA 204 requires, whether your products are covered, and how to get compliant — no developer needed.", + "Plain-English guide to the FDA Food Traceability Rule. Learn what FSMA 204 requires, whether your products are covered, and how to get compliant. No developer needed.", openGraph: { - title: 'FSMA 204 Compliance Guide — What Your Farm Needs to Know', + title: 'FSMA 204 Compliance Guide: What Your Farm Needs to Know', description: 'Plain-English guide to the FDA Food Traceability Rule: what it requires, whether your products are covered, and how to comply.', url: 'https://regengine.co/fsma-204', type: 'article', @@ -57,7 +57,7 @@ const CTES_PLAIN = [ name: "First Land-Based Receiving", icon: Anchor, who: "Receivers of seafood from a fishing vessel", - what: "Per §1.1330: record when seafood was received from a fishing vessel, the lot code, the harvest and landing location, and the receiving facility — distinct from generic imported-food entry.", + what: "Under §1.1335, record when seafood was received from a fishing vessel, the lot code, the harvest and landing location, and the receiving facility. This is distinct from generic imported-food entry.", }, { name: "Shipping", @@ -88,19 +88,19 @@ const STEPS = [ { num: "2", title: "Upload your data", - desc: "Download our CSV or Excel template, fill in your lot codes, locations, and dates. Upload it to RegEngine. No code, no API — just a spreadsheet.", + desc: "Download our CSV or Excel template, fill in your lot codes, locations, and dates. Upload it to RegEngine. No code, no API, just a spreadsheet.", cta: { label: "Download Templates", href: "/onboarding/bulk-upload" }, }, { num: "3", title: "RegEngine maps your events", - desc: "We map your data to the 7 Critical Tracking Events defined in the FSMA 204 rule — harvesting, cooling, initial packing, first land-based receiving, shipping, receiving, and transformation. You only record the events that occur at your operation. The dashboard shows what’s covered and what’s missing.", + desc: "We map your data to the 7 Critical Tracking Events defined in the FSMA 204 rule: harvesting, cooling, initial packing, first land-based receiving, shipping, receiving, and transformation. You only record the events that occur at your operation. The dashboard shows what’s covered and what’s missing.", cta: null, }, { num: "4", title: "Be ready when they ask", - desc: "When the FDA or a retailer requests traceability records, RegEngine produces a sortable electronic spreadsheet structured to FDA's §1.1455 format — populated from the lot codes, dates, and locations you've uploaded. Compliance remains your operation's legal responsibility.", + desc: "When the FDA or a retailer requests traceability records, RegEngine produces a sortable electronic spreadsheet structured to FDA's §1.1455 format, populated from the lot codes, dates, and locations you've uploaded. Compliance remains your operation's legal responsibility.", cta: null, }, ]; @@ -118,7 +118,7 @@ const FAQS = [ }, { q: "I don’t have a developer or IT person. Can I still use RegEngine?", - a: "Yes. You can upload your data using our CSV or Excel templates — no code required. Download the template, fill in your lot codes and dates, and upload. RegEngine handles the rest.", + a: "Yes. You can upload your data using our CSV or Excel templates, with no code required. Download the template, fill in your lot codes and dates, and upload. RegEngine handles the rest.", }, { q: "What if I already track this in spreadsheets?", @@ -130,7 +130,7 @@ const FAQS = [ }, { q: "What happens if I’m not compliant by July 2028?", - a: "FDA enforcement under §1.1455 focuses on producing the required records on request. Beyond direct enforcement, major retailers may drop non-compliant suppliers — the bigger risk for most farms is losing a key retail customer over missing traceability data.", + a: "FDA enforcement under §1.1455 focuses on producing the required records on request. Beyond direct enforcement, major retailers may drop non-compliant suppliers. The bigger risk for most farms is losing a key retail customer over missing traceability data.", }, { q: "How much does this cost?", @@ -145,12 +145,12 @@ const FAQS = [ export default function FSMA204BusinessGuidePage() { return (

    - {/* — HERO — */} + {/* - HERO - */} @@ -177,7 +177,7 @@ export default function FSMA204BusinessGuidePage() { className="border-b-0 pb-0" /> - {/* — KEY FACTS STRIP — */} + {/* - KEY FACTS STRIP - */}
      {KEY_FACTS.map((fact) => (
    • @@ -188,11 +188,11 @@ export default function FSMA204BusinessGuidePage() {
    - {/* — WHAT IS FSMA 204 — */} + {/* - WHAT IS FSMA 204 - */}

    - The FDA's Food Safety Modernization Act Section 204 — commonly called “FSMA 204” or the “Food Traceability Rule” — requires anyone who grows, receives, ships, or transforms certain high-risk foods to keep detailed traceability records. + The FDA's Food Safety Modernization Act Section 204 (commonly called “FSMA 204” or the “Food Traceability Rule”) requires anyone who grows, receives, ships, or transforms certain high-risk foods to keep detailed traceability records.

    The goal is simple: when a foodborne illness outbreak happens, FDA can request your traceability records and you must produce a sortable electronic spreadsheet within 24 hours. Before this rule, that process could take weeks. @@ -204,14 +204,14 @@ export default function FSMA204BusinessGuidePage() { {/* Enforcement callout */} -

    The deadline moved — the rule didn't.

    +

    The deadline moved. The rule didn't.

    - Congress directed FDA not to enforce before July 2028, but major retailers have published supplier traceability programs that pre-date the federal enforcement date. If you sell to a major retailer, check your supplier portal — your effective deadline may already have passed. + Congress directed FDA not to enforce before July 2028, but major retailers have published supplier traceability programs that pre-date the federal enforcement date. If you sell to a major retailer, check your supplier portal: your effective deadline may already have passed.

    - {/* — ARE YOUR PRODUCTS COVERED? — */} + {/* - ARE YOUR PRODUCTS COVERED? - */}
    - {/* — WHAT YOU HAVE TO RECORD — */} + {/* - WHAT YOU HAVE TO RECORD - */}
    - {/* — THE 24-HOUR RULE — */} + {/* - THE 24-HOUR RULE - */}
    - {/* — HOW TO COMPLY — */} + {/* - HOW TO COMPLY - */}
    - {/* — FAQ — */} + {/* - FAQ - */}
    {FAQS.map((faq) => ( @@ -340,7 +340,7 @@ export default function FSMA204BusinessGuidePage() {
    - {/* — FINAL CTA — */} + {/* - FINAL CTA - */}

    @@ -350,7 +350,7 @@ export default function FSMA204BusinessGuidePage() { Don't wait for the deadline.

    - Start with a free tool. See where you stand. Get compliant on your schedule — not the FDA's. + Start with a free tool. See where you stand. Get compliant on your schedule, not the FDA's.