Skip to content
Merged
2 changes: 1 addition & 1 deletion frontend/src/__tests__/lib/epcis-upload.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');
});
});
2 changes: 1 addition & 1 deletion frontend/src/__tests__/pages/homepage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});

Expand Down
12 changes: 6 additions & 6 deletions frontend/src/app/about/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -103,7 +103,7 @@ export default function AboutPage() {
description={
<>
RegEngine is FSMA 204 compliance infrastructure built for mid-market
food companies&mdash;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.
</>
}
Expand Down Expand Up @@ -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&mdash;regional distributors, mid-size processors,
growing food brands&mdash;were stuck choosing between
needed help (regional distributors, mid-size processors,
growing food brands) were stuck choosing between
spreadsheets and software they couldn&apos;t afford.
</p>
<p className="mt-3 max-w-[68ch] text-ui text-re-text-secondary">
Expand Down Expand Up @@ -186,7 +186,7 @@ export default function AboutPage() {
</h2>
<p className="mt-2 max-w-[68ch] text-ui text-re-text-secondary">
RegEngine is built by one person leveraging modern AI tooling as
a development multiplier. This isn&apos;t a limitation&mdash;it&apos;s
a development multiplier. This isn&apos;t a limitation; it&apos;s
a feature.
</p>
</div>
Expand Down Expand Up @@ -258,7 +258,7 @@ export default function AboutPage() {
<p className="mx-auto mt-4 max-w-[48ch] text-body text-re-text-secondary">
Book a free gap analysis call. We&apos;ll review your current FSMA 204
posture, identify coverage gaps, and show you exactly what RegEngine
handles&mdash;no commitment required.
handles. No commitment required.
</p>
<div className="mt-8 flex flex-wrap justify-center gap-3">
<Button asChild size="lg">
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/app/accept-invite/AcceptInviteClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,12 @@ export default function AcceptInvitePage() {
return (
<AuthShell
title="Welcome aboard"
description="Your account is ready. We'll email you a sign-in code when you log in — no password needed."
description="Your account is ready. We'll email you a sign-in code when you log in. No password needed."
>
<div role="status" className="space-y-4">
<p className="sr-only">
Your account is ready. We&apos;ll email you a sign-in code when you
log in — no password needed.
log in. No password needed.
</p>
<Button
className="w-full"
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/api/admin/[...path]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ function getAdminTargets(): string[] {

if (candidates.length === 0 && runningOnVercel) {
console.error(
'[proxy/admin] No admin backend URL configured — set NEXT_PUBLIC_ADMIN_URL, NEXT_PUBLIC_API_BASE_URL, or ADMIN_SERVICE_URL',
'[proxy/admin] No admin backend URL configured; set NEXT_PUBLIC_ADMIN_URL, NEXT_PUBLIC_API_BASE_URL, or ADMIN_SERVICE_URL',
);
}

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/api/compliance/[...path]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function getComplianceUrl(): string {
// Guard: *.railway.internal URLs are unreachable from Vercel serverless
const onVercel = Boolean(process.env.VERCEL || process.env.VERCEL_URL);
if (onVercel && url.includes('.railway.internal')) {
console.warn('[proxy/compliance] COMPLIANCE_SERVICE_URL points to internal Railway URL — unreachable from Vercel. Set a public Railway URL.');
console.warn('[proxy/compliance] COMPLIANCE_SERVICE_URL points to internal Railway URL; unreachable from Vercel. Set a public Railway URL.');
return getServerServiceURL('compliance'); // Will fail with a clear connection error
}
return url;
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/api/controls/[...path]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const ADMIN_URL = (() => {
const url = process.env.ADMIN_SERVICE_URL || getServerServiceURL('admin');
const onVercel = Boolean(process.env.VERCEL || process.env.VERCEL_URL);
if (onVercel && url.includes('.railway.internal')) {
console.warn('[proxy/controls] ADMIN_SERVICE_URL points to internal Railway URL — unreachable from Vercel.');
console.warn('[proxy/controls] ADMIN_SERVICE_URL points to internal Railway URL; unreachable from Vercel.');
return getServerServiceURL('admin');
}
return url;
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/app/api/fsma/[...path]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { applyCookieCredentials, createJsonProxy, passthroughRequestHeaders } fr
// :62 metrics_router prefix="/fsma/metrics" -> /api/v1/fsma/metrics/*
// :63 compliance_router prefix="/fsma/compliance" -> /api/v1/fsma/compliance/*
//
// `gaps` and `export/` are NOT top-level FSMA routes — they are endpoints on
// `gaps` and `export/` are NOT top-level FSMA routes - they are endpoints on
// the compliance sub-router (services/graph/app/routers/fsma/compliance.py):
// :640 @router.get("/gaps") -> /api/v1/fsma/compliance/gaps
// :681 @router.get("/gaps/orphans") -> /api/v1/fsma/compliance/gaps/orphans
Expand All @@ -32,7 +32,7 @@ import { applyCookieCredentials, createJsonProxy, passthroughRequestHeaders } fr
// entry pointed at /api/v1/fsma/drift/* which has never existed. Do not add
// it back without a real backend router to point it at.
//
// Compliance service — services/compliance/app/routes.py:64 declares
// Compliance service - services/compliance/app/routes.py:64 declares
// `APIRouter(tags=["fsma-compliance"])` with NO prefix, and server/main.py:929
// mounts it with no prefix either (`app.include_router(fsma_router, ...)`), so
// its routes are /industries, /checklists, /checklists/{id} and
Expand All @@ -46,13 +46,13 @@ function guardUrl(envVar: string, fallback: string): string {
const onVercel = Boolean(process.env.VERCEL || process.env.VERCEL_URL);
if (url) {
if (onVercel && url.includes('.railway.internal')) {
console.warn(`[proxy/fsma] ${envVar} points to internal Railway URL — unreachable from Vercel.`);
console.warn(`[proxy/fsma] ${envVar} points to internal Railway URL; unreachable from Vercel.`);
return '';
}
return url;
}
if (onVercel) {
console.error(`[proxy/fsma] ${envVar} not configured — localhost is unreachable from Vercel`);
console.error(`[proxy/fsma] ${envVar} not configured; localhost is unreachable from Vercel`);
return '';
}
return fallback;
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/api/graph/[...path]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function getGraphUrl(): string {
// Guard: *.railway.internal URLs are unreachable from Vercel serverless
const onVercel = Boolean(process.env.VERCEL || process.env.VERCEL_URL);
if (onVercel && url.includes('.railway.internal')) {
console.warn('[proxy/graph] GRAPH_SERVICE_URL points to internal Railway URL — unreachable from Vercel. Set a public Railway URL.');
console.warn('[proxy/graph] GRAPH_SERVICE_URL points to internal Railway URL; unreachable from Vercel. Set a public Railway URL.');
return getServerServiceURL('graph');
}
return url;
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/app/api/ingestion/[...path]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function getIngestionTargets(): string[] {
candidates.push(productionUrl);
} else if (runningOnVercel) {
console.error(
'[proxy/ingestion] No ingestion backend URL configured — set NEXT_PUBLIC_INGESTION_URL, INGESTION_SERVICE_URL, or INGESTION_PRODUCTION_URL',
'[proxy/ingestion] No ingestion backend URL configured; set NEXT_PUBLIC_INGESTION_URL, INGESTION_SERVICE_URL, or INGESTION_PRODUCTION_URL',
);
} else {
candidates.push(DEFAULT_INGESTION_URL);
Expand Down Expand Up @@ -93,7 +93,7 @@ const { GET, POST, PUT, PATCH, DELETE, OPTIONS } = createStreamProxy({

// Inject access token + tenant API key + tenant ID from cookies.
// Unlike admin, ingestion overwrites an incoming Authorization header
// with the cookie token — preserving pre-refactor behavior.
// with the cookie token - preserving pre-refactor behavior.
applyCookieCredentials(headers, request);

return headers;
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/app/api/review/[...path]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { getServerServiceURL } from '@/lib/api-config';
import { attestPrivilegedProxyClientIp } from '@/lib/proxy-ip-attestation';

// Proxy review API requests to the Admin backend service.
// Handles the approve/reject actions on flagged extractions — paths like
// Handles the approve/reject actions on flagged extractions - paths like
// /api/review/{id}/approve
// /api/review/{id}/reject
// are transformed into
Expand All @@ -18,7 +18,7 @@ const ADMIN_URL = (() => {
const url = process.env.ADMIN_SERVICE_URL || getServerServiceURL('admin');
const onVercel = Boolean(process.env.VERCEL || process.env.VERCEL_URL);
if (onVercel && url.includes('.railway.internal')) {
console.warn('[proxy/review] ADMIN_SERVICE_URL points to internal Railway URL — unreachable from Vercel.');
console.warn('[proxy/review] ADMIN_SERVICE_URL points to internal Railway URL; unreachable from Vercel.');
return getServerServiceURL('admin');
}
return url;
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/app/api/tools/verify/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Proxy for tool email verification — forwards to backend and sets
* Proxy for tool email verification - forwards to backend and sets
* the re_tool_access HTTP-only cookie on successful code confirmation.
*
* POST /api/tools/verify
Expand Down Expand Up @@ -32,14 +32,14 @@ function getBackendUrl(): string {
}

export async function POST(request: NextRequest) {
// On Vercel, localhost fallback will never work — fail fast with a clear error.
// On Vercel, localhost fallback will never work - fail fast with a clear error.
const backendUrl = getBackendUrl();
if (process.env.VERCEL && !backendUrl) {
console.error(
'[api/tools/verify] ADMIN_SERVICE_URL or NEXT_PUBLIC_API_BASE_URL must be set on Vercel — cannot reach localhost from serverless functions',
'[api/tools/verify] ADMIN_SERVICE_URL or NEXT_PUBLIC_API_BASE_URL must be set on Vercel; cannot reach localhost from serverless functions',
);
return NextResponse.json(
{ error: 'Backend not configured — contact support' },
{ error: 'Backend not configured. Contact support' },
{ status: 503 },
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ function getComplianceUrl(): string {
if (url) {
const onVercel = Boolean(process.env.VERCEL || process.env.VERCEL_URL);
if (onVercel && url.includes('.railway.internal')) {
console.warn('[proxy/attest] COMPLIANCE_SERVICE_URL points to internal Railway URL — unreachable from Vercel.');
console.warn('[proxy/attest] COMPLIANCE_SERVICE_URL points to internal Railway URL; unreachable from Vercel.');
return process.env.NEXT_PUBLIC_API_BASE_URL || url;
}
return url;
}
if (process.env.VERCEL) {
console.error('[api/attest] COMPLIANCE_SERVICE_URL not configured — localhost is unreachable from Vercel');
console.error('[api/attest] COMPLIANCE_SERVICE_URL not configured; localhost is unreachable from Vercel');
return '';
}
return 'http://localhost:8500';
Expand All @@ -49,7 +49,7 @@ export async function POST(
const COMPLIANCE_URL = getComplianceUrl();
const allowFallback = allowDevComplianceSnapshotFallback();
if (!COMPLIANCE_URL && !allowFallback) {
console.error('[proxy/attest] 503 — compliance backend not configured');
console.error('[proxy/attest] 503: compliance backend not configured');
return NextResponse.json(
{ error: 'backend_not_configured', message: 'Compliance backend is not configured' },
{ status: 503 },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function getComplianceUrl(): string {
const url = process.env.COMPLIANCE_SERVICE_URL || getServerServiceURL('compliance');
const onVercel = Boolean(process.env.VERCEL || process.env.VERCEL_URL);
if (onVercel && url.includes('.railway.internal')) {
console.warn('[proxy/audit-pack] COMPLIANCE_SERVICE_URL points to internal Railway URL — unreachable from Vercel.');
console.warn('[proxy/audit-pack] COMPLIANCE_SERVICE_URL points to internal Railway URL; unreachable from Vercel.');
return getServerServiceURL('compliance');
}
return url;
Expand Down Expand Up @@ -73,7 +73,7 @@ export async function GET(
});
}
}
console.error('[proxy/audit-pack] 503 — compliance backend not configured');
console.error('[proxy/audit-pack] 503: compliance backend not configured');
return NextResponse.json(
{ error: 'backend_not_configured', message: 'Compliance backend is not configured' },
{ status: 503 },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function getComplianceUrl(): string {
const url = process.env.COMPLIANCE_SERVICE_URL || getServerServiceURL('compliance');
const onVercel = Boolean(process.env.VERCEL || process.env.VERCEL_URL);
if (onVercel && url.includes('.railway.internal')) {
console.warn('[proxy/export] COMPLIANCE_SERVICE_URL points to internal Railway URL — unreachable from Vercel.');
console.warn('[proxy/export] COMPLIANCE_SERVICE_URL points to internal Railway URL; unreachable from Vercel.');
return getServerServiceURL('compliance');
}
return url;
Expand All @@ -42,7 +42,7 @@ export async function GET(

const { tenantId: rawTenantId, snapshotId: rawSnapshotId } = await params;
// Validate UUIDs before interpolating into the upstream URL (see
// verify/route.ts — same hardening applied to every named-segment proxy).
// verify/route.ts - same hardening applied to every named-segment proxy).
const tenantId = validateUuid(rawTenantId);
const snapshotId = validateUuid(rawSnapshotId);
if (!tenantId || !snapshotId) {
Expand Down Expand Up @@ -73,7 +73,7 @@ export async function GET(
return NextResponse.json(exportPayload);
}
}
console.error('[proxy/export] 503 — compliance backend not configured');
console.error('[proxy/export] 503: compliance backend not configured');
return NextResponse.json(
{ error: 'backend_not_configured', message: 'Compliance backend is not configured' },
{ status: 503 },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function getComplianceUrl(): string {
const url = process.env.COMPLIANCE_SERVICE_URL || getServerServiceURL('compliance');
const onVercel = Boolean(process.env.VERCEL || process.env.VERCEL_URL);
if (onVercel && url.includes('.railway.internal')) {
console.warn('[proxy/fda-response] COMPLIANCE_SERVICE_URL points to internal Railway URL — unreachable from Vercel.');
console.warn('[proxy/fda-response] COMPLIANCE_SERVICE_URL points to internal Railway URL; unreachable from Vercel.');
return getServerServiceURL('compliance');
}
return url;
Expand Down Expand Up @@ -66,7 +66,7 @@ export async function GET(
return NextResponse.json(fdaResponse);
}
}
console.error('[proxy/fda-response] 503 — compliance backend not configured');
console.error('[proxy/fda-response] 503: compliance backend not configured');
return NextResponse.json(
{ error: 'backend_not_configured', message: 'Compliance backend is not configured' },
{ status: 503 },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function getComplianceUrl(): string {
const url = process.env.COMPLIANCE_SERVICE_URL || getServerServiceURL('compliance');
const onVercel = Boolean(process.env.VERCEL || process.env.VERCEL_URL);
if (onVercel && url.includes('.railway.internal')) {
console.warn('[proxy/refreeze] COMPLIANCE_SERVICE_URL points to internal Railway URL — unreachable from Vercel.');
console.warn('[proxy/refreeze] COMPLIANCE_SERVICE_URL points to internal Railway URL; unreachable from Vercel.');
return getServerServiceURL('compliance');
}
return url;
Expand Down Expand Up @@ -79,7 +79,7 @@ export async function POST(
return NextResponse.json(result);
}
}
console.error('[proxy/refreeze] 503 — compliance backend not configured');
console.error('[proxy/refreeze] 503: compliance backend not configured');
return NextResponse.json(
{ error: 'backend_not_configured', message: 'Compliance backend is not configured' },
{ status: 503 },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function getComplianceUrl(): string {
const url = process.env.COMPLIANCE_SERVICE_URL || getServerServiceURL('compliance');
const onVercel = Boolean(process.env.VERCEL || process.env.VERCEL_URL);
if (onVercel && url.includes('.railway.internal')) {
console.warn('[proxy/verify] COMPLIANCE_SERVICE_URL points to internal Railway URL — unreachable from Vercel.');
console.warn('[proxy/verify] COMPLIANCE_SERVICE_URL points to internal Railway URL; unreachable from Vercel.');
return getServerServiceURL('compliance');
}
return url;
Expand Down Expand Up @@ -76,7 +76,7 @@ export async function GET(
return NextResponse.json(result);
}
}
console.error('[proxy/verify] 503 — compliance backend not configured');
console.error('[proxy/verify] 503: compliance backend not configured');
return NextResponse.json(
{ is_valid: false, error: 'backend_not_configured', message: 'Compliance backend is not configured' },
{ status: 503 },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function getComplianceUrl(): string {
const url = process.env.COMPLIANCE_SERVICE_URL || getServerServiceURL('compliance');
const onVercel = Boolean(process.env.VERCEL || process.env.VERCEL_URL);
if (onVercel && url.includes('.railway.internal')) {
console.warn('[proxy/snapshot-diff] COMPLIANCE_SERVICE_URL points to internal Railway URL — unreachable from Vercel.');
console.warn('[proxy/snapshot-diff] COMPLIANCE_SERVICE_URL points to internal Railway URL; unreachable from Vercel.');
return getServerServiceURL('compliance');
}
return url;
Expand Down Expand Up @@ -69,7 +69,7 @@ export async function GET(
return NextResponse.json(result);
}
}
console.error('[proxy/snapshot-diff] 503 — compliance backend not configured');
console.error('[proxy/snapshot-diff] 503: compliance backend not configured');
return NextResponse.json(
{ error: 'backend_not_configured', message: 'Compliance backend is not configured' },
{ status: 503 },
Expand Down
Loading
Loading