Skip to content

refactor: move table-renderer to component/, add KEEP_ALIVE E2E mode - #273

Closed
alfredo1996 wants to merge 3 commits into
improve/charts-integrationfrom
improve/charts
Closed

refactor: move table-renderer to component/, add KEEP_ALIVE E2E mode#273
alfredo1996 wants to merge 3 commits into
improve/charts-integrationfrom
improve/charts

Conversation

@alfredo1996

@alfredo1996 alfredo1996 commented Mar 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • Move TableRenderer from app/ to component/src/components/composed/ — table now follows the same design system as all other chart components (Closes refactor: move table-renderer to component/ package (design system) #256)
  • Add KEEP_ALIVE=1 E2E mode using Testcontainers .withReuse() — subsequent test runs skip container/server startup (~3s vs ~5min)
  • Add npm run test:e2e:fast convenience script
  • Make Neo4j and PostgreSQL seeding idempotent for container reuse

Test plan

  • Component tests pass (81 files, 1202 tests)
  • App tests pass (89 files, 1550 tests)
  • Connection tests pass (27 files, 193 tests)
  • E2E tests pass
  • CI green
  • SonarCloud quality gate

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added fast e2e test mode (test:e2e:fast) for quicker test execution by reusing server and database containers across test runs.
  • Chores

    • Reorganized component library exports for better modularity.
    • Updated project configuration to exclude additional test runtime artifacts.

@coderabbitai

coderabbitai Bot commented Mar 30, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (3)
  • main
  • dev
  • release/.*

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 77b34007-0f8c-493c-8068-5f655b5a4cd7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Refactored table-renderer to the component package with updated imports in app code. Added KEEP_ALIVE support to e2e setup/teardown for conditional server and container reuse with idempotent database seeding. Added test:e2e:fast npm script to enable faster test reruns.

Changes

Cohort / File(s) Summary
E2E Infrastructure - Setup & Teardown
app/e2e/global-setup.ts, app/e2e/global-teardown.ts
Introduced KEEP_ALIVE mechanism for server reuse across runs. Setup attempts to reuse existing Next.js server and containers when KEEP_ALIVE is enabled, with idempotent Neo4j and PostgreSQL seeding. Teardown conditionally skips cleanup when KEEP_ALIVE is true.
E2E Configuration
.gitignore, package.json
Added exclusions for e2e runtime artifacts (.server-pid, .keep-alive) and new test:e2e:fast npm script with KEEP_ALIVE=1 flag.
Table Renderer Refactoring
component/src/components/composed/table-renderer.tsx, component/src/components/composed/index.ts
Moved parseGroupByColumns from app to component package. Updated imports for shared components from @neoboard/components to local paths. Exposed TableRenderer and TableRendererProps in composed components public API.
App Chart Renderer
app/src/components/chart-renderer.tsx
Updated TableRenderer import to use @neoboard/components instead of local path, reflecting move to component package.
App Table Utilities
app/src/lib/table-utils.ts
Removed parseGroupByColumns function after relocation to component package.
Component Tests
component/src/components/composed/__tests__/table-renderer.test.ts
Updated parseGroupByColumns import source to new location in table-renderer, reformatted test assertions for readability.

Sequence Diagram

sequenceDiagram
    participant Setup as Global Setup
    participant FileFS as File System
    participant Server as Next.js Server
    participant Postgres as PostgreSQL<br/>Container
    participant Neo4j as Neo4j<br/>Container

    Setup->>FileFS: Check if KEEP_ALIVE enabled<br/>(env or file)
    alt KEEP_ALIVE Enabled
        Setup->>FileFS: Read SERVER_PID_FILE
        Setup->>Server: Verify PID alive &<br/>port accepting
        alt Server Alive
            Setup->>Server: Reuse existing server
            Setup->>Postgres: Verify running (reuse)
            Setup->>Neo4j: Verify running (reuse)
            Setup->>Postgres: Count rows in "user"<br/>(idempotent check)
            alt No rows exist
                Setup->>Postgres: Seed database
            end
            Setup->>Neo4j: Count nodes<br/>(idempotent check)
            alt No nodes exist
                Setup->>Neo4j: Seed with init.cypher
            end
        else Server Dead
            Setup->>Server: Start new server
            Setup->>FileFS: Save SERVER_PID_FILE
        end
    else KEEP_ALIVE Disabled
        Setup->>Server: Start fresh server
        Setup->>Postgres: Start container
        Setup->>Neo4j: Start container
        Setup->>Postgres: Seed database
        Setup->>Neo4j: Seed with init.cypher
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

enhancement, pkg:component, pkg:app, area:charts

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Out of Scope Changes check ❓ Inconclusive The KEEP_ALIVE E2E optimization is beyond the scope of issue #256 (table-renderer move), though beneficial for development. The move itself is fully in-scope. Clarify whether E2E improvements belong in this PR or should be split into a separate issue/PR for tracking purposes.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the two main changes: moving table-renderer to component/ and adding KEEP_ALIVE E2E mode. Both changes are prominent in the changeset.
Linked Issues check ✅ Passed The PR fulfills #256 requirements: moves table-renderer from app/ to component/src/components/composed/, maintains component API pattern, ensures design system alignment, and maintains test coverage with exports.
Docstring Coverage ✅ Passed Docstring coverage is 85.71% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch improve/charts

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

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

Inline comments:
In `@app/e2e/global-setup.ts`:
- Around line 139-150: The code only unlinks KEEP_ALIVE_FILE when keepAlive is
false but doesn't stop previously left running servers/containers, so add a
pre-bootstrap cleanup when keepAlive is false AND KEEP_ALIVE_FILE existed:
detect the transition (read existence of KEEP_ALIVE_FILE before removal), and if
it existed, call the existing shutdown/cleanup routine or explicitly stop
processes bound to serverPort (using the same serverPort variable) and stop any
test containers before continuing; ensure KEEP_ALIVE_FILE is still removed after
successful cleanup.

In `@app/e2e/global-teardown.ts`:
- Around line 12-26: The early return inside the KEEP_ALIVE check prevents
finalizeCoverage(...) from running for KEEP_ALIVE runs; move or call
finalizeCoverage(...) before returning (or extract it into a helper and always
invoke it) so coverage finalization always executes even when keepAlive is true;
update the KEEP_ALIVE block in global-teardown.ts (the keepAlive boolean check
and the console/logging block) to call finalizeCoverage(...) (or call a new
ensureCoverageFinalized() helper) prior to returning so finalizeCoverage(...) is
never skipped.

In `@component/src/components/composed/table-renderer.tsx`:
- Around line 4-8: The EmptyState component is being passed a className from
table-renderer.tsx but EmptyStateProps lacks that prop, causing type errors;
update the EmptyState API by adding an optional className?: string to the
EmptyStateProps type in the EmptyState component (empty-state.tsx) and ensure
the EmptyState component forwards that className to its root element (preserve
existing styling behavior), so calls from table-renderer.tsx (where EmptyState
is used) remain valid.
🪄 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: CHILL

Plan: Pro

Run ID: 365358cf-e703-4351-84a1-e54d050d3794

📥 Commits

Reviewing files that changed from the base of the PR and between 6f01cf8 and b9ba65a.

📒 Files selected for processing (9)
  • .gitignore
  • app/e2e/global-setup.ts
  • app/e2e/global-teardown.ts
  • app/src/components/chart-renderer.tsx
  • app/src/lib/table-utils.ts
  • component/src/components/composed/__tests__/table-renderer.test.ts
  • component/src/components/composed/index.ts
  • component/src/components/composed/table-renderer.tsx
  • package.json
💤 Files with no reviewable changes (1)
  • app/src/lib/table-utils.ts

Comment thread app/e2e/global-setup.ts
Comment on lines +139 to +150
const keepAlive = process.env.KEEP_ALIVE === "1";
const serverPort =
parseInt(process.env.TEST_SERVER_PORT || "3100", 10) || 3100;

console.log("\n⏳ Starting test containers...\n");
// Write/clean KEEP_ALIVE marker for teardown (env vars don't always propagate)
if (keepAlive) {
fs.writeFileSync(KEEP_ALIVE_FILE, "1");
} else {
try {
fs.unlinkSync(KEEP_ALIVE_FILE);
} catch {}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Handle KEEP_ALIVE → normal mode transition before bootstrapping.

When a previous run used KEEP_ALIVE, normal mode (Line 139 false path) only removes .keep-alive, but it does not stop old server/containers before starting new ones. Then Line 352 can pass against the old server, even if the newly spawned server failed to bind the port. Result: tests may run against stale state and old resources can leak.

Suggested fix direction
+// Before starting new containers/server in non-KEEP_ALIVE mode,
+// explicitly clean previously kept-alive resources (PID + state file).
+if (!keepAlive) {
+  // 1) Stop prior server if SERVER_PID_FILE exists
+  // 2) Remove prior containers if STATE_FILE exists
+  // 3) Remove stale marker/pid/state files
+}

Also applies to: 250-257, 309-316, 351-353

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/e2e/global-setup.ts` around lines 139 - 150, The code only unlinks
KEEP_ALIVE_FILE when keepAlive is false but doesn't stop previously left running
servers/containers, so add a pre-bootstrap cleanup when keepAlive is false AND
KEEP_ALIVE_FILE existed: detect the transition (read existence of
KEEP_ALIVE_FILE before removal), and if it existed, call the existing
shutdown/cleanup routine or explicitly stop processes bound to serverPort (using
the same serverPort variable) and stop any test containers before continuing;
ensure KEEP_ALIVE_FILE is still removed after successful cleanup.

Comment on lines +12 to +26
// KEEP_ALIVE: leave containers + server running for the next run.
const keepAlive =
process.env.KEEP_ALIVE === "1" || fs.existsSync(KEEP_ALIVE_FILE);
if (keepAlive) {
console.log(
"\n♻️ KEEP_ALIVE=1 — skipping teardown. Server and containers stay alive.",
);
console.log(
" Next run with KEEP_ALIVE=1 will reuse them (~2 min instead of ~25 min).",
);
console.log(
" To stop: KEEP_ALIVE=0 npx playwright test, or kill manually.\n",
);
return;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

KEEP_ALIVE path skips coverage finalization.

Because of the early return at Lines 15-25, finalizeCoverage(...) at Lines 72-79 is never reached when KEEP_ALIVE=1. That can silently drop E2E coverage output for KEEP_ALIVE runs.

Suggested fix
   if (keepAlive) {
+    if (process.env.E2E_COVERAGE) {
+      const nextcovConfig = await loadNextcovConfig(
+        path.resolve(__dirname, "..", "playwright.config.ts"),
+      );
+      await finalizeCoverage(nextcovConfig);
+    }
     console.log(
       "\n♻️  KEEP_ALIVE=1 — skipping teardown. Server and containers stay alive.",
     );

Also applies to: 72-79

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/e2e/global-teardown.ts` around lines 12 - 26, The early return inside the
KEEP_ALIVE check prevents finalizeCoverage(...) from running for KEEP_ALIVE
runs; move or call finalizeCoverage(...) before returning (or extract it into a
helper and always invoke it) so coverage finalization always executes even when
keepAlive is true; update the KEEP_ALIVE block in global-teardown.ts (the
keepAlive boolean check and the console/logging block) to call
finalizeCoverage(...) (or call a new ensureCoverageFinalized() helper) prior to
returning so finalizeCoverage(...) is never skipped.

Comment on lines +4 to +8
import { EmptyState } from "./empty-state";
import { DataGrid } from "./data-grid";
import { DataGridColumnHeader } from "./data-grid-column-header";
import { DataGridViewOptions } from "./data-grid-view-options";
import { DataGridPagination } from "./data-grid-pagination";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

EmptyState API mismatch will break type-checking.

After switching to local ./empty-state, Line 298 still passes className, but that prop is not in EmptyStateProps for component/src/components/composed/empty-state.tsx.

💡 Minimal fix in this file
-    return <EmptyState title={emptyMessage} className="py-6" />;
+    return <EmptyState title={emptyMessage} />;

Also applies to: 295-299

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@component/src/components/composed/table-renderer.tsx` around lines 4 - 8, The
EmptyState component is being passed a className from table-renderer.tsx but
EmptyStateProps lacks that prop, causing type errors; update the EmptyState API
by adding an optional className?: string to the EmptyStateProps type in the
EmptyState component (empty-state.tsx) and ensure the EmptyState component
forwards that className to its root element (preserve existing styling
behavior), so calls from table-renderer.tsx (where EmptyState is used) remain
valid.

Closes #256

Table move:
- Move TableRenderer from app/ to component/src/components/composed/
- Inline parseGroupByColumns utility, export for testing
- Move test to component/__tests__/table-renderer.test.ts
- Update chart-renderer.tsx import to @neoboard/components

KEEP_ALIVE E2E mode:
- Use Testcontainers .withReuse() for container reuse across runs
- Add server PID reuse check (skip spawn if already running)
- Make Neo4j and PostgreSQL seeding idempotent (skip if data exists)
- Teardown skips cleanup when KEEP_ALIVE marker is present
- Add `npm run test:e2e:fast` convenience script

First run: ~5 min (normal). Subsequent runs: ~3 sec setup + test time.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
E2E global setup/teardown is test infrastructure — not application code.
Cannot be unit-tested and shouldn't count toward coverage gate.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
5.2% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@alfredo1996
alfredo1996 changed the base branch from release/1.0 to improve/charts-integration March 30, 2026 21:16
- Add cleanupPreviousRun() to stop stale server/containers when switching
  from KEEP_ALIVE to normal mode, preventing resource leaks
- Move finalizeCoverage() before KEEP_ALIVE early return in teardown so
  coverage reports are always generated regardless of mode

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@alfredo1996 alfredo1996 added this to the v1.0 — Community Launch milestone Mar 31, 2026
@alfredo1996

Copy link
Copy Markdown
Owner Author

Superseded by #282 (merged).

@alfredo1996
alfredo1996 deleted the improve/charts branch April 7, 2026 11:47
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.

2 participants