feat: phase 2 databases via DBX (v0.3.0)

- dbx-mcp persistent stdio subprocess in Go backend (internal/dbx),
  lazy start + single retry, tool failures surface as 502
- core.db_connections registry: per-project connections, credentials
  server-side only, managed entries protected (409)
- platform-postgres + platform-dragonfly auto-register per project
- REST proxy: list/create/delete/test, databases, tables, describe,
  schema context, SQL query, redis command
- Databases page: connection list, schema/table browser, column
  inspector, SQL editor with result grid + row detail, redis console
- backend image moved to debian-slim for glibc; pinned dbx release
  with SHA256 verification

Authored By: TDvorak <[email protected]>
This commit is contained in:
Tomas Dvorak committed 2026-09-16 14:54:33 +02:00
1 parent 420502eec1
commit 627bd89d5e
71 files changed
+3685 -49

No files matched your search

@@ -19,16 +19,19 @@ import (
"github.com/jackc/pgx/v5/pgtype"
db "github.com/tdvorak/primora/apps/backend/internal/database/db"
"github.com/tdvorak/primora/apps/backend/internal/dbx"
"github.com/tdvorak/primora/apps/backend/internal/models"
"github.com/tdvorak/primora/apps/backend/internal/repositories"
"github.com/tdvorak/primora/apps/backend/internal/storage"
)
type PlatformService struct {
repo *repositories.CoreRepository
store *storage.LocalStore
mailer *Mailer
publicURL string
repo *repositories.CoreRepository
store *storage.LocalStore
mailer *Mailer
publicURL string
dbx *dbx.Client
managedDBSeeds []ManagedDBSeed
}
type BootstrapInput struct {
@@ -206,8 +209,8 @@ type InvitationSummary struct {
Status string `json:"status"`
}
func NewPlatformService(repo *repositories.CoreRepository, store *storage.LocalStore, mailer *Mailer, publicURL string) *PlatformService {
return &PlatformService{repo: repo, store: store, mailer: mailer, publicURL: publicURL}
func NewPlatformService(repo *repositories.CoreRepository, store *storage.LocalStore, mailer *Mailer, publicURL string, dbxClient *dbx.Client, managedDBSeeds []ManagedDBSeed) *PlatformService {
return &PlatformService{repo: repo, store: store, mailer: mailer, publicURL: publicURL, dbx: dbxClient, managedDBSeeds: managedDBSeeds}
}
func (s *PlatformService) Me(ctx context.Context, actor *models.Actor) (PlatformSummary, error) {