Skip to content

feat(diagram-views): complete saved-layout update contract - #723

Open
seonghobae wants to merge 23 commits into
mainfrom
feature/update-saved-diagram-view
Open

feat(diagram-views): complete saved-layout update contract#723
seonghobae wants to merge 23 commits into
mainfrom
feature/update-saved-diagram-view

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

What

Completes the in-place saved ERD view contract across backend and frontend API layers.

Backend

Adds an editor-authorized replacement endpoint:

PUT /api/diagram-views/{diagram_view_uuid}

It updates the saved name and complete layout payload while preserving the stable opaque diagram_view_uuid and original creation metadata.

Frontend API foundation

Adds typed, CSRF-protected clients for the complete saved-view lifecycle:

  • list views by project;
  • create a view;
  • get a view with layout state;
  • update a view in place;
  • delete a view.

The demo mode now implements the same CRUD contract in memory so the product can demonstrate saved-layout workflows without a backend.

Product gap closed

The backend previously supported create, list, read, and delete but not update, and the frontend had no typed client for any saved-view endpoint. Users would otherwise have to create duplicate views whenever they adjusted table positions, zoom, or review-oriented layouts. This PR establishes the contract required for explicit Save, overwrite, and later autosave UI.

Safety and correctness

  • requires project editor membership for mutations;
  • returns the same uniform 404 for missing and unauthorized views;
  • enforces the existing 512 KiB serialized layout bound;
  • validates the complete replacement before mutating the persistent object;
  • preserves the stable view identifier and created_at;
  • refreshes updated_at only after authorization and payload validation;
  • keeps layout metadata forward-compatible while typing known positions and viewport fields;
  • sends credentials and CSRF tokens on all mutations;
  • includes focused backend and frontend network/demo regression coverage.

CHANGELOG.md records the commercial saved-view capability.

Summary by CodeRabbit

  • 새로운 기능

    • 저장된 다이어그램 뷰의 이름과 레이아웃을 수정할 수 있습니다.
    • 다이어그램 뷰의 목록 조회, 생성, 상세 조회, 수정 및 삭제를 지원합니다.
    • 데모 모드에서도 다이어그램 뷰를 저장하고 관리할 수 있습니다.
    • 레이아웃 정보에 위치와 화면 영역을 포함한 형식이 적용됩니다.
  • 개선 사항

    • 편집 권한이 없는 뷰에는 접근할 수 없습니다.
    • 레이아웃 크기를 512KB로 제한하며, 초과 데이터는 저장되지 않습니다.
    • 권한이 없거나 존재하지 않는 리소스는 동일한 방식으로 처리됩니다.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@seonghobae, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 9 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1579e5e7-2849-4be1-ab34-9b98e9ca0f0d

📥 Commits

Reviewing files that changed from the base of the PR and between 9c4954f and 0cfb3b6.

📒 Files selected for processing (11)
  • .env.example
  • CHANGELOG.md
  • backend/app/main.py
  • backend/app/request_body_limit.py
  • backend/app/settings.py
  • backend/pyproject.toml
  • backend/tests/test_api_diagram_views.py
  • backend/tests/test_request_body_limit.py
  • docs/doctoring/request-body-and-saved-view-resource-limits.md
  • frontend/src/api.ts
  • frontend/src/diagramViewsApi.test.ts
📝 Walkthrough

Walkthrough

다이어그램 뷰의 타입과 CRUD API를 추가했습니다. 백엔드는 편집자 권한, 404 응답, 512KB 레이아웃 제한을 적용합니다. 프론트엔드는 실제 HTTP 모드와 데모 메모리 모드를 지원합니다. 양쪽 동작을 테스트로 검증합니다.

Changes

다이어그램 뷰 CRUD

Layer / File(s) Summary
백엔드 수정 API
backend/app/api/diagram_views.py, CHANGELOG.md
기존 다이어그램 뷰를 이름과 레이아웃으로 갱신하는 PUT 엔드포인트를 추가했습니다. 편집자 권한을 확인하고, 대상이 없거나 권한이 없으면 404를 반환합니다. 레이아웃 크기를 검증한 뒤 수정 시각을 갱신하고 커밋합니다.
백엔드 수정 검증
backend/tests/test_api_diagram_views.py
수정 성공, 식별자와 생성 시각 유지, 권한 부족 시 404, 512KB 초과 시 413 및 변경·커밋 미실행을 검증합니다.
프론트엔드 타입 및 CRUD API
frontend/src/types.ts, frontend/src/api.ts
다이어그램 뷰와 레이아웃 타입을 추가했습니다. 실제 모드의 인증 HTTP 요청과 데모 모드의 프로젝트별 메모리 저장소를 사용해 조회, 생성, 수정, 삭제를 제공합니다.
프론트엔드 CRUD API 검증
frontend/src/diagramViewsApi.test.ts
인증, CSRF 토큰, 요청 본문, HTTP 오류와 데모 모드 CRUD 및 404 처리를 검증합니다.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant frontend_api as frontend/src/api.ts
  participant backend_api as PUT /api/diagram-views/{diagram_view_uuid}
  participant database as AsyncSession
  Client->>frontend_api: updateDiagramView(name, layout_json)
  frontend_api->>backend_api: 인증 PUT 요청 전송
  backend_api->>database: 대상 조회 및 변경사항 커밋
  database-->>backend_api: 갱신된 뷰 반환
  backend_api-->>frontend_api: DiagramView 응답 반환
  frontend_api-->>Client: 갱신된 다이어그램 뷰 반환
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 백엔드 및 프론트엔드 계층 전체에 걸친 저장된 ERD 뷰 업데이트 기능의 추가를 명확하고 간결하게 설명합니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ 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 feature/update-saved-diagram-view

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

@seonghobae
seonghobae enabled auto-merge (squash) August 3, 2026 03:18
@seonghobae seonghobae changed the title feat(diagram-views): update saved layouts in place feat(diagram-views): complete saved-layout update contract Aug 3, 2026
@seonghobae
seonghobae marked this pull request as draft August 3, 2026 03:58
auto-merge was automatically disabled August 3, 2026 03:58

Pull request was converted to draft

@seonghobae
seonghobae marked this pull request as ready for review August 3, 2026 03:58
@seonghobae
seonghobae enabled auto-merge (squash) August 3, 2026 03:58
@seonghobae
seonghobae marked this pull request as draft August 3, 2026 05:48
auto-merge was automatically disabled August 3, 2026 05:48

Pull request was converted to draft

@seonghobae
seonghobae marked this pull request as ready for review August 3, 2026 05:48
@seonghobae
seonghobae enabled auto-merge (squash) August 3, 2026 05:48

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

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.

Copy link
Copy Markdown
Collaborator Author

@opencode-agent @cwl-noema-review Please independently review exact current head 26eb3792a0132f1aebb7d55f6fd6aa55b98aed43. Verify saved-view list/create/read/update/delete contracts, editor authorization, uniform 404 behavior, stable UUID/created_at preservation, size validation, CSRF protection, and demo parity. Exact-head CI, Security Scan, and Semgrep are green; submit APPROVE only if no blocker remains.

Copy link
Copy Markdown
Collaborator Author

@opencode-agent Please review exact head 26eb3792a0132f1aebb7d55f6fd6aa55b98aed43. Repository CI, Security Scan, and Semgrep are green with no unresolved threads. Verify editor authorization, uniform 404 behavior, 512 KiB validation before mutation, stable UUID/created_at preservation, updated_at semantics, CSRF-protected frontend CRUD, and demo/network parity. Submit APPROVE only if no blocker remains.

Copy link
Copy Markdown
Collaborator Author

@cwl-noema-review Please independently review exact head 26eb3792a0132f1aebb7d55f6fd6aa55b98aed43. Confirm the saved-view update and complete CRUD contract preserve authorization, opaque identifiers, validation order, timestamps, and CSRF boundaries; submit APPROVE only if no blocker remains.

Copy link
Copy Markdown
Collaborator Author

@opencode-agent @cwl-noema-review Please independently review exact current head 26eb3792a0132f1aebb7d55f6fd6aa55b98aed43. Current-head CI, Security Scan, and SAST Semgrep are successful and no inline thread is unresolved. Verify editor authorization, uniform missing/unauthorized 404 behavior, 512 KiB serialized-layout bound, validate-before-mutate ordering, stable opaque diagram_view_uuid and created_at, refreshed updated_at, CSRF/credential propagation, demo/network CRUD parity, forward-compatible layout typing, tests, and CHANGELOG. Submit APPROVE only for this exact head if no blocking finding remains.

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

🧹 Nitpick comments (1)
backend/tests/test_api_diagram_views.py (1)

179-200: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

512 KiB 경계를 직접 검증하십시오.

현재 테스트는 600 KiB payload만 거부하는지 확인합니다. 직렬화된 레이아웃이 정확히 512 KiB일 때 허용되고, 1바이트 클 때 413을 반환하는 focused test를 추가하십시오. 이 테스트는 계약값 변경을 검출합니다.

As per coding guidelines, “Add or update focused tests when changing behavior.”

🤖 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 `@backend/tests/test_api_diagram_views.py` around lines 179 - 200, Extend the
focused tests around update_view to cover the 512 KiB boundary using the
serialized layout size: verify a payload exactly 512 KiB is accepted, and a
payload one byte larger raises HTTPException with status 413. Reuse the existing
DiagramViewCreateIn setup and authorization/session mocks, and retain assertions
that rejected updates do not mutate or commit the view.

Source: Coding guidelines

🤖 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 `@backend/app/api/diagram_views.py`:
- Around line 150-165: Add an equivalent request-body size limit at the `/api`
router or upstream middleware so oversized JSON payloads are rejected before
`DiagramViewCreateIn` deserialization and before authentication. Configure the
limit using the existing Traefik/Hypercorn or application request-parsing
mechanism, and retain `_bound_layout_size` as the post-parse validation for
accepted requests.

In `@frontend/src/api.ts`:
- Line 283: Update the demo view ID generation at diagram_view_uuid to include a
module-scoped incrementing sequence or other unique generator alongside
Date.now(), ensuring create calls in the same millisecond receive distinct IDs.
Add a regression test that creates two views with the same timestamp and
verifies each view’s update and delete operations target the correct view.
- Around line 331-337: Update the demo view replacement flow around updated and
demoDiagramViewsByProject so the modified view is repositioned according to
descending updated_at order instead of retaining found.index. Remove the view
from its old position, insert the updated view at the front or sort the
collection by updated_at, and add a regression test covering creation of two
views followed by updating the older one and verifying it appears first.
- Around line 285-292: Apply shared validation before mutating
demoDiagramViewsByProject in both demo create and update paths: require name
length 1–200 characters and reject layout_json whose serialized size exceeds 512
KiB, matching the backend contract. Ensure rejected inputs leave the demo store
unchanged, including before the view is constructed or prepended. Add regression
tests covering rejection and unchanged storage for both create and update.

---

Nitpick comments:
In `@backend/tests/test_api_diagram_views.py`:
- Around line 179-200: Extend the focused tests around update_view to cover the
512 KiB boundary using the serialized layout size: verify a payload exactly 512
KiB is accepted, and a payload one byte larger raises HTTPException with status
413. Reuse the existing DiagramViewCreateIn setup and authorization/session
mocks, and retain assertions that rejected updates do not mutate or commit the
view.
🪄 Autofix

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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 83f6c9fc-2a3c-40e6-bf26-0b218e0bdcc9

📥 Commits

Reviewing files that changed from the base of the PR and between 72afe6d and 9c4954f.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • backend/app/api/diagram_views.py
  • backend/tests/test_api_diagram_views.py
  • frontend/src/api.ts
  • frontend/src/diagramViewsApi.test.ts
  • frontend/src/types.ts

Comment thread backend/app/api/diagram_views.py
Comment thread frontend/src/api.ts Outdated
Comment thread frontend/src/api.ts
Comment thread frontend/src/api.ts Outdated
@opencode-agent
opencode-agent Bot disabled auto-merge August 4, 2026 16:08
@seonghobae
seonghobae enabled auto-merge (squash) August 6, 2026 03:03

Copy link
Copy Markdown
Collaborator Author

@opencode-agent @cwl-noema-review Please perform a fresh independent review of current head 0cfb3b6e35403326bf7b8a511324c8585a834f52. Repository CI, Security Scan, Semgrep, and CodeRabbit are green; all inline threads are resolved. Verify pre-parse API request-size enforcement, exact 512 KiB saved-layout boundaries, mutation atomicity, demo/network CRUD parity, stable IDs, descending update order, CSRF, and authorization behavior.

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