Repository navigation
Conversation
…rough their binding dms-database enumerates the named interface-database-catalog connections that have an interface-database connection of the same id, and serves the own database and each external one under /api/database/connections. Rows are read and edited through the browse layer, which now takes the Database a request names. Writes to an external connection stay off until its toggle, stored in connection_settings, turns them on.
The guard lived in the own browse route only, so PUT /api/database/connections/own/row edited whichever instance held the id. editRow now refuses it for every caller.
…quests Core answers a module's connections in that module's context, and a request reaches the controller in the API module's, where dms-database's named connections are invisible. The module records itself at construct and the lookups and binding loads run as it.
Lists the project database and every external connection, toggles an external connection's writes, and shows its catalog relations and their first rows. Also moves the interface-database-catalog and test fixture ranges to the >=x.y.z <1.0.0 shape lint requires.
… what its state does The switch's accessible name stayed on its first state, and the hint said edits are refused while writes were on.
Upd4ting
marked this pull request as ready for review
November 11, 2026 21:22
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
dms-database only showed the project's own database. It now also lists every external database the connect flow added, so users see all their data in one place. Each external database is read and edited through its own
interface-databasebinding, with the same browse layer as the own database. Edits stay off until the owner turns them on for that database.⚠ sensitive: this writes to a customer's external database, and it adds a stored table,
connection_settings.What changes
Connections list.
GET /api/database/connectionsreturns the own database first, then each external connection withid,kind,label,engine,writesandunsupported.@antelopejs/interface-database-catalogconnection that has an@antelopejs/interface-databaseconnection with the same id on this module's entry.engineandlabelcome from the catalog'sInfo(). When the catalog refuses, outside development,engineisnullandlabelfalls back to the connection id.Description from the catalog.
GET /<id>/relationsreturnsListRelationsandGET /<id>/relations/<schema>.<name>returnsDescribeRelations. A catalog refusal comes back as409with its reason, and an unknown relation as404.Reads and writes through the binding.
GET /<id>/rows,GET /<id>/rowandPUT /<id>/rowtake the Data browser's query parameters.Databasehandle (src/service/database.ts): the own database, orrequire(GetInterfaceInstance(...).path)for an external one.browse.ts,declaredFields.tsand the neweditRowinrowEdit.tstake that handle. The existing/api/database/browse/*routes pass the own database and behave as before.Writes toggle.
PUT /<id>/writeswith{ "enabled": boolean }sets it.connection_settings, keyed by connection id, and starts off. While it is off, an edit is refused with403.Unsupported features. An external connection reports
migrations,schemaEdits,indexes,diagram,queryConsole,instancesandrowReferences. Its tables have no instances, so a request on one that namesfilter_instancegets a400.Module context. Core answers a module's named connections only in that module's own context, and an API request reaches the controller in the API module's context. The module records its id at
construct(), and the lookups and binding loads run underRunWithResponsibleModule.Minimal UI. A new Connections page (
/modules/database/connections) shows:The designed switcher and external view come after the design session.
Docs. The new page
docs/4.usage/6.external-databases.md, plus one line in the README.The config shape ANT-2044 must write
The connect flow (ANT-2044, dms-assistant) must add these entries to the dms-database module entry, next to what it already writes for the provider and the tables module:
interface-databaseentry pins the default binding. Without the own-database entry first, dms-database's own tables would move to the external database.interface-database@<provider>copy, soSchema.list()on the named binding lists them.RemoveConnectionremoves a named connection from every module'simportOverrides, which covers both named entries. The own-database pin stays.Proof
The new tests boot a real DMS with:
mongodb-erp, inmode: "external", on a seedederpdatabase;test-fixtures/erp-tables;src/test/harness.ts.Before, on
mainwith this harness. The only browse API cannot reach the external table:Before the module-context fix. Over HTTP, the list holds only the own database:
After:
Other results:
pnpm test:layerpasses: 168 tests, including two for the Connections page.pnpm run checkspasses: 12 of 12.flowchart LR UI[Connections page] -->|GET/PUT /api/database/connections/:id/...| C[DatabaseConnectionsController] C -->|own| OWN[OWN_DATABASE: Schema.list] C -->|external id| R[resolveDatabase / resolveCatalog] R -->|RunWithResponsibleModule dms-database| L[GetInterfaceInstance + require path] L --> DB[interface-database@provider: Schema.list, queries] L --> CAT[interface-database-catalog@provider: Info, ListRelations, DescribeRelations] C -->|PUT row| W{writes on?} W -->|no| X[403] W -->|yes| E[editRow through the binding] E --> DBReview
Two adversarial reviewers, on Opus and Sonnet, attacked the change. Both findings are fixed, and each fix has its own test:
PUT /own/rowedited across all instances, which the old edit route refuses. The guard now lives ineditRow.They also probed these, and the code held:
/erp/rows;_idedits;Follow-ups
ExternalWriteErrorinstead of a mapped4xx.