Skip to content

feat: persist swagger schemas - #84

Merged
AlyaEngineer merged 2 commits into
developfrom
story/3-schema-persistence
Jul 13, 2026
Merged

feat: persist swagger schemas#84
AlyaEngineer merged 2 commits into
developfrom
story/3-schema-persistence

Conversation

@Ivan-khodorov

@Ivan-khodorov Ivan-khodorov commented Jul 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

Closes #44

Adds schema persistence for authenticated users in the Swagger Editor.

What Changed

  • Added server-side schema restore on the main page.
  • Passes restored schema into SwaggerEditor as initialSchema.
  • Removed client-side schema restore from useSwagger to avoid empty editor flicker after mount.
  • Removed fake auth from useSwagger.
  • Added /api/schema POST route for saving schemas.
  • Saves raw schema text and format (json / yaml) instead of only parsed JSON.
  • Saves schemas per authenticated user through Supabase.
  • Added Supabase SQL for public.schemas table and RLS own-user policies.
  • Added tests for:
    • save only when schema is valid;
    • saved payload includes raw text and format;
    • server restore reaches editor initial prop;
    • API route validation/statuses;
    • Supabase restore/save behavior.

Affected Files

  • src/app/[locale]/page.tsx
  • src/app/[locale]/page.test.tsx
  • src/app/api/schema/route.ts
  • src/app/api/schema/route.test.ts
  • src/components/swagger-control/swagger-control.test.tsx
  • src/components/swagger-editor/swagger-editor.tsx
  • src/components/swagger-editor/swagger-editor.test.tsx
  • src/services/schema-persistence.ts
  • src/services/schema-server-service.ts
  • src/services/schema-server-service.test.ts
  • src/services/schema-service.ts
  • src/utils/hooks/use-swagger.ts
  • src/utils/hooks/use-swagger.test.ts
  • supabase/schema-persistence.sql

Validation

  • npm test
  • npm run lint
  • npm run build
  • git diff --check

Manual Check Required

  • Apply supabase/schema-persistence.sql in Supabase.
  • Verify RLS: two users cannot read each other's schemas.
  • Verify full cycle: save schema → sign out → sign in → schema is restored in the editor.
  • Verify restored schema appears without empty editor flicker.

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Saved schemas are now fetched and loaded automatically when opening the editor.
    • Added authenticated schema persistence for saving schema content and format for later sessions.
    • Introduced a schema API endpoint with validation and clear success/error responses.
  • Bug Fixes

    • Improved input validation so invalid schema payloads no longer trigger saves.
  • Tests

    • Added/updated tests for editor initialization, schema restoration, schema saving, API validation, and unauthorized/error scenarios.

@Ivan-khodorov Ivan-khodorov linked an issue Jul 12, 2026 that may be closed by this pull request
@vercel

vercel Bot commented Jul 12, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
swagger-editor-app Ready Ready Preview, Comment Jul 13, 2026 6:22pm

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds Supabase-backed schema persistence for authenticated users, a POST API route for saving schemas, server-side restoration in the locale page, and initial-schema wiring through SwaggerEditor and useSwagger, with corresponding tests.

Changes

Schema persistence flow

Layer / File(s) Summary
Persistence contract and server storage
src/services/schema-persistence.ts, supabase/schema-persistence.sql, src/services/schema-server-service.ts, src/services/schema-server-service.test.ts
Defines validated saved-schema records, creates the per-user Supabase table and RLS policies, and implements authenticated save and restore operations.
Save API and client integration
src/app/api/schema/route.ts, src/app/api/schema/route.test.ts, src/services/schema-service.ts, src/components/swagger-control/*
Adds schema POST handling with validation and authorization responses, updates the client save request, and tests valid, invalid, and unauthorized saves.
Server restoration and editor initialization
src/app/[locale]/page.tsx, src/app/[locale]/page.test.tsx, src/components/swagger-editor/*, src/utils/hooks/use-swagger.*
Loads saved schemas in the page component and passes them through SwaggerEditor into useSwagger as initial editor content and format.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Home
  participant SchemaServerService
  participant Supabase
  participant SwaggerEditor
  participant SchemaService
  Home->>SchemaServerService: restoreSchemaForCurrentUser()
  SchemaServerService->>Supabase: query authenticated user's schema
  Supabase-->>SchemaServerService: saved content and format
  Home->>SwaggerEditor: pass initialSchema
  SwaggerEditor->>SchemaService: save schema
  SchemaService->>Home: return save response
Loading

Possibly related PRs

Suggested reviewers: lexarudak, yuliademir

🚥 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately describes the main change: persisting Swagger schemas.
Linked Issues check ✅ Passed The PR meets #44: it saves raw content and format, restores on the server into the editor prop, and adds validity-gated save tests.
Out of Scope Changes check ✅ Passed No clearly unrelated changes are present; the diffs stay focused on schema persistence, restore flow, and related tests.
✨ 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 story/3-schema-persistence

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

@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: 1

🧹 Nitpick comments (3)
src/app/api/schema/route.test.ts (1)

44-51: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing test for the result === 'error' → 500 branch.

Tests cover 200/400/401 but not the 500 case handled in the route.

✅ Suggested additional test
   it('returns unauthorized when there is no authenticated user', async () => {
     mockSaveSchemaForCurrentUser.mockResolvedValue('unauthorized');

     const response = await POST(createRequest({ content: 'openapi: 3.0.0', format: 'yaml' }));

     expect(response.status).toBe(401);
   });
+
+  it('returns a server error when saving fails', async () => {
+    mockSaveSchemaForCurrentUser.mockResolvedValue('error');
+
+    const response = await POST(createRequest({ content: 'openapi: 3.0.0', format: 'yaml' }));
+
+    expect(response.status).toBe(500);
+  });
 });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/api/schema/route.test.ts` around lines 44 - 51, Add a test alongside
the existing POST route cases in schema route.test.ts that configures
mockSaveSchemaForCurrentUser to resolve to 'error', invokes POST with a valid
schema request, and asserts the response status is 500.
src/services/schema-server-service.test.ts (1)

35-87: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for the authenticated-but-Supabase-error branches.

Tests cover success and unauthenticated paths for both functions, but not the case where the user is authenticated and Supabase returns an error (e.g., RLS denial or DB failure) on maybeSingle()/upsert(). Those branches (error || !isSavedSchema(data) and error ? 'error' : 'saved') are untested.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/services/schema-server-service.test.ts` around lines 35 - 87, The tests
for restoreSchemaForCurrentUser and saveSchemaForCurrentUser cover success and
unauthenticated cases but omit authenticated Supabase-error paths. Add tests
with an authenticated user where mockMaybeSingle returns an error and where
mockUpsert returns an error, asserting the restore function returns null and the
save function returns 'error', respectively.
src/services/schema-server-service.ts (1)

7-56: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Supabase failures are silently swallowed with no logging or exception guarding.

Every Supabase call here (auth.getUser(), select(), upsert()) only checks the error field and falls back to null/'error' without ever logging — production save/restore failures (RLS denials, network errors, misconfig) become invisible. There's also no try/catch around createClient()/getUser(), so an unexpected thrown exception (vs. a returned error object) would propagate uncaught into the Server Component render path (page.tsx) instead of degrading gracefully.

♻️ Proposed fix: log errors and guard against thrown exceptions
 async function getCurrentUserId() {
-  const supabase = await createClient();
-  const { data, error } = await supabase.auth.getUser();
-
-  if (error || !data.user) {
-    return { supabase, userId: null };
-  }
-
-  return { supabase, userId: data.user.id };
+  const supabase = await createClient();
+
+  try {
+    const { data, error } = await supabase.auth.getUser();
+
+    if (error || !data.user) {
+      if (error) console.error('Failed to resolve current user', error);
+      return { supabase, userId: null };
+    }
+
+    return { supabase, userId: data.user.id };
+  } catch (unexpectedError) {
+    console.error('Unexpected error resolving current user', unexpectedError);
+    return { supabase, userId: null };
+  }
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/services/schema-server-service.ts` around lines 7 - 56, Update
restoreSchemaForCurrentUser, saveSchemaForCurrentUser, and getCurrentUserId to
log Supabase errors with relevant operation context, and wrap createClient(),
auth.getUser(), select(), and upsert() flows in try/catch guards. Preserve the
existing null, unauthorized, and 'error' fallback results while ensuring both
returned Supabase errors and thrown exceptions are logged and do not escape the
Server Component render path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app/api/schema/route.ts`:
- Around line 1-22: Update POST to validate the parsed payload with
validateSwaggerSchema after isSavedSchema and before saveSchemaForCurrentUser;
reject invalid OpenAPI content with the existing 400 invalid-payload response,
while preserving the current authorization and save-error handling.

---

Nitpick comments:
In `@src/app/api/schema/route.test.ts`:
- Around line 44-51: Add a test alongside the existing POST route cases in
schema route.test.ts that configures mockSaveSchemaForCurrentUser to resolve to
'error', invokes POST with a valid schema request, and asserts the response
status is 500.

In `@src/services/schema-server-service.test.ts`:
- Around line 35-87: The tests for restoreSchemaForCurrentUser and
saveSchemaForCurrentUser cover success and unauthenticated cases but omit
authenticated Supabase-error paths. Add tests with an authenticated user where
mockMaybeSingle returns an error and where mockUpsert returns an error,
asserting the restore function returns null and the save function returns
'error', respectively.

In `@src/services/schema-server-service.ts`:
- Around line 7-56: Update restoreSchemaForCurrentUser,
saveSchemaForCurrentUser, and getCurrentUserId to log Supabase errors with
relevant operation context, and wrap createClient(), auth.getUser(), select(),
and upsert() flows in try/catch guards. Preserve the existing null,
unauthorized, and 'error' fallback results while ensuring both returned Supabase
errors and thrown exceptions are logged and do not escape the Server Component
render path.
🪄 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 Plus

Run ID: 79f5c3f0-8d4e-4445-9239-ab432ad1bf07

📥 Commits

Reviewing files that changed from the base of the PR and between 87d1003 and f6a21a9.

📒 Files selected for processing (14)
  • src/app/[locale]/page.test.tsx
  • src/app/[locale]/page.tsx
  • src/app/api/schema/route.test.ts
  • src/app/api/schema/route.ts
  • src/components/swagger-control/swagger-control.test.tsx
  • src/components/swagger-editor/swagger-editor.test.tsx
  • src/components/swagger-editor/swagger-editor.tsx
  • src/services/schema-persistence.ts
  • src/services/schema-server-service.test.ts
  • src/services/schema-server-service.ts
  • src/services/schema-service.ts
  • src/utils/hooks/use-swagger.test.ts
  • src/utils/hooks/use-swagger.ts
  • supabase/schema-persistence.sql

Comment thread src/app/api/schema/route.ts
@AlyaEngineer AlyaEngineer added the feature-3-editor Feature 3: Swagger Editor label Jul 12, 2026
@AlyaEngineer
AlyaEngineer self-requested a review July 12, 2026 21:50
AlyaEngineer
AlyaEngineer previously approved these changes Jul 12, 2026

@AlyaEngineer AlyaEngineer left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

оперативно :)

@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.

🧹 Nitpick comments (1)
src/app/api/schema/route.test.ts (1)

52-58: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider asserting the call args, not just the status code.

This test only checks response.status. Adding an assertion that mockSaveSchemaForCurrentUser was called with the expected payload would strengthen coverage of the unauthorized branch, consistent with the success test at Line 26.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/api/schema/route.test.ts` around lines 52 - 58, Strengthen the
unauthorized test by asserting that mockSaveSchemaForCurrentUser was called with
the expected schema payload and format, matching the argument assertion used in
the success test while retaining the existing 401 status assertion.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/app/api/schema/route.test.ts`:
- Around line 52-58: Strengthen the unauthorized test by asserting that
mockSaveSchemaForCurrentUser was called with the expected schema payload and
format, matching the argument assertion used in the success test while retaining
the existing 401 status assertion.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: adb71ea2-b65d-41b8-b68c-547e9024c17c

📥 Commits

Reviewing files that changed from the base of the PR and between f6a21a9 and b96b41e.

📒 Files selected for processing (4)
  • src/app/api/schema/route.test.ts
  • src/app/api/schema/route.ts
  • src/services/schema-server-service.test.ts
  • src/services/schema-server-service.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/app/api/schema/route.ts
  • src/services/schema-server-service.ts

@AlyaEngineer
AlyaEngineer requested a review from lexarudak July 13, 2026 17:24
@AlyaEngineer
AlyaEngineer merged commit 8447b6d into develop Jul 13, 2026
3 checks passed
@AlyaEngineer
AlyaEngineer deleted the story/3-schema-persistence branch July 13, 2026 18:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature-3-editor Feature 3: Swagger Editor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Schema persistence

3 participants