Skip to content

docs: root cleanup — archive TECHNICAL_PLAN; fix FEATURES, ARCHITECTURE, HELM_CHART, OIDC, STORAGE#86

Closed
cevheri wants to merge 36 commits into
mainfrom
docs/root-cleanup-features-arch
Closed

docs: root cleanup — archive TECHNICAL_PLAN; fix FEATURES, ARCHITECTURE, HELM_CHART, OIDC, STORAGE#86
cevheri wants to merge 36 commits into
mainfrom
docs/root-cleanup-features-arch

Conversation

@cevheri

@cevheri cevheri commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Summary

docs/ root cleanup: audited each root doc against current code, archiving the stale one and correcting drift in the rest. Every claim verified against source before editing.

Archived

  • TECHNICAL_PLAN.mddocs/archived/ — Dec-2025 roadmap, every item shipped, no inbound links.

Verified clean (no changes needed)

  • SEED_CONNECTIONS.md — every claim matches src/lib/seed/ + the Helm seed-configmap wiring.

Fixed in place

FEATURES.md — AI → multi-provider + AI suite; added Redis (was absent); added OIDC SSO; moved ERD "Planned"→Implemented (#18); fixed duplicate section numbers → 1–18; normalized markdown indentation (Copilot note).

ARCHITECTURE.md — "8 database backends" → 7; added §4.6 Workspace Abstraction (npm-package embedding); refreshed the directory tree + api/ai/ routes.

HELM_CHART.md — corrected the appVersion claim (CI fails only if ahead; behind tolerated); added NODE_OPTIONS, seed env vars, seed-configmap.yaml, §8 Seed Connections; pointer to chart README for values.

OIDC.mdbuildLogoutUrl snippet aligned to code (searchParams API, precise Auth0 host check, Zitadel /oidc/v1/end_session special-case + table row); OIDCClaims name?preferred_username?; corrected username fallback chain.

STORAGE.md — SQLite upsert INSERT OR REPLACEON CONFLICT … DO UPDATE; added missing isReady field to StorageSyncState.

Helm repo URL — resolved

Confirmed https://libredb.org/libredb-studio/ is canonical (github.io 301-redirects to it; live index.yaml served there). Aligned the chart README.md, which had advertised github.io. HELM_CHART.md/CLAUDE.md were already correct.

Scope notes

API_DOCS.md deliberately excluded — it diverges on the dev branch (+49 lines of provider query-format docs not yet on main); editing the stale main copy would collide. DATABASE_PROVIDERS.md likewise lives on dev. docs/releases/* left frozen as historical snapshots.

Docs-only change — no source touched.

cevheri and others added 29 commits June 17, 2026 15:19
The dialect-aware quoteIdentifier treated a schema-qualified table name as a
single identifier, so 'employees.department' became '"employees.department"' —
which Postgres reads as one relation literally named with a dot, failing with a
query error. Sidebar 'select top 100' on any schema-qualified table was broken.

Add quoteQualifiedName(): split on '.', quote each segment only-when-needed, and
rejoin. 'employees.department' stays unquoted; 'public.Order' becomes
'public."Order"'. Use it for table names in the query generators and the data
profiler (columns still use single-identifier quoting).

Verified end-to-end against a Neon Postgres database: the generated
'SELECT * FROM employees.department LIMIT 50;' runs, whereas the old quoted form
failed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(sql): quote schema-qualified table names per-segment
…as getSchema() ran a single query that joins five information_schema-based CTEs (columns, PKs, foreign keys, indexes + table sizes). PostgreSQL 12+ inlines single-reference CTEs, and because the planner estimates rows=1 for information_schema views it chose nested-loop joins that re-execute the expensive fk/index CTEs many times. On schemas with 100+ tables this exploded to ~295s and always hit the connection's 60s statement_timeout, so the schema tree never loaded.

Two complementary fixes:
1. Mark all CTEs AS MATERIALIZED so each is computed once instead of being re-executed inside nested loops (~295s -> ~2.6s on a 122-table schema).
2. Split schema loading into two phases so a slow/failing stats query can never block the table list:
   - getSchemaList()      -> tables + columns + PKs (fast, ~50ms)  [/api/db/schema/list]
   - getSchemaRelations() -> foreign keys + indexes (heavy, ~2.3s) [/api/db/schema/relations]
The client renders the tree from the fast list immediately, then merges relations asynchronously. If relations fail/time out they are logged and skipped — the table list stays intact. getSchema() is kept (MATERIALIZED) for consumers that need the full schema (diff, AI context).
New optional provider methods getSchemaList/getSchemaRelations fall back to getSchema()/[] for providers that don't implement them.
Adds regression coverage for the schema-introspection timeout fix (0d60c47),
which split schema loading into a fast structural list and a heavy, best-effort
relations phase. None of the new code paths were previously tested.

Provider (tests/integration/db/postgres-provider.test.ts, +11):
- getSchemaList(): returns columns + PKs but intentionally empty
  indexes/foreignKeys, isPrimary detection, non-public schema prefixing,
  negative reltuples row_count clamped to 0, and null/empty columns.
- getSchemaRelations(): FK/index data keyed by display name, non-public
  prefixing on both the table and the referenced table, public references kept
  bare, empty/null fk-index tolerance, and null index columns coerced to [].

API routes (new files, 15 tests):
- /api/db/schema/list: uses getSchemaList() when present, falls back to
  getSchema() otherwise, plus auth (401), empty-body (400), missing-type (400),
  ConnectionError (503) and DatabaseError/generic (500).
- /api/db/schema/relations: uses getSchemaRelations() when present, returns []
  fallback otherwise, plus the same auth/validation/error matrix.

Hook (tests/hooks/use-connection-manager.test.ts, +4):
- phase 1 renders the table list, phase 2 merges FKs/indexes by table name;
- relations failure does NOT wipe the table list and shows no error toast
  (the core resilience contract of the fix);
- phase 1 failure short-circuits so the heavy relations endpoint is never hit;
- tables absent from the relations payload are left unchanged.

Full suite green: lint (0 errors), typecheck, 2050 unit/api/integration +
251 hooks + component groups, 0 failures.
…Sonar gate

The SonarCloud PR quality gate failed on #71 with 53.3% coverage and 6.6%
duplication on new code. Both stem from how the schema introspection SQL was
written, not from missing tests.

Coverage: the getSchema/getSchemaList/getSchemaRelations SQL lived in multi-line
template literals *inside the method bodies*. bun's coverage instruments the
interior lines of such literals as 0-hit in any test process that imports the
module without exercising the method; the merged lcov (per-file isolated runs)
then reports those SQL lines as uncovered even though the methods are tested.
Verified empirically: a module-level `const` template is evaluated once at load
and reported covered everywhere, while an in-body one is not. Hoisting the three
queries to module scope takes postgres.ts new-code line coverage 28% -> 100%
(overall new-code coverage 53.9% -> ~99%).

Duplication: the hoisted queries shared the same CTEs (tables/columns/pk across
full+list, fk/index across full+relations). Extracted each CTE to a single
reusable fragment const and compose the three queries from them, removing the
duplicated blocks. The SQL text produced is unchanged.

Tests: the two route specs intentionally keep their mock.module setup inline
(a shared helper breaks bun's per-file mock scoping under the non-isolated
`bun run test`, clobbering @/lib/db mocks across files). Added an empty-object
({}) body case to each for the last uncovered branch. Test mock/setup
boilerplate is expected harness scaffolding, so tests are excluded from Sonar
copy-paste detection (sonar.cpd.exclusions).

No behavioural change: same SQL, same provider/route/hook logic. Verified:
lint (0 errors), typecheck, 2052 unit/api/integration + hooks + component
groups (0 failures), production build, full coverage regenerated.
The Sonar PR gate still flagged 6.2% duplication on new code: the
/api/db/schema/list and /api/db/schema/relations routes shared ~39 identical
lines of body parsing, auth, connection resolution and error handling (the only
difference is which provider method they call).

Extract that boilerplate into handleSchemaRequest() in src/lib/api/schema-route.ts;
each route is now a thin wrapper that passes a `load` callback selecting the
provider method (with the getSchemaList->getSchema and getSchemaRelations->[]
fallbacks preserved). Removes both 39-line duplicated blocks.

Coverage holds at 100% on new code (the shared handler is fully exercised by the
existing route specs). Verified: typecheck, 2052 core tests + 0 failures,
coverage regenerated (schema-route.ts 32/32 lines).
…or cross-schema FKs

Copilot review on #71 flagged a pre-existing bug in the FK introspection
(from 0d60c47, relocated verbatim into CTE_FK_INFO during the dedupe):

  JOIN information_schema.constraint_column_usage ccu
    ON ccu.constraint_name = tc.constraint_name
    AND ccu.table_schema = tc.table_schema   -- wrong

For a foreign key, constraint_column_usage reports the *referenced* (parent)
table's columns, so ccu.table_schema is the referenced schema while
tc.table_schema is the referencing schema. Joining them requires the two to be
equal, which silently drops every cross-schema foreign key and makes
referencedSchema always equal the referencing schema — defeating the non-public
referenced-table prefixing (e.g. billing.accounts).

Join on the constraint's own schema instead (ccu.constraint_schema =
tc.constraint_schema). Because the FK CTE is now single-sourced, this fixes both
getSchema() and getSchemaRelations().

Added a SQL-level regression guard: the existing specs mock the query result, so
they can't catch a bad join; the new test asserts the emitted SQL joins on
constraint_schema and not table_schema. Real cross-schema FK behaviour should be
confirmed against a live Postgres via E2E.
The npm-publish workflow's Validate job runs `bun run test:ci`, but the script
was dropped from package.json somewhere after v0.9.19 (it was added in #66).
The v0.9.25 tag push therefore failed with "Script not found test:ci", blocking
the npm publish (the GitHub release, tag and Docker images published fine).

Restore it to the per-file-isolated form the publish gate expects:
  test:ci = bash tests/run-core.sh && bun run test:components

This mirrors ci.yml's reliable path and avoids bun's process-wide mock.module
load-order flakiness that the single-process `bun run test` is prone to.
The 'default tab is overview' and 'can switch to operations tab' E2E tests
asserted on empty-state-only copy ('Command Center', the 'Select connection'
placeholder), which disappears once seed connections load the populated
dashboard. They passed in CI (no seed file) but failed locally with
SEED_CONFIG_PATH set.

Add stable data-testid hooks (admin-content-overview/-operations) to the
TabsContent wrappers and assert on testid visibility + tab aria-selected,
so the tests hold in both empty and populated states.

Verified: 32/32 full E2E pass with seeds loaded, 8/8 admin pass with seeds disabled.
…andling

- Introduced Redis connection configuration and query formats in CLAUDE.md and API_DOCS.md.
- Added support for both plain Redis commands and JSON command objects.
- Implemented schema introspection and health metrics retrieval for Redis.
- Enhanced Redis provider tests to cover error handling for malformed commands and Redis-side errors.
* docs(providers): add comprehensive Redis provider reference

Add docs/providers/redis.md — the single reference point for the Redis
provider covering design rationale, architecture (Strategy Pattern + base
class), connection, query interface, schema mapping, monitoring, capabilities,
error handling, testing, usage, and known limitations.

Also serves as the template for the other provider docs under docs/providers/.

* docs(providers): address review — TYPE sampling, analyze line count, TLS wording
* docs(providers): add comprehensive PostgreSQL provider reference

Add docs/providers/postgresql.md documenting the PostgreSQL provider — the
reference implementation for the SQL provider family. Covers the SQLBaseProvider
layer, connection pooling/SSL, automatic LIMIT injection, transactions and query
cancellation, the MATERIALIZED-CTE two-phase schema introspection (and its
performance/coverage rationale), pg_stat_* monitoring with graceful degradation,
maintenance, capabilities, error mapping, testing, and known limitations.

* docs(providers): rename to postgres.md to match the canonical type-id

Convention: doc filename mirrors the code type-id / source filename
(providers/sql/postgres.ts -> docs/providers/postgres.md) for a 1:1
code<->doc mapping. The official name "PostgreSQL" is retained in the
document title and prose.

* docs(providers): address review — queryTimeout source, SSL precedence, getHealth fallback, tx pooling, config validation

- queryTimeout is ProviderOptions.queryTimeout (not pool), applied as statement_timeout
- SSL step 2 also triggers on options.ssl === true, not just cloud hosts
- getHealth returns a placeholder row (no pg_stat_activity fallback — that's getSlowQueries)
- transaction client is checked out from the pool, not held "outside" it
- the two connection forms are not mutually exclusive; connection string wins when both given

* docs(providers): address review — test:ci runner & statement_timeout error class

- Testing: `bun run test` runs the core group in one process (mock.module flaky);
  CI uses `test:ci` (run-core.sh per-file isolation) / `test:coverage`, not `bun run test`
- Error mapping: PG statement_timeout emits "canceling statement due to statement
  timeout" → classified as QueryCancelledError (cancellation check precedes timeout),
  not TimeoutError; TimeoutError is for generic/acquire timeouts
- getHealth: clarified as placeholder path (not pg_stat_activity fallback) in coverage notes
Providers are the lifeblood of the project: for each provider, code, docs, and
tests form a 1:1 triad keyed by the canonical type-id, and a change to any one
side must sync the other two in the same PR. Documented as a callout under
Architecture → Key Patterns → Database Abstraction.
* docs(providers): add comprehensive MySQL provider reference

Add docs/providers/mysql.md documenting the MySQL provider, framed as a diff
against the PostgreSQL SQL reference. Covers the mysql2 pool config (only `max`
honored; no statement_timeout wiring), backtick quoting, binary→hex row
sanitization, N+1 single-database schema introspection (no two-phase split),
KILL QUERY cancellation, transactions, performance_schema monitoring with its
three distinct degradation modes, analyze/optimize/check/kill maintenance,
error mapping, testing, and known limitations.

* docs(providers): address review — connectionString bypass & TimeoutError nuance

- buildPoolConfig connectionString path returns {...baseConfig, uri} and skips
  the discrete branch, so ssl/connection.ssl/auto-SSL and timezone are ignored
  (must be encoded in the URI) — now documented in §4.2/§4.3
- error handling: mapDatabaseError DOES emit TimeoutError for any "timeout"/
  "timed out" driver message (e.g. lock-wait timeout); the MySQL-specific gap is
  only the lack of a server-side timeout derived from queryTimeout

* docs(providers): address review — rowCount for non-SELECT & MAX_EXECUTION_TIME

- rowCount is rows.length only for array (SELECT) results; non-SELECT returns a
  ResultSetHeader and the provider reports rowCount: 0 (affected-rows not surfaced)
- future-work: MAX_EXECUTION_TIME is the per-statement limit; wait_timeout is
  idle-connection only and wouldn't bound query execution — dropped it
* docs(providers): add comprehensive Oracle provider reference

Add docs/providers/oracle.md documenting the Oracle provider (oracledb Thin
mode), framed as a diff vs the PostgreSQL SQL reference. Covers EZConnect
service-name connect string, FETCH FIRST pagination, owner-scoped 5-query schema
introspection, connection.break() cancellation, transactions without an
auto-rollback timeout, the absence of an SSL config path (TLS via wallet/connect
string), privilege-guarded V$-view monitoring, DBMS_STATS/index-rebuild/kill
maintenance, overridden Oracle UI labels, ORA-* error mapping, testing, and
known limitations.

* docs(providers): address review — queryTimeout is a separate ProviderOptions field, not part of DEFAULT_POOL_CONFIG

* docs(providers): document Oracle data-type & feature gaps (LOB, NUMBER, EXPLAIN, callTimeout, privileges)

Add a §5.3 on CLOB/BLOB (returned as Lob stream objects, not configured via
fetchAsString/fetchAsBuffer) and NUMBER precision loss, and expand Known
Limitations with: LOB rendering gap, large-NUMBER precision, EXPLAIN advertised
but not implemented for Oracle (UI builder is pg/mysql only), connection.callTimeout
as the fix for no server-side timeout, ALTER SYSTEM / V$ privilege requirements,
and the module-global oracledb settings side effect.

* docs(providers): clarify Oracle connectionString is EZConnect/TNS, not oracle://

connectionString is passed straight to oracledb.createPool({ connectString }),
which expects EZConnect/TNS. The oracle:// scheme is only a UI paste-parser
convenience that decomposes into discrete fields and never reaches the driver.
…ence (#80)

* docs(providers): add comprehensive Microsoft SQL Server (mssql) reference

Add docs/providers/mssql.md documenting the SQL Server provider (node-mssql),
framed as a diff vs the PostgreSQL SQL reference, and remove the stray
sqlserver.md placeholder (type-id naming: file = mssql, prose = "SQL Server").

Covers encrypt-by-default/Azure-aware TLS, TOP / OFFSET-FETCH pagination,
five-query cross-schema introspection, the fully-wired pool+requestTimeout
(server-side query timeout), rowsAffected-based rowCount, real blocked-session
detection and real index scan counts, mssql.Transaction (no auto-rollback
timeout), request.cancel() cancellation, DMV monitoring with privilege guards,
analyze/check/optimize/kill maintenance, overridden labels, SQL-Server error
mapping, and known gaps (connectionString ignored by buildConfig, EXPLAIN
advertised-not-implemented, non-Azure cert trust, unsanitized binary).

* docs(providers): address review — requestTimeout is driver-enforced, soften connectionString wording

- requestTimeout is enforced client-side by the mssql/Tedious driver, not a
  server-enforced statement timeout (Postgres statement_timeout is the latter);
  reworded §3.5 and §11 accordingly (+ fixed the anchor link)
- connectionString-only config: reworded from "silently connect to localhost"
  to targeting an unintended server and likely failing on missing fields

* docs(providers): document SQL Server data-type & enterprise gaps

Add §5.3 (parameter type inference, BIGINT/DECIMAL/MONEY precision loss, binary
Buffer, single-recordset) and expand Known Limitations with numeric precision,
untyped parameter binding, missing Always On options (MultiSubnetFailover /
ApplicationIntent ReadOnly routing), and Azure SQL DMV/DBCC caveats.

* docs(providers): address review — grammar, cancel wording, index-scan claim, cancellation error class

- "does bound" -> "does impose a request timeout"
- cancelQuery: returns false if no tracked Request, else true if cancel() didn't
  throw (doesn't confirm cancellation took effect)
- index scans: Postgres ALSO reports real counts (pg_stat_user_indexes.idx_scan);
  SQL Server is unique only for blocked-session detection
- error table: cancellation-pattern messages map to QueryCancelledError before the timeout check
* docs(providers): add comprehensive SQLite reference (with deployment-constraint framing)

Add docs/providers/sqlite.md. Leads with the strategic framing the product needs:
SQLite-as-target is an embedded, server-local, bun:sqlite-only engine — fit for
self-hosted / local-dev / edge and zero-config trials, NOT a multi-tenant SaaS
target. Disentangles the two SQLites (storage better-sqlite3 vs target bun:sqlite).

Covers file-path resolution + traversal guard, connect PRAGMAs (WAL/FK), read/write
dispatch, the absence of transactions/cancellation/pooling, single-schema PRAGMA
introspection, minimal/estimated monitoring, vacuum/analyze/reindex/check
maintenance, real-engine (:memory:) testing, and known limitations.

* docs(providers): address review — stable anchor (drop emoji from heading) & accurate path-traversal note

- Removed the ⚠️ from the "Deployment constraint" heading (variation-selector
  made the GitHub anchor brittle); moved it into the body and fixed the §0 link
- Corrected the path-traversal claim: resolved !== normalize(resolved) is a no-op
  (path.resolve already normalises), so only NUL bytes are rejected; documented
  the ineffective guard as a known limitation
…#82)

* docs(providers): add comprehensive MongoDB reference (final provider)

Add docs/providers/mongodb.md documenting the MongoDB document provider (official
mongodb driver). Covers the JSON/MQL query format and all operations, BSON
serialization, sampling-based flat schema inference, the find-100-cap vs unbounded
aggregate, MongoClient pooling, validate/compact/dbCheck/killOp maintenance,
serverStatus/currentOp/$indexStats monitoring with real index scans, overridden
collection labels, and known gaps (sampled schema, unbounded aggregate, no EXPLAIN/
transactions/cancel, collStats deprecation, privilege-gated monitoring).

Completes the docs/providers/ set: postgres, mysql, oracle, mssql, sqlite, redis, mongodb.

* docs(api): fix MongoDB operations list to match the provider

The MongoDBProvider expects operation: "count" (not "countDocuments") and also
supports "distinct" (field taken from options.projection). Correct the
API_DOCS.md operations list accordingly. Surfaced during the mongodb.md review (#82).

* docs(providers): incorporate deep-review findings into mongodb.md

Verified each review claim against mongodb.ts / route.ts before documenting:
- prepareQuery is NOT a true no-op — it returns limit: options.limit||100 which
  the /api/db/query route uses for hasMore/pagination; clarified wording
- fixed off-by-one citation (find 100-cap is line 252, not 251)
- per-operation options handling: findOne honours only projection (sort/skip/limit
  silently ignored); aggregate ignores options entirely; distinct takes its field
  from the first key of options.projection (no dedicated field param) — documented
  the required shape and flagged as limitations
- getPerformanceMetrics "queries/sec" is actually total ops/sec (q+i+u+d ÷ uptime)
- active-sessions "user" column shows op.client (host:port), not a real user
- getIndexStats indexType only distinguishes text vs btree (hashed/geo/wildcard
  mislabelled); serializeDocument normalises only a subset of BSON types
- unlimited option ignored (hasMore may be wrong); getSchema serial round-trips
- softened the "never use bun run test" note to match CLAUDE.md's pre-commit gate;
  tidied the connection-string template
The alias-aware completion feature is live; this doc is its sole reference, so
it's kept (not archived) — but the completion provider was refactored out of
QueryEditor.tsx into src/lib/editor/sql-completions.ts. Update the module
structure, Key Components, and Related Files accordingly; QueryEditor.tsx now
hosts the editor and registers the provider. Core API (extractAliases/
resolveAlias) and types are unchanged.
…E_PROVIDERS.md (#83)

* docs: make docs/providers/ the prime provider reference; slim DATABASE_PROVIDERS.md

The per-provider docs under docs/providers/ are now the canonical reference for
each database. This wires them up and removes the now-duplicated provider detail
from DATABASE_PROVIDERS.md while preserving its unique value.

- Add docs/providers/README.md: index of all 7 prime docs (provider/type-id/
  family/driver/query-language table) + conventions + links to the architecture/
  authoring guide and the API contract.
- DATABASE_PROVIDERS.md is repurposed as the cross-cutting "architecture +
  how-to-add-a-provider" guide: the duplicated per-provider sections (Supported
  Databases table, MongoDB Query Format, Provider-Specific Features, Reference:
  Existing Providers) now point to the prime docs; fixed the stale SQLite driver
  (better-sqlite3 -> bun:sqlite for the target provider) and completed the
  architecture file-tree + provider hierarchy (oracle/mssql/redis).
- README.md: add a Provider reference docs pointer and correct the SQLite driver.

No content lost — the unique architecture overview, interface contracts, and the
full "Adding a New Database Provider" guide remain in DATABASE_PROVIDERS.md.

* docs: trim Step 2's inlined provider skeletons in DATABASE_PROVIDERS.md

The "Adding a New Provider" guide inlined ~265 lines of synthetic SQL/non-SQL
provider class skeletons (CockroachDB/Redis-like). Now that each provider has a
detailed doc and the real source files are the best template, replace the
skeletons with concise guidance: which base to extend, which real file to copy
as a template (linked), the abstract methods to implement, and the metadata
hooks to override. Kept the "what the base class gives you for free" /
"what SQLBaseProvider adds" tables and the interface-contracts reference.

DATABASE_PROVIDERS.md: 895 -> 583 lines; no longer carries code that can drift
from the providers it describes.

* docs: address review — type-id filename + mapDatabaseError query arg

- Step 2: provider files are named by the canonical type-id (<type-id>.ts),
  aligning with docs/providers/README.md and the code/docs/tests convention
- mapDatabaseError's 3rd arg is the raw query string (SQL or JSON per errors.ts),
  not "sql" — reworded so it's accurate for non-SQL providers too
Continues the docs/ root cleanup.

Archive:
- docs/TECHNICAL_PLAN.md -> docs/archived/ (git mv). Dec-2025 roadmap whose every
  phase has shipped (Monaco, autocomplete, multi-tab, virtualized grid, inline
  editing, EXPLAIN, ERD); no inbound links. Joins AI_PLAN.md et al.

FEATURES.md (drift fixes, all verified against code):
- AI section: "Gemini 2.5 Flash" -> "Multi-Provider LLM"; documented the flexible
  provider support and the shipped AI suite (index-advisor, impact, query-safety,
  describe-schema).
- Added the Redis key-value provider (was entirely absent despite shipping).
- Added OIDC SSO to the Authentication section.
- Moved Visual Schema Explorer (ERD) from "Planned" to Implemented (#18) — it ships
  via src/components/SchemaDiagram.tsx; "Planned" section now points to docs/backlogs/.
- Fixed duplicate section numbers (two #8, two #10) -> sequential 1..18.

ARCHITECTURE.md (drift fixes, all verified):
- "8 database backends" -> "7" (it lists exactly 7).
- Added §4.6 Workspace Abstraction documenting the npm-package embedding layer
  (src/workspace/, src/exports/, tsup build:lib) — central per CLAUDE.md, previously
  undocumented.
- Directory tree: added workspace/, exports/, lib/editor/, lib/seed/, lib/api/,
  components/monitoring/, app/monitoring/, results-grid/, SchemaDiagram.tsx; expanded
  the api/ai/ route list.

Verified before editing: provider count (7), SchemaDiagram.tsx exists, all 8 ai/
routes exist, every src/ dir referenced exists. Avoided DATABASE_PROVIDERS.md (in
flight on the providers branch) and left docs/releases/* frozen.
@cevheri cevheri requested a review from Copilot June 22, 2026 12:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Docs-root cleanup to reduce drift between documentation and the current shipped feature set/architecture: one stale planning doc is archived, and two root docs are updated to accurately describe current capabilities and structure.

Changes:

  • Archived the stale TECHNICAL_PLAN.md under docs/archived/.
  • Updated FEATURES.md to reflect current AI (multi-provider), Redis support, OIDC SSO, and shipped ERD; reorganized/renumbered sections and added a roadmap pointer.
  • Updated ARCHITECTURE.md to correct backend count, document the workspace/package embedding layer, and refresh the directory tree + AI route list.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.

File Description
docs/FEATURES.md Updates feature documentation for AI/Redis/OIDC/ERD + roadmap; renumbers sections.
docs/archived/TECHNICAL_PLAN.md Moves the old roadmap into the archived docs area.
docs/ARCHITECTURE.md Corrects backend count; documents npm embedding/workspace abstraction; refreshes directory structure and AI route list.
Comments suppressed due to low confidence (1)

docs/FEATURES.md:70

  • Headings and bullets for sections 9–10 are indented by 4 spaces, which makes them render as a code block instead of normal markdown headings/lists. Removing the leading indentation fixes the table-of-contents/scroll behavior and readability.
    ### 9. Advanced Schema Explorer (2025 Edition)
    *   **Deep Tree Inspection:** Expand tables to view column definitions, data types, and Primary Key (PK) constraints with intuitive iconography.
    *   **Global Search & Filter:** Real-time, high-performance filtering across both table names and column names.
    *   **Precision Row Counts:** Optimized PostgreSQL integration using `pg_class` statistics for fast, accurate (estimated) row counts even on large datasets.
    *   **Visual Table Designer:** Create new tables directly from the explorer with a modern, column-based UI. No SQL knowledge required for basic structures.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/FEATURES.md Outdated
Comment on lines 36 to 40
### 6. AI Query Assistant (Multi-Provider LLM)
* **Natural Language to SQL:** Convert natural language requests into high-precision SQL code.
* **AI SQL Explanation:** One-click "AI Explain" button to translate complex SQL logic into plain English for easier debugging and onboarding.
* **Schema-Aware Generation:** AI automatically understands your tables and columns for accurate query generation.
* **Interactive UI:** Floating `⌘+K` style command bar for a seamless "AI-first" workflow.
Comment thread docs/FEATURES.md Outdated
Comment on lines 113 to 117
### 17. Authentication & Identity Management
* **Secure User Onboarding:** Full-featured login/logout flows and session management via Next.js middleware and API routes.
* **OIDC Single Sign-On:** Optional SSO via OpenID Connect (Auth0, Keycloak, Okta, Azure AD) using PKCE, mapping to the same local JWT session as email/password auth. See [OIDC](OIDC.md).
* **Context-Aware UI:** Personalized experience based on authenticated user state (e.g., "Me" endpoint integration).
* **Enterprise Security First:** Environment variable protection with `.env.example` templates and strict Git tracking policies for credentials.
Audited docs/HELM_CHART.md against charts/libredb-studio/. Fix-in-place
(keeps the architecture/rationale focus; defers the values reference to the
chart's own README).

Fixes (all verified against the chart + CI):
- Version Management: corrected the appVersion claim. CI does NOT enforce
  appVersion == package.json. The real guard (ci.yml "Verify appVersion is
  valid") fails only if appVersion is *ahead* of package.json; being behind is
  tolerated with an info notice. Removed the false "helm-lint job enforces
  equality" wording (in Version Management and Known Limitations).
- Env vars: added NODE_OPTIONS (--max-old-space-size=384, hardcoded in
  configmap.yaml) and SEED_CONFIG_PATH/SEED_CACHE_TTL_MS.
- Chart structure: added seed-configmap.yaml (was omitted).
- Added §8 Seed Connections architecture note (config mount, env wiring,
  runtime credential resolution).
- Added a pointer to charts/libredb-studio/README.md as the authoritative
  values reference.

Left untouched (pending user confirmation): the Helm repo URL
(libredb.org vs github.io) — CLAUDE.md/this doc say libredb.org while the
chart README + CI use github.io; canonical domain not determinable from main.
@cevheri cevheri changed the title docs: archive stale TECHNICAL_PLAN; fix drift in FEATURES + ARCHITECTURE docs: root cleanup — archive TECHNICAL_PLAN; fix FEATURES, ARCHITECTURE, HELM_CHART Jun 22, 2026
cevheri added 2 commits June 22, 2026 15:51
Several section headings/bullets were indented 4 spaces, which GitHub/CommonMark
renders as code blocks instead of headings/lists (Copilot flagged lines 40, 70,
117). Normalized the whole file flush-left; sub-bullets under SQL/Document/
Key-Value providers keep their single 4-space nesting level.
The chart README told users 'helm repo add libredb https://libredb.github.io/
libredb-studio'. Verified that github.io 301-redirects to the canonical custom
domain https://libredb.org/libredb-studio/ (the live Helm index.yaml is served
there), which is what HELM_CHART.md and CLAUDE.md already use. Aligned the README
to the canonical URL so all docs agree.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.

Comment thread docs/HELM_CHART.md Outdated
Comment on lines +182 to +185
When `seedConnections.enabled=true`, the chart provisions a set of pre-defined database connections at startup:

- Connection definitions come from inline `seedConnections.config` (rendered into `seed-configmap.yaml`) or an `existingConfigMap`.
- The deployment mounts the config at `/app/config/seed-connections.yaml` and sets `SEED_CONFIG_PATH` (plus `SEED_CACHE_TTL_MS` from `seedConnections.cacheTTL`).
Comment thread docs/HELM_CHART.md Outdated
| `NEXT_PUBLIC_AUTH_PROVIDER` | `authProvider` | Always |
| `STORAGE_PROVIDER` | Auto-wired (see above) | Always |
| `STORAGE_SQLITE_PATH` | `config.storageSqlitePath` | When sqlite |
| `SEED_CONFIG_PATH` / `SEED_CACHE_TTL_MS` | `seedConnections.*` | When `seedConnections.enabled` |
Comment thread docs/FEATURES.md
* **Document Databases:**
* **MongoDB:** Full support with official driver, JSON-based MQL queries, automatic schema inference, and aggregation pipelines.
* **Key-Value Stores:**
* **Redis:** Full support via the official `ioredis` driver — plain-command and JSON query styles, prefix-grouped key "schema" through a non-blocking `SCAN`, and `INFO`/`SLOWLOG`/`CLIENT LIST`-derived health and metrics.
Audited SEED_CONNECTIONS.md, OIDC.md, STORAGE.md against current code.

SEED_CONNECTIONS.md — LIVE, no changes. Every claim (config schema, env vars,
credential resolution, RBAC, Helm seed-configmap wiring) matches src/lib/seed/.

OIDC.md (fix-then-keep):
- buildLogoutUrl snippet corrected to match src/lib/oidc.ts: uses
  searchParams.set() (not "+ params"), precise Auth0 host check, and the
  Zitadel RP-Initiated Logout special-case (/oidc/v1/end_session, detected via
  the role claim). Added Zitadel to the provider logout-endpoints table.
- OIDCClaims interface: replaced the non-existent `name?` field with the actual
  `preferred_username?` field.
- Username resolution note: corrected to the real fallback chain
  (claims.email || claims.preferred_username || claims.sub || role).

STORAGE.md (fix-then-keep):
- SQLite upsert: "INSERT OR REPLACE" -> actual "INSERT ... ON CONFLICT ... DO
  UPDATE" (sqlite.ts:105).
- StorageSyncState: added the missing `isReady` field (use-storage-sync.ts:13).

All claims verified against source (oidc.ts, callback route, sqlite provider,
use-storage-sync). main and dev are identical for these three files, so no
divergence risk.
@cevheri cevheri changed the title docs: root cleanup — archive TECHNICAL_PLAN; fix FEATURES, ARCHITECTURE, HELM_CHART docs: root cleanup — archive TECHNICAL_PLAN; fix FEATURES, ARCHITECTURE, HELM_CHART, OIDC, STORAGE Jun 22, 2026
cevheri added 3 commits June 22, 2026 16:12
# Conflicts:
#	docs/editor/sql-alias-completion.md
#	package.json
…Copilot)

Addresses two Copilot review notes on HELM_CHART.md:
- SEED_CONFIG_PATH / SEED_CACHE_TTL_MS are set directly on the Deployment
  (deployment.yaml:118-120), not via the app ConfigMap — table Source column +
  section intro clarified.
- Seed §8: the mount filename is configurable via seedConnections.configMapKey
  (default seed-connections.yaml), and enabling the feature without
  seedConnections.config OR existingConfigMap provisions nothing.

The third Copilot note (FEATURES.md:56, Redis 'CLIENT LIST') is a false
positive — getActiveSessions() uses this.client.client('LIST') at
redis.ts:455 (ioredis exposes CLIENT LIST as .client('LIST')), so the doc
and CLAUDE.md are correct. No change.
The 'dev' merge into this branch left two redundant descriptions of the
completion provider in Section 2 (one from #84, one from #85). Collapsed into a
single accurate paragraph: registerSQLCompletionProvider -> registerCompletion
ItemProvider('sql', …) with trigger characters '.' and space, registered from
QueryEditor.tsx. Verified triggerCharacters ['.', ' '] at sql-completions.ts:121.
@sonarqubecloud

Copy link
Copy Markdown

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 21 out of 22 changed files in this pull request and generated 3 comments.

Comment thread package.json
{
"name": "@libredb/studio",
"version": "0.9.26",
"version": "0.9.27",
Comment thread docs/FEATURES.md
* **SQL Databases:**
* **PostgreSQL:** Full support with connection pooling (`pg`), schema inspection, and maintenance tools.
* **MySQL:** Full support with connection pooling (`mysql2`), performance schema integration.
* **SQLite:** File-based database support (`better-sqlite3`) with WAL mode.
Comment thread docs/API_DOCS.md
Comment on lines 321 to +323
- `aggregate` - Aggregation pipeline
- `countDocuments` - Count documents
- `count` - Count documents matching a filter (runs `countDocuments` internally)
- `distinct` - Distinct values for a field (the field is taken from the first key of `options.projection`)
@cevheri

cevheri commented Jun 22, 2026

Copy link
Copy Markdown
Contributor Author

Closing — this branch targets dev, not main. Re-opened against the correct base as #87 (same branch, same commits). All review notes here are carried over and addressed in #87.

@cevheri cevheri closed this Jun 22, 2026
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