Skip to content

Conversation

MH4GF
Copy link
Member

@MH4GF MH4GF commented Oct 7, 2025

Issue

  • resolve:

Why is this change needed?

Add a new /erd/demo/[...slug] route that displays pre-parsed schema JSON from GitHub URLs.

Unlike /erd/p which parses raw schema files (SQL, Prisma, etc.), /erd/demo expects JSON that already matches the Schema type and validates it using valibot's schemaSchema.

Summary

  • Add /erd/demo/[...slug] page component
  • Fetch JSON from GitHub URLs (converts blob URLs to raw URLs automatically)
  • Validate JSON against schemaSchema using valibot
  • Error handling for network failures, JSON parsing errors, and schema validation failures
  • Reuse ERDViewer component from /erd/p route

Test plan

  • Visit /erd/demo/[github-url-to-schema-json] and verify ERD is displayed
  • Test with invalid JSON and verify error handling
  • Test with invalid schema format and verify validation error
  • Test with network failures and verify error messages

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added an ERD Demo page that loads JSON schemas from shared URLs and renders them in an ERD viewer.
    • Improved validation and clear error messaging for network, parsing, and schema issues.
    • Enhanced share previews with dynamic titles and images.
    • Remembers sidebar visibility and panel sizes via cookies.
  • Tests

    • Added comprehensive schema datasets to support rich demo scenarios and end-to-end test cases.

Add /erd/demo/[...slug] route that displays pre-parsed schema JSON from GitHub URLs. Unlike /erd/p which parses raw schema files, /erd/demo expects JSON that matches the Schema type and validates it with valibot.

Features:
- Fetch JSON from GitHub URLs (converts blob URLs to raw URLs)
- Validate against schemaSchema
- Error handling for network, JSON parsing, and validation failures
- Share ERDViewer component with /erd/p route

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link

changeset-bot bot commented Oct 7, 2025

⚠️ No Changeset found

Latest commit: 1789684

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link

vercel bot commented Oct 7, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
liam-app Ready Ready Preview Comment Oct 7, 2025 1:00am
liam-assets Ready Ready Preview Comment Oct 7, 2025 1:00am
liam-erd-sample Ready Ready Preview Comment Oct 7, 2025 1:00am
liam-storybook Ready Ready Preview Comment Oct 7, 2025 1:00am
1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
liam-docs Ignored Ignored Preview Oct 7, 2025 1:00am

Copy link
Contributor

coderabbitai bot commented Oct 7, 2025

Walkthrough

Adds a new ERD demo Next.js page that resolves a content URL, fetches JSON, validates it against a schema, handles errors, and renders an ERD viewer with cookie-derived UI state and metadata. Also introduces three JSON schema fixtures representing complex database schemas for testing.

Changes

Cohort / File(s) Summary
ERD demo page implementation
frontend/apps/app/app/erd/demo/[...slug]/page.tsx
New route component: parses params, resolves GitHub/raw URLs, fetches JSON (no-cache), parses/validates against schemaSchema, reads cookies for UI defaults, generates metadata, and renders ERDViewer with success/error states.
Procurement/ERP schema fixtures
pm-testcases-*.json
Adds large JSON fixtures describing comprehensive relational schemas with tables, columns, indexes, and constraints for procurement flows (RFQs, quotations, POs, receipts). Files: pm-testcases-before.json, pm-testcases-after.json, pm-testcases-case-001.json.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User Browser
  participant R as Next.js Route Page
  participant UR as URL Resolver
  participant F as Fetch
  participant JP as JSON Parser
  participant SV as Schema Validator
  participant CK as Cookie Store
  participant V as ERDViewer

  U->>R: Navigate to /erd/demo/[...slug]
  R->>CK: Read cookies (sidebar, panellayout)
  R->>UR: Build and resolve content URL
  alt Valid content URL
    R->>F: fetch(contentUrl, { cache: "no-store" })
    alt 200 OK
      F-->>R: Response
      R->>JP: Parse JSON
      alt JSON parsed
        R->>SV: Validate against schemaSchema
        alt Valid schema
          R->>V: Render ERDViewer(schema, uiState)
        else ValidationError
          R->>V: Render ERDViewer(empty, errors=[ValidationError])
        end
      else ParseError
        R->>V: Render ERDViewer(empty, errors=[ParseError])
      end
    else NetworkError/Non-OK
      R->>V: Render ERDViewer(empty, errors=[NetworkError])
    end
  else Invalid URL
    R->>V: Render ERDViewer(empty, errors=[InvalidURL])
  end

  note over R,V: Metadata generated from slug (title, OG)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

Review effort 4/5

Suggested reviewers

  • hoshinotsuyoshi
  • FunamaYukina
  • NoritakaIkeda

Poem

Hop hop! I fetched a schema bright,
Cookies set the panels right.
If JSON stumbles, I won’t despair—
I’ll show the errors, plain and fair.
ERDs bloom across the screen,
Procurement dreams in structured green. 🐇📜✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The description includes the required Issue and Why is this change needed sections but leaves the resolve field blank under Issue, so the template’s required information is incomplete. Please fill in the resolve field with the related issue number or mark it as “n/a” if there is no linked issue to fully satisfy the template requirements.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The title clearly and concisely summarizes the primary change by indicating the addition of an ERD demo page for pre-parsed schema JSON and aligns directly with the pull request’s contents.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch show-erd

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link

supabase bot commented Oct 7, 2025

Updates to Preview Branch (show-erd) ↗︎

Deployments Status Updated
Database Tue, 07 Oct 2025 00:56:32 UTC
Services Tue, 07 Oct 2025 00:56:32 UTC
APIs Tue, 07 Oct 2025 00:56:32 UTC

Tasks are run on every commit but only new migration files are pushed.
Close and reopen this PR if you want to apply changes from existing seed or migration files.

Tasks Status Updated
Configurations Tue, 07 Oct 2025 00:56:37 UTC
Migrations Tue, 07 Oct 2025 00:56:40 UTC
Seeding Tue, 07 Oct 2025 00:56:40 UTC
Edge Functions Tue, 07 Oct 2025 00:56:40 UTC

View logs for this Workflow Run ↗︎.
Learn more about Supabase for Git ↗︎.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 630b3ee and 1789684.

📒 Files selected for processing (4)
  • frontend/apps/app/app/erd/demo/[...slug]/page.tsx (1 hunks)
  • pm-testcases-after.json (1 hunks)
  • pm-testcases-before.json (1 hunks)
  • pm-testcases-case-001.json (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Name React component files in PascalCase and use TSX (e.g., App.tsx)

Prefix event handler functions with “handle” (e.g., handleClick)

Files:

  • frontend/apps/app/app/erd/demo/[...slug]/page.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript/TSX across the codebase

**/*.{ts,tsx}: Prefer early returns for readability
Use named exports only (no default exports)
Prefer const arrow functions over function declarations for simple utilities (e.g., const toggle = () => {})

Files:

  • frontend/apps/app/app/erd/demo/[...slug]/page.tsx
frontend/apps/**

📄 CodeRabbit inference engine (AGENTS.md)

Next.js apps live under frontend/apps; target app-specific scripts and configs there

Files:

  • frontend/apps/app/app/erd/demo/[...slug]/page.tsx
frontend/apps/**/app/**/page.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Do not implement page logic directly in page.tsx; create separate page components

Files:

  • frontend/apps/app/app/erd/demo/[...slug]/page.tsx
frontend/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Follow existing import patterns and tsconfig path aliases

Files:

  • frontend/apps/app/app/erd/demo/[...slug]/page.tsx
frontend/apps/**/app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

frontend/apps/**/app/**/*.{ts,tsx}: Use Server Components for server-side data fetching
Do client-side data fetching only when necessary
Align data fetching responsibilities with component roles
Use Server Actions for all data mutations (create/update/delete)

Files:

  • frontend/apps/app/app/erd/demo/[...slug]/page.tsx
🧬 Code graph analysis (1)
frontend/apps/app/app/erd/demo/[...slug]/page.tsx (1)
frontend/apps/app/app/erd/p/[...slug]/erdViewer.tsx (1)
  • ERDViewer (23-59)
⏰ 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: frontend-lint
  • GitHub Check: frontend-ci
  • GitHub Check: security-review
  • GitHub Check: Supabase Preview

Comment on lines +13 to +27
const resolveContentUrl = (url: string): string | undefined => {
try {
const parsedUrl = new URL(url)

if (parsedUrl.hostname === 'github.com' && url.includes('/blob/')) {
return url
.replace('github.com', 'raw.githubusercontent.com')
.replace('/blob', '')
}

return url
} catch {
return undefined
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Block SSRF by allowlisting trusted hosts

resolveContentUrl currently returns any https://${joinedPath} that a visitor supplies. Because the slug comes straight from the request path, an attacker can coerce the server into fetching arbitrary HTTPS endpoints (e.g. internal control planes or metadata services), which is a classic SSRF vector. Please harden this by restricting outbound fetches to the small set of hosts we trust (e.g. GitHub blob/raw) and reject everything else.

+const ALLOWED_SCHEMA_HOSTS = new Set([
+  'github.com',
+  'raw.githubusercontent.com',
+  'gist.githubusercontent.com',
+])
+
 const resolveContentUrl = (url: string): string | undefined => {
   try {
     const parsedUrl = new URL(url)
 
+    if (parsedUrl.protocol !== 'https:' || !ALLOWED_SCHEMA_HOSTS.has(parsedUrl.hostname)) {
+      return undefined
+    }
+
     if (parsedUrl.hostname === 'github.com' && url.includes('/blob/')) {
       return url
         .replace('github.com', 'raw.githubusercontent.com')
         .replace('/blob', '')
     }
 
-    return url
+    return parsedUrl.toString()
   } catch {
     return undefined
   }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const resolveContentUrl = (url: string): string | undefined => {
try {
const parsedUrl = new URL(url)
if (parsedUrl.hostname === 'github.com' && url.includes('/blob/')) {
return url
.replace('github.com', 'raw.githubusercontent.com')
.replace('/blob', '')
}
return url
} catch {
return undefined
}
}
const ALLOWED_SCHEMA_HOSTS = new Set([
'github.com',
'raw.githubusercontent.com',
'gist.githubusercontent.com',
])
const resolveContentUrl = (url: string): string | undefined => {
try {
const parsedUrl = new URL(url)
if (parsedUrl.protocol !== 'https:' || !ALLOWED_SCHEMA_HOSTS.has(parsedUrl.hostname)) {
return undefined
}
if (parsedUrl.hostname === 'github.com' && url.includes('/blob/')) {
return url
.replace('github.com', 'raw.githubusercontent.com')
.replace('/blob', '')
}
return parsedUrl.toString()
} catch {
return undefined
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant