Skip to content

feat: schema-change actionability (migration SQL) + annotations, connection test, coverage#440

Open
seonghobae wants to merge 10 commits into
mainfrom
adhesive-piper
Open

feat: schema-change actionability (migration SQL) + annotations, connection test, coverage#440
seonghobae wants to merge 10 commits into
mainfrom
adhesive-piper

Conversation

@seonghobae

Copy link
Copy Markdown
Collaborator

Goal

Move the product up the value ladder visualize → diff → act → govern, grounded in a full code-knowledge-graph pass. See docs/valuation-gap-analysis.md for the codegraph-informed roadmap.

Highlights (P0 delivered: actionability)

  • Migration SQL from a schema diff (ddl/migration.py) — GET /api/snapshots/{uuid}/migration.sql?against=…&dialect=… turns a read-only diff into the CREATE/ALTER/DROP + FK statements to apply. Bridges the previously test-only-connected diff and ddl modules. Name-matched (oid-independent); destructive/PK changes emitted with review comments; PG-precise + Snowflake SET DATA TYPE.

Also in this branch (features shipped this cycle, backend + frontend)

  • Schema Diff + Saved Views
  • Table annotations (per-project notes keyed by table name; IDOR-guarded CRUD + modal UI)
  • Connection health test (SSRF-safe probe reusing the introspectors' guard; button + status UI)
  • fix(alembic): repaired the broken multi-head revision graph (verified against Postgres)
  • Security/logic coverage → 100% on the SSRF guard, sanitize, schema_diff

Verification

  • backend pytest 258 passed; frontend vitest 136 passed; tsc --noEmit clean
  • migrations 00040006 applied against real Postgres
  • SSRF pinning, IDOR uniform-404, DSN-redacted errors preserved

🤖 Generated with Claude Code

seonghobae and others added 9 commits July 5, 2026 20:43
0003_revoked_token pointed at nonexistent down_revision "0002" and the tree had two heads. Repoint to 0002_auth_share and add 0004_merge_heads merging 0003 + 0003_validate_project_space_fk. Verified: alembic upgrade head runs the full chain against Postgres.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AxU2xaupAjp912oDNFuWyd
Cover render, dialog a11y (role=dialog/aria-modal), source-backed labels, handler wiring and input changes for the three dialogs lacking direct component tests. +13 tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AxU2xaupAjp912oDNFuWyd
Schema Diff: pure diff_snapshots() matching tables by (schema,name) not volatile relation_oid; GET /api/snapshots/{uuid}/diff (IDOR-safe, uniform not_found); DiffModal + demo. Saved Views: DiagramView model + 0005 migration + IDOR-guarded CRUD; captureLayout/applyLayout + ViewsModal. Verified: frontend 130 tests, backend 235 tests, tsc --noEmit clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AxU2xaupAjp912oDNFuWyd
Close untested branches in the DSN SSRF guard: non-integer query port, host resolving to no usable address (empty sockaddr), and host dedup. dsn_guard.py coverage 96% -> 100%. Full backend suite 238 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AxU2xaupAjp912oDNFuWyd
sanitize_for_storage: memoryview/bytes/bytearray -> text, invalid-utf8 base64 fallback, tuple recursion (75% -> 100%). schema_diff: orphan/nameless column/pk/fk rows are skipped and table-comment changes detected (94% -> 100%).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AxU2xaupAjp912oDNFuWyd
TableAnnotation model + 0006 migration + IDOR-guarded CRUD (list/upsert/delete). Notes are keyed by (project, schema_name, relation_name) -- never the volatile relation_oid -- with a unique constraint (one note per table). Editor role for writes, uniform 404 for missing/unauthorized. Migration verified against Postgres; full backend suite 245 passing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AxU2xaupAjp912oDNFuWyd
POST /api/connections/{uuid}/test probes a stored connection and reports ok/server_version/error. IDOR-safe (project membership required, uniform 404). Reuses the introspectors' SSRF guard: probe_postgres pins to validate_postgres_dsn_target's IPs, probe_snowflake goes through _parse_snowflake_dsn; errors are DSN-redacted and an unreachable DB is ok=false (not an error status). Backend suite green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AxU2xaupAjp912oDNFuWyd
AnnotationsModal (list/add/edit/delete table notes) wired to a toolbar button; api client listAnnotations/upsertAnnotation/deleteAnnotation + demo store. Connection test button + status pill next to the connection picker; api testConnection + demo. types ConnectionTestResult/TableAnnotation. typecheck clean, frontend suite 23 files / 136 tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AxU2xaupAjp912oDNFuWyd
snapshot_diff_to_migration_sql(base, target, dialect) bridges the (previously test-only-connected) diff and ddl modules: CREATE/DROP TABLE, ADD/DROP/ALTER COLUMN, SET/DROP NOT NULL, ADD/DROP FOREIGN KEY -- name-matched (oid-independent), reusing schema_diff indexing + ddl/export type mapping. Endpoint GET /api/snapshots/{uuid}/migration.sql (IDOR-safe, dialect param). Destructive/PK changes emitted with review comments. +7 tests; backend suite 258. Adds docs/valuation-gap-analysis.md (codegraph-grounded roadmap).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AxU2xaupAjp912oDNFuWyd
@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

@opencode-agent

opencode-agent Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

  • Head SHA: 31f47ead5e74ecb19fefdc07b45e2213d9647f63
  • Workflow run: 28742819565
  • Workflow attempt: 1
  • Gate result: APPROVE (exit 0)

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Backend (25 files)"]
  S1 --> I1["API and service runtime"]
  I1 --> R1["Review risk: Backend (25 files)"]
  R1 --> V1["backend tests"]
  Evidence --> S2["Docs: valuation-gap-analysis.md"]
  S2 --> I2["operator or user guidance"]
  I2 --> R2["Review risk: Docs: valuation-gap-analysis.md"]
  R2 --> V2["docs review"]
  Evidence --> S3["Frontend (15 files)"]
  S3 --> I3["browser runtime and bundle"]
  I3 --> R3["Review risk: Frontend (15 files)"]
  R3 --> V3["frontend tests"]
Loading

session.get returns DbConnection | None; the connection-test endpoint dereferenced it without a None check, failing CI mypy (union-attr) at connections.py:99. Add a 404 guard (mirrors create_snapshot). Fixes backend CI on #440.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AxU2xaupAjp912oDNFuWyd
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