Skip to content

chore: Auto-migrate and denpendencies#117

Merged
carlosrfjunior merged 2 commits into
mainfrom
feat-live-update
May 9, 2026
Merged

chore: Auto-migrate and denpendencies#117
carlosrfjunior merged 2 commits into
mainfrom
feat-live-update

Conversation

@carlosrfjunior
Copy link
Copy Markdown
Collaborator

No description provided.

@carlosrfjunior carlosrfjunior requested a review from Copilot May 9, 2026 19:31
@carlosrfjunior carlosrfjunior merged commit dfa55dd into main May 9, 2026
10 of 13 checks passed
@carlosrfjunior carlosrfjunior deleted the feat-live-update branch May 9, 2026 19:32
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces server-side startup auto-migration with bounded retry rounds, improves migration execution concurrency control, and adds dependency-aware batch ordering for the frontend/UI. It also standardizes Postgres backend name matching (postgres vs postgresql), updates docs/examples, and refreshes some frontend tooling and UI behaviors.

Changes:

  • Add startup auto-migrate loop (configurable enablement, connection filtering, retries, and readiness checks) and supporting executor helpers.
  • Add migration execution advisory-locking on the state DB plus history-status interpretation (success vs applied) consistency across APIs/UI.
  • Add “order migration batch” API + frontend integration to execute selected migrations in dependency order.

Reviewed changes

Copilot reviewed 38 out of 39 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
README.md Expands high-level project description to emphasize centralized migrations and dynamic schema creation.
ffm/vite.config.ts Adds Tailwind Vite plugin to the frontend Vite build pipeline.
ffm/src/types/api.ts Adds typed request/response models for the new order-batch endpoint.
ffm/src/services/api.ts Adds API client method for /v1/migrations/order-batch.
ffm/src/components/MigrationList.tsx Uses server-computed dependency ordering before executing selected migrations.
ffm/src/components/MigrationDetail.tsx Treats applied history status as applied (alongside success).
ffm/src/components/Dashboard.tsx Makes Recharts tooltip formatter more robust to non-number inputs.
ffm/postcss.config.cjs Removes Tailwind PostCSS config (shift toward Vite plugin flow).
ffm/package-lock.json Updates lockfile to reflect dependency/tooling changes.
examples/sfm/postgresql/core/20260101120100_core_schema_example_audit.up.sql Adds example fixed-schema migration (audit table).
examples/sfm/postgresql/core/20260101120100_core_schema_example_audit.down.sql Adds down migration for audit table.
examples/sfm/postgresql/core/20260101120100_core_schema_example_audit.go Registers new example migration script with dependency metadata.
examples/sfm/postgresql/core/20260101120000_core_schema_example_settings.up.sql Adds example fixed-schema settings table migration for auto-migrate.
examples/sfm/postgresql/core/20260101120000_core_schema_example_settings.down.sql Adds down migration for settings table.
examples/sfm/postgresql/core/20260101120000_core_schema_example_settings.go Registers new example migration script.
docs/DEPLOYMENT.md Documents startup auto-migrate behavior, retry semantics, readiness rules, and Postgres naming aliasing.
deploy/docker-compose.standalone.yml Bumps Postgres image and adjusts volume mount for PG 18+ layout.
deploy/docker-compose.dev.yml Same as standalone + adds env vars for auto-migrate in dev compose.
api/internal/state/postgresql/tracker.go Stabilizes history ordering and clarifies pending/applied semantics for concurrency checks.
api/internal/state/postgresql/advisory_lock.go Adds advisory-lock-based execution lock implementation.
api/internal/state/interface.go Extends StateTracker with WithMigrationExecutionLock contract.
api/internal/state/history_status.go Centralizes applied-history status interpretation (success and applied).
api/internal/state/errors.go Introduces ErrMigrationAlreadyInProgress.
api/internal/registry/interface.go Adds backend-name normalization/matching and applies it to registry lookups.
api/internal/registry/registry_test.go Adds tests for backend alias matching and FindByTarget alias behavior.
api/internal/registry/dependency_resolver_test.go Updates mock tracker to satisfy new StateTracker interface.
api/internal/executor/executor.go Adds auto-migrate context behavior, advisory lock integration, batch ordering helper, and pending-count helper.
api/internal/executor/executor_test.go Adds tests for auto-migrate dynamic-schema skipping and pending-count helper; updates mocks for new interface.
api/internal/executor/executor_cross_connection_test.go Updates mock tracker to satisfy new StateTracker interface.
api/internal/backends/postgresql/validator.go Avoids false schema-existence failures during bootstrap when schema-creating deps are in the execution set.
api/internal/backends/postgresql/validator_test.go Adds coverage for the new bootstrap schema existence behavior; updates mocks.
api/internal/api/protobuf/handler.go Aligns “applied” detection with shared history-status helper.
api/internal/api/http/handler.go Adds /migrations/order-batch endpoint and aligns applied detection with shared helper.
api/internal/api/http/handler_test.go Adds history-status test coverage and updates mocks for new interface.
api/internal/api/http/dto/migrations.go Adds DTOs for order-batch request/response.
api/cmd/server/main.go Adds root context/cancel and starts startup auto-migrate background task.
api/cmd/server/auto_migrate.go Implements startup auto-migrate loop (retry rounds, readiness checks, connection filtering).
api/cmd/server/auto_migrate_test.go Adds unit tests for retry/env parsing and connection readiness checks.
.pre-commit-config.yaml Excludes runtime-config JS from ESLint hook input set.
Files not reviewed (1)
  • ffm/package-lock.json: Language not supported

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

Comment thread ffm/vite.config.ts
Comment on lines +1 to 8
import tailwindcss from "@tailwindcss/vite";
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";

// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
plugins: [react(), tailwindcss()],
// Development server configuration (only used in dev mode)
Comment on lines +210 to +221
target := &registry.MigrationTarget{
Backend: cr.cfg.Backend,
Connection: cr.name,
}
runCtx := executor.WithAutoMigrateContext(executor.SetExecutionContext(context.Background(), "bfm-server", "auto_migrate", map[string]interface{}{
"connection": cr.name,
"source": "BFM_AUTO_MIGRATE",
"round": round,
}))

logger.Infof("Auto-migrate: running pending migrations for connection %q (backend=%s)", cr.name, cr.cfg.Backend)
result, err := exec.ExecuteUp(runCtx, target, cr.name, []string{""}, false, false)
Comment on lines +42 to +58
func connectionConfigReadyForAutoMigrate(conn *backends.ConnectionConfig) bool {
if conn == nil {
return false
}
switch strings.ToLower(strings.TrimSpace(conn.Backend)) {
case "postgresql":
return strings.TrimSpace(conn.Host) != ""
case "greptimedb":
return strings.TrimSpace(conn.Host) != ""
case "etcd":
if etcdEndpointsExtraNonEmpty(conn.Extra) {
return true
}
return strings.TrimSpace(conn.Host) != "" && strings.TrimSpace(conn.Port) != ""
default:
return true
}
Comment on lines +928 to +936
// OrderMigrationBatch returns migration_ids sorted in dependency order for the given connection.
// Duplicate IDs are preserved in the output (grouped after their migration's topological position).
func (e *Executor) OrderMigrationBatch(migrationIDs []string, connection string) ([]string, error) {
if len(migrationIDs) == 0 {
return nil, nil
}
if connection == "" {
return nil, fmt.Errorf("connection is required")
}
Comment on lines +928 to +982
// OrderMigrationBatch returns migration_ids sorted in dependency order for the given connection.
// Duplicate IDs are preserved in the output (grouped after their migration's topological position).
func (e *Executor) OrderMigrationBatch(migrationIDs []string, connection string) ([]string, error) {
if len(migrationIDs) == 0 {
return nil, nil
}
if connection == "" {
return nil, fmt.Errorf("connection is required")
}

type pair struct {
id string
m *backends.MigrationScript
}
pairs := make([]pair, 0, len(migrationIDs))
var unknown []string
for _, id := range migrationIDs {
m := e.GetMigrationByID(id)
if m == nil {
unknown = append(unknown, id)
continue
}
if m.Connection != connection {
return nil, fmt.Errorf("migration %s belongs to connection %q, expected %q", id, m.Connection, connection)
}
pairs = append(pairs, pair{id: id, m: m})
}
if len(unknown) > 0 {
return nil, fmt.Errorf("unknown migration_id(s): %s", strings.Join(unknown, ", "))
}

byBase := make(map[string][]string)
seenBase := make(map[string]bool)
var unique []*backends.MigrationScript
for _, p := range pairs {
base := e.getMigrationID(p.m)
byBase[base] = append(byBase[base], p.id)
if !seenBase[base] {
seenBase[base] = true
unique = append(unique, p.m)
}
}

sorted, err := e.resolveDependencies(unique)
if err != nil {
return nil, err
}

out := make([]string, 0, len(migrationIDs))
for _, m := range sorted {
base := e.getMigrationID(m)
out = append(out, byBase[base]...)
}
return out, nil
}
Comment on lines 40 to 45
})

api.POST("/migrations/up", h.authenticate, h.migrateUp)
api.POST("/migrations/order-batch", h.authenticate, h.orderMigrationBatch)
api.POST("/migrations/down", h.authenticate, h.migrateDown)
api.GET("/migrations", h.authenticate, h.listMigrations)
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