Skip to content

feat(web): grounded UVAI one-page homepage - #172

Merged
groupthinking merged 6 commits into
mainfrom
feat/grounded-homepage
May 1, 2026
Merged

feat(web): grounded UVAI one-page homepage#172
groupthinking merged 6 commits into
mainfrom
feat/grounded-homepage

Conversation

@groupthinking

Copy link
Copy Markdown
Owner

Summary

Rewrites / to be the grounded UVAI one-page positioning site, matching the static reference at /home/user/workspace/eventrelay-onepage. The page now reflects only proven repo capabilities (YouTube transcript, typed event extraction, Gemini/OpenAI analysis, SSE pipeline, OpenAPI, Docker/Cloud Run/Railway/Vercel, MIT) and drops unsupported homepage claims.

What changed

  • Replaced apps/web/src/app/page.tsx with the grounded one-pager: hero, pipeline preview, capabilities, workflow steps, developers panel, four template highlights (with a pointer to the dashboard for the rest), and an honest mailto-based inbound form.
  • Removed unproven stats (10K+ videos, 500ms response, 98% accuracy), pricing/SSO/SAML/enterprise/Slack/Notion claims, and "auto-deploy in one click" framing from the homepage.
  • Brand: public site = UVAI; EventRelay only shown as the repo/project name in the developer section and footer.
  • apps/web/src/app/layout.tsx: removed third-party Google Fonts <link> (uses existing system-ui Tailwind stack — avoids third-party font cookies). Updated metadata title/description to match grounded copy.
  • External links use rel="noopener noreferrer" with target="_blank".

Preserved

  • /dashboard and all /api/* routes are untouched and still build (build output confirms 20 routes including /dashboard, /dashboard/agents, and every existing API route).
  • Other marketing routes (/features, /pricing, /playground, /prototype) untouched.
  • Design system colors and component patterns reused.

Test plan

  • npm run build (Next.js 16 / Turbopack) — succeeded; static pages generated; both / and /dashboard routed.
  • npx eslint src/app/page.tsx src/app/layout.tsx --max-warnings=0 — clean.
  • Manual UI verification (no browser available in CI sandbox).

Notes / risks

  • npm run lint script uses Next 15's next lint --dir src which Next 16 removed — pre-existing repo issue, unrelated to this PR. Direct eslint invocation passes.
  • Workspace install required --legacy-peer-deps due to a pre-existing vitest/@opentelemetry peer conflict in the monorepo.
  • Pricing page (/pricing) is still in the app from earlier work; only homepage messaging is updated as scoped.

🤖 Generated with Claude Code

Rewrite `/` to mirror the static one-page positioning site at
/home/user/workspace/eventrelay-onepage. The new homepage describes only
proven, currently shipping capabilities and drops marketing claims that
the repository does not back up.

What changed
- New hero, capabilities, workflow, developers, templates, and contact
  sections that map 1:1 to the grounded reference page.
- Removed unfounded stats (10K+ videos, 500ms response, 98% accuracy)
  and the "deploy in one click" claims; templates are described as
  starting points, not auto-deploy promises.
- Removed pricing/Slack/Notion/SSO/SAML/enterprise SKU references on
  the homepage. Existing /pricing, /features, /playground, /prototype
  routes are left untouched for the parent app.
- Inbound form is honest: client-side validation only, opens a mailto
  to viralnowsales@gmail.com. No fake backend submission.
- External links use rel="noopener noreferrer" and target="_blank"
  consistently.
- Brand: public site is UVAI; EventRelay is referenced only as the
  open-source repo/project name in the developer section and footer.
- Layout: dropped the third-party Google Fonts <link> in favor of the
  existing system-ui Tailwind font stack to avoid third-party font
  cookies. Updated metadata title/description to match the grounded
  positioning.

Preserved
- /dashboard and all /api/* routes are untouched and still build.
- Existing components, workflow templates module, and design system
  variables (#0e0e13, #6af2de, etc.) reused so the page fits the
  surrounding app.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 1, 2026 07:16
@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown

🔍 PR Validation

⚠️ Large PR detected (1313 lines changed)

@github-actions github-actions Bot added the javascript Pull requests that update javascript code label May 1, 2026
@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@coderabbitai

coderabbitai Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3afa1ba9-5297-4389-be00-fe8f8736733b

📥 Commits

Reviewing files that changed from the base of the PR and between 293b823 and e0b3241.

📒 Files selected for processing (2)
  • apps/web/src/app/ContactForm.tsx
  • apps/web/src/app/page.tsx
📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*.tsx

⚙️ CodeRabbit configuration file

React components in Next.js 16. Check for proper use of 'use client' directives, hook dependency arrays, memory leaks in useEffect, and accessibility issues. Flag any TODO or placeholder UI components that are not production-ready.

Files:

  • apps/web/src/app/ContactForm.tsx
  • apps/web/src/app/page.tsx
🔇 Additional comments (4)
apps/web/src/app/ContactForm.tsx (2)

54-100: Submission handler is solid and consistent.

Line 60 normalization is reused through validation/body generation, and Line 99 includes complete hook dependencies. Good defensive client-side flow for the mailto handoff.


113-200: Form accessibility structure is correctly wired.

Inputs are properly associated with labels, required constraints are declared, and the live status region is in place for feedback updates.

Also applies to: 247-267

apps/web/src/app/page.tsx (2)

1-3: Server/client boundary is correctly applied.

Keeping page.tsx server-rendered while composing the client ContactForm preserves static rendering on / and avoids unnecessary hydration of the full landing page.

Also applies to: 559-603


172-176: External link hardening is correctly implemented.

target="_blank" links consistently include rel="noopener noreferrer" on the updated sections.

Also applies to: 589-593, 620-623


📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added a contact form to submit workflow requests directly from the landing page.
  • Updates

    • Redesigned landing page with dedicated sections for capabilities, workflow, developers, and contact information.
    • Updated site branding from "Video to Software" to "Video to Structured Intelligence" across all pages and social media previews.

Walkthrough

Rebrands site metadata to “Video to Structured Intelligence”, replaces the interactive template gallery with a static marketing landing page, adds a client-side ContactForm that opens a mailto: link, introduces a CONTACT_EMAIL constant, and removes inline Google Fonts injection from the layout.

Changes

Cohort / File(s) Summary
SEO & Metadata
apps/web/src/app/layout.tsx
Updated exported metadata values (title, description, keywords) and Open Graph / Twitter title+description to "Video to Structured Intelligence". Removed inline Google Fonts preconnect/stylesheet injection; layout now relies on Tailwind/system fonts. Review SEO copy and canonical tags and confirm font fallback is acceptable.
Landing Page (static marketing)
apps/web/src/app/page.tsx
Replaced prior client-side template gallery and router-driven navigation with a server-rendered static one-page marketing layout. Added page-local arrays (PIPELINE_ROWS, CAPABILITY_CARDS, STEPS, DEVELOPER_ITEMS, TEMPLATE_CARDS), anchored sections and CTAs to /dashboard. Removed 'use client'. Verify no client-only hooks/components remain and server-side rendering assumptions hold (e.g., no window/document usage).
Contact form (client component)
apps/web/src/app/ContactForm.tsx
New client-rendered ContactForm with controlled inputs, validation (email regex, YouTube hostname check, max lengths), normalizing optional YouTube URLs, and submission via a constructed mailto: link to CONTACT_EMAIL. Pay attention to mailto encoding limits, user privacy (input placed into mail body), and behavior when no native mail client exists; consider server-side submission fallback or an API endpoint for reliability.
Constants
apps/web/src/lib/constants.ts
Added exported CONTACT_EMAIL computed from process.env.NEXT_PUBLIC_CONTACT_EMAIL?.trim() with fallback 'viralnowsales@gmail.com'. Confirm that exposing this via NEXT_PUBLIC is intended and that the fallback value is correct for production.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

frontend

Poem

✨ A gallery folds its wings anew,
Metadata sings a clearer cue,
A static page opens its gate,
A contact form composes fate,
Structured signals navigate.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(web): grounded UVAI one-page homepage' directly and clearly summarizes the main change: replacing the homepage with a grounded, static one-page site positioning.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, covering what changed, what was removed, what was preserved, and test results with specific details about the implementation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/grounded-homepage

Review rate limit: 4/5 reviews remaining, refill in 12 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown

✅ E2E Test Results: ALL TESTS PASSED

Metric Value
Status 🟢 GREEN
Total Tests
Passed 17
Failed
Deployment https://uvai.io
Test Output
emplate cards�[32m 25�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mPOST /api/pipeline/stream returns SSE content-type�[33m 590�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mSSE stream emits pipeline_status:running then pipeline_status:complete�[33m 9389�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mSSE stream closes within 90 seconds (no 95% hang)�[33m 12841�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mSSE events fire in correct agent order�[33m 8599�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mCloudEvent Schema�[2m > �[22mSSE events contain valid timestamps�[33m 8886�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mCloudEvent Schema�[2m > �[22mpipeline_status:complete includes duration and agent count�[33m 8032�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mError Handling�[2m > �[22mmissing URL returns 400, not a hang�[32m 106�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mError Handling�[2m > �[22minvalid URL returns error event or completes quickly, not a hang�[33m 8810�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mDashboard�[2m > �[22m/dashboard returns 200�[32m 262�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mDashboard�[2m > �[22m/dashboard contains agent or pipeline visualization markup�[32m 36�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mAPI Health�[2m > �[22mGET /api returns a response (not 404)�[32m 186�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mAPI Health�[2m > �[22mPOST /api/pipeline/stream with no body returns 400�[32m 56�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mStatic Assets�[2m > �[22mhomepage has proper meta tags�[32m 22�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mStatic Assets�[2m > �[22m/features page returns 200�[33m 387�[2mms�[22m�[39m

�[2m Test Files �[22m �[1m�[32m1 passed�[39m�[22m�[90m (1)�[39m
�[2m      Tests �[22m �[1m�[32m17 passed�[39m�[22m�[90m (17)�[39m
�[2m   Start at �[22m 07:16:59
�[2m   Duration �[22m 58.69s�[2m (transform 45ms, setup 0ms, import 55ms, tests 58.54s, environment 0ms)�[22m


@coderabbitai coderabbitai Bot added the frontend label May 1, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the public / route of the Next.js web app to a grounded, single-page UVAI positioning site that removes unsupported marketing claims and aligns the copy with capabilities that exist in the repo.

Changes:

  • Replaced apps/web/src/app/page.tsx with a new one-page marketing layout (hero, pipeline preview, capabilities, workflow steps, developer section, template highlights, and a mailto-based contact form).
  • Updated apps/web/src/app/layout.tsx metadata (title/description/keywords) to match the new grounded homepage messaging.
  • Removed the Google Fonts <head> links from layout.tsx to avoid third-party font requests.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
apps/web/src/app/page.tsx Rewrites the homepage to a grounded one-pager and introduces a mailto-based inbound form.
apps/web/src/app/layout.tsx Updates SEO metadata and removes Google Fonts <head> links.

Comment on lines 82 to 84
<html lang="en">
<head>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&family=JetBrains+Mono:wght@100..800&family=Space+Grotesk:wght@300..700&display=swap"
rel="stylesheet"
/>
</head>
<body className="min-h-screen bg-surface-950 font-sans antialiased">
{/* Global background effects */}

Copilot AI May 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RootLayout still has a comment claiming font CSS variables are defined via Google Fonts <link> tags in <head>, but this PR removes that <head> block. Please update/remove that comment (and any related assumptions) so it matches the new approach (system-ui / locally available fonts).

Copilot uses AI. Check for mistakes.
Comment thread apps/web/src/app/page.tsx Outdated
>
{template.description}
</p>
const CONTACT_EMAIL = 'viralnowsales@gmail.com';

Copilot AI May 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CONTACT_EMAIL is hardcoded to a personal address in the client bundle. Consider reading this from a public env var (e.g., NEXT_PUBLIC_CONTACT_EMAIL) with a safe default, so forks/deploys can configure it without code changes and to avoid baking personal contact info into OSS builds.

Suggested change
const CONTACT_EMAIL = 'viralnowsales@gmail.com';
const CONTACT_EMAIL =
process.env.NEXT_PUBLIC_CONTACT_EMAIL || 'contact@example.com';

Copilot uses AI. Check for mistakes.
Comment thread apps/web/src/app/page.tsx Outdated
Comment on lines +173 to +175
if (n.length > 100 || msg.length > 2000) {
setStatus({ kind: 'error', text: 'Keep the name under 100 characters and the note under 2,000 characters.' });
return;

Copilot AI May 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mailto body allows up to 2,000 characters, but mailto: URIs have fairly low and client-dependent length limits (and URL-encoding expands the payload). This can lead to truncated bodies or failures in some email clients. Consider lowering the limit substantially or switching to a real POST endpoint (even if it just relays to email) for longer requests.

Copilot uses AI. Check for mistakes.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the application metadata and completely redesigns the landing page to focus on core video intelligence capabilities. Key changes include the removal of manual font loading in the layout and the introduction of a new contact form that utilizes mailto: for workflow requests. Feedback is provided to improve the YouTube URL validation by handling missing protocols and to reduce the message character limit to ensure compatibility with email client URL length restrictions.

Comment thread apps/web/src/app/page.tsx Outdated
Comment on lines +140 to +148
function isYouTube(value: string) {
if (!value) return true;
try {
const u = new URL(value);
return ['youtube.com', 'www.youtube.com', 'youtu.be', 'm.youtube.com'].includes(u.hostname);
} catch {
return false;
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The new URL() constructor throws an error if the string does not include a protocol (e.g., youtube.com/...). Users often omit https:// when typing URLs, which will cause this validation to fail and show an error message even for valid YouTube domains. Prepending a default protocol before validation improves the user experience.

Suggested change
function isYouTube(value: string) {
if (!value) return true;
try {
const u = new URL(value);
return ['youtube.com', 'www.youtube.com', 'youtu.be', 'm.youtube.com'].includes(u.hostname);
} catch {
return false;
}
}
function isYouTube(value: string) {
if (!value) return true;
try {
const urlToTest = /^https?:\/\//.test(value) ? value : `https://${value}`;
const u = new URL(urlToTest);
return ['youtube.com', 'www.youtube.com', 'youtu.be', 'm.youtube.com'].includes(u.hostname);
} catch {
return false;
}
}

Comment thread apps/web/src/app/page.tsx Outdated
Comment on lines +173 to +176
if (n.length > 100 || msg.length > 2000) {
setStatus({ kind: 'error', text: 'Keep the name under 100 characters and the note under 2,000 characters.' });
return;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current validation allows a message length of up to 2,000 characters. When combined with other fields and URL encoding, the resulting mailto: link will likely exceed the character limit for many email clients and browsers (often around 2,000 characters total). This can cause the "Send request" button to fail silently or open a broken link in the user's mail client. Reducing the limit to 1,000 characters is safer for a mailto-based implementation.

Suggested change
if (n.length > 100 || msg.length > 2000) {
setStatus({ kind: 'error', text: 'Keep the name under 100 characters and the note under 2,000 characters.' });
return;
}
if (n.length > 100 || msg.length > 1000) {
setStatus({ kind: 'error', text: 'Keep the name under 100 characters and the note under 1,000 characters.' });
return;
}

Comment thread apps/web/src/app/page.tsx Outdated
id="message"
name="message"
placeholder="Example: turn product demo videos into API docs and tickets."
maxLength={2000}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The maxLength should be reduced to 1,000 to ensure the generated mailto: URL remains within the compatibility limits of most email clients.

Suggested change
maxLength={2000}
maxLength={1000}

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/web/src/app/page.tsx`:
- Around line 186-200: The privacy claim is inaccurate because the form data is
serialized into a mailto URI (subject/body) and handed to the OS mail handler,
and setStatus is set to 'success' before any handoff confirmation; update either
by implementing a real POST-backed submission (create an API endpoint and send
the payload via fetch/POST from the form handler, await the response, then call
setStatus({ kind: 'success', ... }) on success) or, if you keep the mailto flow
(subject/body and window.location.href =
`mailto:${CONTACT_EMAIL}?subject=${subject}&body=${body}`), change the UI text
to a softer privacy/safety message and only set a non-final status (e.g.,
'action started' or remove premature success) instead of declaring success;
update all occurrences that use CONTACT_EMAIL, subject, body,
window.location.href and setStatus (also the similar block at the other
location) accordingly.
- Around line 1-4: page.tsx is currently a Client Component solely to host the
contact form, which forces the whole homepage to hydrate; extract the form into
a new small Client Component named ContactForm (e.g.,
apps/web/src/app/ContactForm.tsx) and keep page.tsx as a Server Component. Move
the form JSX and all related client state/hooks (useState, useCallback, status
state and the existing handleSubmit logic) into ContactForm, export it as
default, and replace the inline form in page.tsx with <ContactForm /> (server
component imports a client component). Ensure all event handlers and local state
live only in ContactForm and update any imports (useState/useCallback)
accordingly so page.tsx no longer contains 'use client'.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: ebebfb6e-e0e8-4484-878a-25b751df84ff

📥 Commits

Reviewing files that changed from the base of the PR and between e42aa4c and 6341340.

📒 Files selected for processing (2)
  • apps/web/src/app/layout.tsx
  • apps/web/src/app/page.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Agent
  • GitHub Check: Generate and Upload Coverage
  • GitHub Check: trivy
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.tsx

⚙️ CodeRabbit configuration file

React components in Next.js 16. Check for proper use of 'use client' directives, hook dependency arrays, memory leaks in useEffect, and accessibility issues. Flag any TODO or placeholder UI components that are not production-ready.

Files:

  • apps/web/src/app/layout.tsx
  • apps/web/src/app/page.tsx
🧠 Learnings (1)
📚 Learning: 2025-10-06T03:55:57.139Z
Learnt from: CR
Repo: groupthinking/EventRelay PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T03:55:57.139Z
Learning: Ensure all features support the single workflow: YouTube link → context extraction → agent dispatch

Applied to files:

  • apps/web/src/app/page.tsx

Comment thread apps/web/src/app/page.tsx Outdated
Comment thread apps/web/src/app/page.tsx Outdated
…dback

- Move mailto form into apps/web/src/app/ContactForm.tsx so page.tsx
  is a Server Component (no 'use client', useState, or useCallback)
- Soften privacy and status copy: replace 'success' with non-final
  'Trying to open your email app...' and clarify that drafts are
  handled by the browser or local mail app, not stored on our backend
- Accept YouTube URLs without protocol by prepending https:// before
  validation
- Reduce message maxLength from 2000 to 1000 to keep mailto URLs safe
- Update stale layout comment that referenced a Google Fonts <head>
  link; fonts come from the system stack via tailwind.config
- Read CONTACT_EMAIL from NEXT_PUBLIC_CONTACT_EMAIL with fallback to
  the live default
@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown

🔍 PR Validation

⚠️ Large PR detected (1366 lines changed)

@groupthinking

Copy link
Copy Markdown
Owner Author

Addressed review feedback in 6203203:

  • page.tsx → Server Component: Extracted the mailto form into a new small Client Component at apps/web/src/app/ContactForm.tsx. page.tsx no longer contains 'use client', useState, or useCallback; the homepage now prerenders as static.
  • Privacy & status copy: Replaced the success status with a non-final Trying to open your email app... (kind: 'pending'). Privacy note rewritten to: this page does not submit to our backend and explains the draft is handed to the browser/local mail app — no backend storage claims.
  • YouTube validation: isYouTube now prepends https:// when the input lacks a protocol before constructing URL.
  • mailto length safety: message maxLength and validation reduced from 2000 → 1000 chars.
  • Stale layout comment: Updated; layout never linked Google Fonts in <head> — fonts come from the system stack via tailwind.config.
  • Contact email config: Reads process.env.NEXT_PUBLIC_CONTACT_EMAIL with fallback to viralnowsales@gmail.com (default unchanged).

Verification:

  • npm run build (apps/web) → Compiled successfully, TypeScript OK, / listed as ○ (Static) (confirms server component).
  • ESLint on the three changed TSX files → no warnings.

CodeRabbit should re-review automatically on the new push. To force a fresh review, comment @coderabbitai review on the PR.

@coderabbitai

coderabbitai Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@groupthinking: Thanks for the thorough follow-up — the fixes look well-targeted. Here's a quick read on each item before the fresh pass kicks off:

  • Server Component extraction — Clean split; ContactForm.tsx as the isolated client boundary is the right pattern for Next.js App Router. Static prerender on / is a meaningful win.
  • YouTube validation — Prepending https:// before constructing URL is the correct fix; bare hostnames like youtu.be/abc would have thrown previously.
  • mailto length safety — 1000-char cap is reasonable; prevents over-long mailto: URIs that some mail clients truncate silently.
  • Privacy copypending status + "handed to the browser/local mail app" framing avoids any false backend-storage implication. Good call.
  • Contact email env varNEXT_PUBLIC_CONTACT_EMAIL with a hardcoded fallback is straightforward; just worth noting the fallback email will be visible in the client bundle if the env var is ever omitted in production.
  • Layout comment — Keeping docs in sync with reality is appreciated.

Triggering a full re-review now.

[full_review]

@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown

✅ E2E Test Results: ALL TESTS PASSED

Metric Value
Status 🟢 GREEN
Total Tests
Passed 17
Failed
Deployment https://uvai.io
Test Output
plate cards�[32m 18�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mPOST /api/pipeline/stream returns SSE content-type�[32m 242�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mSSE stream emits pipeline_status:running then pipeline_status:complete�[33m 8827�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mSSE stream closes within 90 seconds (no 95% hang)�[33m 13275�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mSSE events fire in correct agent order�[33m 9166�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mCloudEvent Schema�[2m > �[22mSSE events contain valid timestamps�[33m 9185�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mCloudEvent Schema�[2m > �[22mpipeline_status:complete includes duration and agent count�[33m 10929�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mError Handling�[2m > �[22mmissing URL returns 400, not a hang�[32m 124�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mError Handling�[2m > �[22minvalid URL returns error event or completes quickly, not a hang�[33m 3713�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mDashboard�[2m > �[22m/dashboard returns 200�[32m 170�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mDashboard�[2m > �[22m/dashboard contains agent or pipeline visualization markup�[32m 35�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mAPI Health�[2m > �[22mGET /api returns a response (not 404)�[33m 312�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mAPI Health�[2m > �[22mPOST /api/pipeline/stream with no body returns 400�[32m 106�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mStatic Assets�[2m > �[22mhomepage has proper meta tags�[32m 23�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mStatic Assets�[2m > �[22m/features page returns 200�[32m 172�[2mms�[22m�[39m

�[2m Test Files �[22m �[1m�[32m1 passed�[39m�[22m�[90m (1)�[39m
�[2m      Tests �[22m �[1m�[32m17 passed�[39m�[22m�[90m (17)�[39m
�[2m   Start at �[22m 07:30:25
�[2m   Duration �[22m 56.75s�[2m (transform 41ms, setup 0ms, import 52ms, tests 56.60s, environment 0ms)�[22m


@coderabbitai coderabbitai Bot removed the frontend label May 1, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/web/src/app/ContactForm.tsx`:
- Around line 20-24: Duplicate CONTACT_EMAIL and DEFAULT_CONTACT_EMAIL logic in
ContactForm.tsx and page.tsx should be extracted to a single shared constant;
create a module (e.g., lib/constants.ts) that exports CONTACT_EMAIL (computed
from DEFAULT_CONTACT_EMAIL and process.env.NEXT_PUBLIC_CONTACT_EMAIL) and then
replace the local definitions in both ContactForm.tsx and page.tsx by importing
CONTACT_EMAIL from that module, removing the duplicated constants so both
components use the same exported symbol.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 362b5bae-88e2-4800-844e-ffbc6379a733

📥 Commits

Reviewing files that changed from the base of the PR and between 6341340 and 6203203.

📒 Files selected for processing (3)
  • apps/web/src/app/ContactForm.tsx
  • apps/web/src/app/layout.tsx
  • apps/web/src/app/page.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: test
  • GitHub Check: Generate and Upload Coverage
  • GitHub Check: trivy
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: E2E Pipeline Tests
🧰 Additional context used
📓 Path-based instructions (1)
**/*.tsx

⚙️ CodeRabbit configuration file

React components in Next.js 16. Check for proper use of 'use client' directives, hook dependency arrays, memory leaks in useEffect, and accessibility issues. Flag any TODO or placeholder UI components that are not production-ready.

Files:

  • apps/web/src/app/layout.tsx
  • apps/web/src/app/page.tsx
  • apps/web/src/app/ContactForm.tsx
🧠 Learnings (4)
📚 Learning: 2025-10-06T03:55:57.139Z
Learnt from: CR
Repo: groupthinking/EventRelay PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T03:55:57.139Z
Learning: Applies to frontend/src/**/*.{ts,tsx} : Frontend uses React 18+ with TypeScript; prefer React hooks and functional components

Applied to files:

  • apps/web/src/app/page.tsx
📚 Learning: 2025-10-06T03:55:57.139Z
Learnt from: CR
Repo: groupthinking/EventRelay PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T03:55:57.139Z
Learning: Applies to frontend/src/**/*.{ts,tsx} : Extract reusable logic into custom hooks

Applied to files:

  • apps/web/src/app/page.tsx
📚 Learning: 2025-10-06T03:55:57.139Z
Learnt from: CR
Repo: groupthinking/EventRelay PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T03:55:57.139Z
Learning: Applies to frontend/src/**/*.{tsx,jsx} : Prefer functional components with hooks in React

Applied to files:

  • apps/web/src/app/page.tsx
📚 Learning: 2025-10-06T03:55:57.139Z
Learnt from: CR
Repo: groupthinking/EventRelay PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T03:55:57.139Z
Learning: Applies to frontend/src/services/**/*.{ts,tsx} : Add frontend API client integrations under frontend/src/services/

Applied to files:

  • apps/web/src/app/page.tsx
🔇 Additional comments (8)
apps/web/src/app/page.tsx (4)

575-583: Privacy copy is accurate now.

The updated text correctly states the page doesn't submit to the backend and that the draft is handled by the browser/mail app. This addresses the earlier concern about overstating guarantees.


1-2: Good extraction of ContactForm.

The page is now a proper Server Component with the interactive form extracted to a Client Component. This addresses the earlier feedback about unnecessary client-side hydration.


176-184: External links properly secured.

All target="_blank" links include rel="noopener noreferrer" which prevents reverse tabnabbing attacks.


99-121: Remove unused workflow-templates.ts—it's dead code.

TEMPLATE_CARDS defined locally here replaces the entire WORKFLOW_TEMPLATES and CATEGORIES exports from apps/web/src/lib/workflow-templates.ts. The file is not imported anywhere in the codebase and serves no purpose. Delete it to eliminate dead code.

apps/web/src/app/ContactForm.tsx (2)

54-100: LGTM on the submit handler.

The dependency array is complete, validation is thorough, and the status correctly shows "pending" rather than claiming success before the mail client actually opens. This addresses the earlier feedback about overstating guarantees.


102-201: Good accessibility on the form.

role="status" with aria-live="polite" ensures screen readers announce validation errors without interrupting. All inputs have proper labels and autocomplete hints. No concerns here.

apps/web/src/app/layout.tsx (2)

6-9: Good documentation on font strategy.

The comment clearly explains why next/font/google is avoided (build failures when Google Fonts API is unreachable). This prevents future contributors from "fixing" it and breaking CI.


11-64: Metadata updates align with the rebrand.

Title, description, keywords, and OG/Twitter cards are consistent with the new "Video to Structured Intelligence" positioning. No issues.

Comment thread apps/web/src/app/ContactForm.tsx Outdated
…s values

Browser native URL validation on type='url' was blocking submission of
protocol-less values like "youtube.com/watch?v=..." before our onSubmit
handler could prepend https:// in isYouTube(). Switch to type='text' with
inputMode='url' and autoComplete='url' for accessibility and mobile UX,
and add a visible hint that https:// is optional.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown

🔍 PR Validation

⚠️ Large PR detected (1373 lines changed)

@coderabbitai coderabbitai Bot added the frontend label May 1, 2026
@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown

✅ E2E Test Results: ALL TESTS PASSED

Metric Value
Status 🟢 GREEN
Total Tests
Passed 17
Failed
Deployment https://uvai.io
Test Output
t 5 template cards�[32m 34�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mPOST /api/pipeline/stream returns SSE content-type�[32m 96�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mSSE stream emits pipeline_status:running then pipeline_status:complete�[33m 9109�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mSSE stream closes within 90 seconds (no 95% hang)�[33m 7965�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mSSE events fire in correct agent order�[33m 10632�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mCloudEvent Schema�[2m > �[22mSSE events contain valid timestamps�[33m 8749�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mCloudEvent Schema�[2m > �[22mpipeline_status:complete includes duration and agent count�[33m 9105�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mError Handling�[2m > �[22mmissing URL returns 400, not a hang�[32m 92�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mError Handling�[2m > �[22minvalid URL returns error event or completes quickly, not a hang�[33m 3440�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mDashboard�[2m > �[22m/dashboard returns 200�[32m 21�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mDashboard�[2m > �[22m/dashboard contains agent or pipeline visualization markup�[32m 24�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mAPI Health�[2m > �[22mGET /api returns a response (not 404)�[32m 73�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mAPI Health�[2m > �[22mPOST /api/pipeline/stream with no body returns 400�[32m 61�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mStatic Assets�[2m > �[22mhomepage has proper meta tags�[32m 30�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mStatic Assets�[2m > �[22m/features page returns 200�[32m 21�[2mms�[22m�[39m

�[2m Test Files �[22m �[1m�[32m1 passed�[39m�[22m�[90m (1)�[39m
�[2m      Tests �[22m �[1m�[32m17 passed�[39m�[22m�[90m (17)�[39m
�[2m   Start at �[22m 07:36:59
�[2m   Duration �[22m 49.89s�[2m (transform 53ms, setup 0ms, import 66ms, tests 49.70s, environment 0ms)�[22m


@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/web/src/app/ContactForm.tsx`:
- Around line 21-24: CONTACT_EMAIL is chosen using
NEXT_PUBLIC_CONTACT_EMAIL.trim() to validate but then uses the untrimmed env
value, which can leave leading/trailing spaces in the mailto: link; change the
assignment to use the trimmed value (e.g., compute a trimmedEmail from
process.env.NEXT_PUBLIC_CONTACT_EMAIL?.trim(), check trimmedEmail.length > 0 and
set CONTACT_EMAIL = trimmedEmail, otherwise fallback to DEFAULT_CONTACT_EMAIL)
so the final CONTACT_EMAIL contains no surrounding whitespace.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 86c6adcc-470c-458d-8271-8d329777cb86

📥 Commits

Reviewing files that changed from the base of the PR and between 6203203 and fadda5e.

📒 Files selected for processing (1)
  • apps/web/src/app/ContactForm.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: Generate and Upload Coverage
  • GitHub Check: build
  • GitHub Check: npm-audit
  • GitHub Check: test
  • GitHub Check: python-safety
  • GitHub Check: Analyze (javascript)
  • GitHub Check: trivy
  • GitHub Check: Analyze (python)
  • GitHub Check: E2E Pipeline Tests
🧰 Additional context used
📓 Path-based instructions (1)
**/*.tsx

⚙️ CodeRabbit configuration file

React components in Next.js 16. Check for proper use of 'use client' directives, hook dependency arrays, memory leaks in useEffect, and accessibility issues. Flag any TODO or placeholder UI components that are not production-ready.

Files:

  • apps/web/src/app/ContactForm.tsx
🔇 Additional comments (2)
apps/web/src/app/ContactForm.tsx (2)

33-42: YouTube normalization logic is solid.

Accepting protocol-less input and normalizing before URL parsing avoids false negatives while keeping host allowlisting strict.


186-200: Status announcement pattern is accessibility-friendly.

Using a live region for async/error feedback here is a good implementation choice.

Comment thread apps/web/src/app/ContactForm.tsx Outdated
Move the duplicated CONTACT_EMAIL / DEFAULT_CONTACT_EMAIL logic into
apps/web/src/lib/constants.ts and import it from both ContactForm.tsx
and page.tsx. Addresses CodeRabbit feedback on PR #172.
@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown

🔍 PR Validation

⚠️ Large PR detected (1371 lines changed)

@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown

✅ E2E Test Results: ALL TESTS PASSED

Metric Value
Status 🟢 GREEN
Total Tests
Passed 17
Failed
Deployment https://uvai.io
Test Output
 template cards�[32m 44�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mPOST /api/pipeline/stream returns SSE content-type�[32m 175�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mSSE stream emits pipeline_status:running then pipeline_status:complete�[33m 9067�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mSSE stream closes within 90 seconds (no 95% hang)�[33m 6493�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mSSE events fire in correct agent order�[33m 5889�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mCloudEvent Schema�[2m > �[22mSSE events contain valid timestamps�[33m 7391�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mCloudEvent Schema�[2m > �[22mpipeline_status:complete includes duration and agent count�[33m 9078�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mError Handling�[2m > �[22mmissing URL returns 400, not a hang�[32m 206�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mError Handling�[2m > �[22minvalid URL returns error event or completes quickly, not a hang�[33m 2966�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mDashboard�[2m > �[22m/dashboard returns 200�[32m 40�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mDashboard�[2m > �[22m/dashboard contains agent or pipeline visualization markup�[32m 36�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mAPI Health�[2m > �[22mGET /api returns a response (not 404)�[32m 132�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mAPI Health�[2m > �[22mPOST /api/pipeline/stream with no body returns 400�[32m 125�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mStatic Assets�[2m > �[22mhomepage has proper meta tags�[32m 46�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mStatic Assets�[2m > �[22m/features page returns 200�[32m 34�[2mms�[22m�[39m

�[2m Test Files �[22m �[1m�[32m1 passed�[39m�[22m�[90m (1)�[39m
�[2m      Tests �[22m �[1m�[32m17 passed�[39m�[22m�[90m (17)�[39m
�[2m   Start at �[22m 07:46:10
�[2m   Duration �[22m 42.27s�[2m (transform 56ms, setup 0ms, import 70ms, tests 42.08s, environment 0ms)�[22m


@coderabbitai coderabbitai Bot removed the frontend label May 1, 2026
@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown

🔍 PR Validation

⚠️ Large PR detected (1368 lines changed)

@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown

✅ E2E Test Results: ALL TESTS PASSED

Metric Value
Status 🟢 GREEN
Total Tests
Passed 17
Failed
Deployment https://uvai.io
Test Output
5 template cards�[32m 18�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mPOST /api/pipeline/stream returns SSE content-type�[32m 76�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mSSE stream emits pipeline_status:running then pipeline_status:complete�[33m 9547�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mSSE stream closes within 90 seconds (no 95% hang)�[33m 10329�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mSSE events fire in correct agent order�[33m 12981�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mCloudEvent Schema�[2m > �[22mSSE events contain valid timestamps�[33m 9691�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mCloudEvent Schema�[2m > �[22mpipeline_status:complete includes duration and agent count�[33m 9797�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mError Handling�[2m > �[22mmissing URL returns 400, not a hang�[32m 178�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mError Handling�[2m > �[22minvalid URL returns error event or completes quickly, not a hang�[33m 2908�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mDashboard�[2m > �[22m/dashboard returns 200�[32m 27�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mDashboard�[2m > �[22m/dashboard contains agent or pipeline visualization markup�[32m 34�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mAPI Health�[2m > �[22mGET /api returns a response (not 404)�[32m 62�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mAPI Health�[2m > �[22mPOST /api/pipeline/stream with no body returns 400�[32m 75�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mStatic Assets�[2m > �[22mhomepage has proper meta tags�[32m 31�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mStatic Assets�[2m > �[22m/features page returns 200�[32m 40�[2mms�[22m�[39m

�[2m Test Files �[22m �[1m�[32m1 passed�[39m�[22m�[90m (1)�[39m
�[2m      Tests �[22m �[1m�[32m17 passed�[39m�[22m�[90m (17)�[39m
�[2m   Start at �[22m 07:48:27
�[2m   Duration �[22m 56.25s�[2m (transform 58ms, setup 0ms, import 72ms, tests 56.05s, environment 0ms)�[22m


@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
apps/web/src/lib/constants.ts (1)

3-6: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use the trimmed env value in CONTACT_EMAIL.

NEXT_PUBLIC_CONTACT_EMAIL is validated with .trim(), but the exported value is still the raw env string. If the env var has leading/trailing spaces, every homepage mailto: link can break.

🔧 Minimal fix
 const DEFAULT_CONTACT_EMAIL = 'viralnowsales@gmail.com';
+const trimmedContactEmail = (process.env.NEXT_PUBLIC_CONTACT_EMAIL ?? '').trim();
 
 export const CONTACT_EMAIL =
-  process.env.NEXT_PUBLIC_CONTACT_EMAIL && process.env.NEXT_PUBLIC_CONTACT_EMAIL.trim().length > 0
-    ? process.env.NEXT_PUBLIC_CONTACT_EMAIL
-    : DEFAULT_CONTACT_EMAIL;
+  trimmedContactEmail || DEFAULT_CONTACT_EMAIL;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/lib/constants.ts` around lines 3 - 6, The exported CONTACT_EMAIL
uses the raw NEXT_PUBLIC_CONTACT_EMAIL despite validating with .trim(), which
allows leading/trailing spaces to persist; update the logic for CONTACT_EMAIL to
compute a local env string (e.g., read process.env.NEXT_PUBLIC_CONTACT_EMAIL
into a variable), call .trim() safely only when the var is defined, and use the
trimmed value in the ternary so CONTACT_EMAIL becomes either the trimmed
NEXT_PUBLIC_CONTACT_EMAIL or DEFAULT_CONTACT_EMAIL; reference CONTACT_EMAIL,
NEXT_PUBLIC_CONTACT_EMAIL, and DEFAULT_CONTACT_EMAIL when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/web/src/app/ContactForm.tsx`:
- Around line 31-34: Validation currently normalizes protocol-less YouTube
inputs into the local variable candidate (and URL u) but the draft email still
uses the original raw videoUrl, producing non-clickable links; modify the flow
to normalize once and reuse that normalized value when building the outgoing
draft body and anywhere the URL is used (replace uses of the raw videoUrl with a
single normalized variable like normalizedVideoUrl / candidate), and apply the
same change to the other validation/usage sites referenced (the blocks around
lines 53-57 and 74-90) so validation and outgoing content use the exact same
normalized URL.

In `@apps/web/src/app/page.tsx`:
- Around line 154-168: The nav links point to hash IDs (e.g., '#capabilities',
'#workflow', '#developers', '#contact') but the fixed header covers the anchored
headings; add scroll offset by applying CSS scroll-margin-top to each target
element (the section or heading elements that have id="capabilities" etc.).
Update the page.tsx targets (the elements that render those IDs) to include a
class like "scroll-mt-20" or inline style {scrollMarginTop:
'var(--header-height)'} (or a pixel value) so clicking the <a> tags in the
mapped links scrolls the section below the fixed navbar; apply the same change
to the other listed IDs (lines referenced) to fix all anchors.

---

Duplicate comments:
In `@apps/web/src/lib/constants.ts`:
- Around line 3-6: The exported CONTACT_EMAIL uses the raw
NEXT_PUBLIC_CONTACT_EMAIL despite validating with .trim(), which allows
leading/trailing spaces to persist; update the logic for CONTACT_EMAIL to
compute a local env string (e.g., read process.env.NEXT_PUBLIC_CONTACT_EMAIL
into a variable), call .trim() safely only when the var is defined, and use the
trimmed value in the ternary so CONTACT_EMAIL becomes either the trimmed
NEXT_PUBLIC_CONTACT_EMAIL or DEFAULT_CONTACT_EMAIL; reference CONTACT_EMAIL,
NEXT_PUBLIC_CONTACT_EMAIL, and DEFAULT_CONTACT_EMAIL when making the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: f2ce6f31-92ee-4b96-9303-51d4699bb2f0

📥 Commits

Reviewing files that changed from the base of the PR and between fadda5e and be59686.

📒 Files selected for processing (3)
  • apps/web/src/app/ContactForm.tsx
  • apps/web/src/app/page.tsx
  • apps/web/src/lib/constants.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Generate and Upload Coverage
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Analyze (python)
  • GitHub Check: trivy
🧰 Additional context used
📓 Path-based instructions (2)
**/*.tsx

⚙️ CodeRabbit configuration file

React components in Next.js 16. Check for proper use of 'use client' directives, hook dependency arrays, memory leaks in useEffect, and accessibility issues. Flag any TODO or placeholder UI components that are not production-ready.

Files:

  • apps/web/src/app/ContactForm.tsx
  • apps/web/src/app/page.tsx
**/*.ts

⚙️ CodeRabbit configuration file

This is a TypeScript/Next.js project. Focus on type safety, null checks, async/await error handling, and SSE stream lifecycle management. Flag any fetch() calls without AbortSignal.timeout. Check for proper error boundaries. Flag any TODO, placeholder, or stub implementations that are not production-ready. Enforce TypeScript strict mode compliance — flag implicit any, missing return types, and unsafe type assertions.

Files:

  • apps/web/src/lib/constants.ts
🧠 Learnings (4)
📚 Learning: 2025-10-06T03:55:57.139Z
Learnt from: CR
Repo: groupthinking/EventRelay PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T03:55:57.139Z
Learning: Applies to frontend/src/**/*.{ts,tsx} : Frontend uses React 18+ with TypeScript; prefer React hooks and functional components

Applied to files:

  • apps/web/src/app/page.tsx
📚 Learning: 2025-10-06T03:55:57.139Z
Learnt from: CR
Repo: groupthinking/EventRelay PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T03:55:57.139Z
Learning: Applies to frontend/src/**/*.{ts,tsx} : Extract reusable logic into custom hooks

Applied to files:

  • apps/web/src/app/page.tsx
📚 Learning: 2025-10-06T03:55:57.139Z
Learnt from: CR
Repo: groupthinking/EventRelay PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T03:55:57.139Z
Learning: Applies to frontend/src/services/**/*.{ts,tsx} : Add frontend API client integrations under frontend/src/services/

Applied to files:

  • apps/web/src/app/page.tsx
📚 Learning: 2025-10-06T03:55:57.139Z
Learnt from: CR
Repo: groupthinking/EventRelay PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-06T03:55:57.139Z
Learning: Applies to frontend/src/**/*.{tsx,jsx} : Prefer functional components with hooks in React

Applied to files:

  • apps/web/src/app/page.tsx

Comment thread apps/web/src/app/ContactForm.tsx Outdated
Comment thread apps/web/src/app/page.tsx
@groupthinking

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot added frontend and removed frontend labels May 1, 2026
- ContactForm: extract normalizeVideoUrl helper; apply normalization to
  the trimmed video URL once and use that value for both validation and
  the outgoing mailto body.
- page.tsx: add scroll-mt-24 to #capabilities, #workflow, #developers,
  and #contact so the sticky header does not cover hash-link targets.
@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown

🔍 PR Validation

⚠️ Large PR detected (1372 lines changed)

@github-actions

github-actions Bot commented May 1, 2026

Copy link
Copy Markdown

✅ E2E Test Results: ALL TESTS PASSED

Metric Value
Status 🟢 GREEN
Total Tests
Passed 17
Failed
Deployment https://uvai.io
Test Output
 5 template cards�[32m 30�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mPOST /api/pipeline/stream returns SSE content-type�[32m 77�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mSSE stream emits pipeline_status:running then pipeline_status:complete�[33m 9375�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mSSE stream closes within 90 seconds (no 95% hang)�[33m 11817�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mSSE Pipeline Stream�[2m > �[22mSSE events fire in correct agent order�[33m 12608�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mCloudEvent Schema�[2m > �[22mSSE events contain valid timestamps�[33m 9110�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mCloudEvent Schema�[2m > �[22mpipeline_status:complete includes duration and agent count�[33m 9586�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mError Handling�[2m > �[22mmissing URL returns 400, not a hang�[32m 90�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mError Handling�[2m > �[22minvalid URL returns error event or completes quickly, not a hang�[33m 2916�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mDashboard�[2m > �[22m/dashboard returns 200�[32m 30�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mDashboard�[2m > �[22m/dashboard contains agent or pipeline visualization markup�[32m 19�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mAPI Health�[2m > �[22mGET /api returns a response (not 404)�[32m 49�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mAPI Health�[2m > �[22mPOST /api/pipeline/stream with no body returns 400�[32m 49�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mStatic Assets�[2m > �[22mhomepage has proper meta tags�[32m 20�[2mms�[22m�[39m
 �[32m✓�[39m tests/e2e/pipeline.test.ts�[2m > �[22mEventRelay E2E — Live Deployment�[2m > �[22mStatic Assets�[2m > �[22m/features page returns 200�[32m 45�[2mms�[22m�[39m

�[2m Test Files �[22m �[1m�[32m1 passed�[39m�[22m�[90m (1)�[39m
�[2m      Tests �[22m �[1m�[32m17 passed�[39m�[22m�[90m (17)�[39m
�[2m   Start at �[22m 07:56:20
�[2m   Duration �[22m 56.21s�[2m (transform 51ms, setup 0ms, import 66ms, tests 56.03s, environment 0ms)�[22m


@groupthinking
groupthinking enabled auto-merge (squash) May 1, 2026 22:16
@groupthinking

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot added the frontend label May 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

frontend javascript Pull requests that update javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants