refactor(server): rename Org to Instance

Adds migration 0004_org_to_instance, the ScopedCollections list, the
AssertNoScopedCollectionMissed boot check, and moves EnsureAuthIndexes into
its own file.

Two ordering constraints the rename exposed, both now enforced and commented:

- 0004 must run BEFORE EnsureAuthIndexes. The index builder creates
  instances.slug, which would create an empty instances collection and make
  0004 refuse to rename orgs onto an existing target.
- Migrations 0001 to 0003 run BEFORE 0004 and still read and write org_id, so
  they use a private legacyOrg struct rather than shared/models.
This commit is contained in:
2026-07-24 13:58:41 +01:00
parent 43a2fdb3a0
commit 4f041d2f4b
61 changed files with 895 additions and 967 deletions
+31 -26
View File
@@ -19,9 +19,6 @@ func main() {
mongoURI := getEnv("MONGO_URI", "mongodb://localhost:27017")
dbName := getEnv("MONGO_DB", "vantage")
if os.Getenv("GRPC_HOST") == "" {
log.Fatal("GRPC_HOST is required (host:port agents dial for gRPC)")
}
@@ -31,19 +28,13 @@ func main() {
}
log.Println("connected to MongoDB")
if err := services.EnsureAuthIndexes(); err != nil {
log.Fatalf("failed to ensure auth indexes: %v", err)
}
// Migrations 0001 to 0003 still speak the pre-rename shape (orgs, org_id),
// so they must run before 0004 renames everything underneath them.
if err := services.RunMigrations(); err != nil {
log.Fatalf("migration failed: %v", err)
}
// 0002 must precede 0003: 0003 can create a "default" org, which pushes
// 0002 into its ambiguous multi-org branch.
if err := services.MigrateSettingsOrg(); err != nil {
log.Fatalf("settings org migration failed: %v", err)
}
@@ -51,13 +42,31 @@ func main() {
log.Fatalf("missed org scope migration failed: %v", err)
}
// 0004 renames orgs to instances. It must run BEFORE the index builders:
// EnsureAuthIndexes creates instances.slug, which would create an empty
// instances collection and make 0004 refuse to rename onto it.
migCtx, migCancel := context.WithTimeout(context.Background(), 10*time.Minute)
migErr := services.MigrateOrgToInstance(migCtx, db.Database)
migCancel()
if migErr != nil {
log.Fatalf("instance rename migration failed: %v", migErr)
}
assertCtx, assertCancel := context.WithTimeout(context.Background(), 30*time.Second)
assertErr := services.AssertNoScopedCollectionMissed(assertCtx, db.Database)
assertCancel()
if assertErr != nil {
log.Fatalf("scoped collection check failed: %v", assertErr)
}
if err := services.EnsureAuthIndexes(); err != nil {
log.Fatalf("failed to ensure auth indexes: %v", err)
}
if err := services.EnsureSecretIndexes(); err != nil {
log.Printf("warning: failed to ensure secret indexes: %v", err)
}
if err := services.EnsureSettingsIndexes(); err != nil {
log.Fatalf("failed to ensure settings indexes: %v", err)
}
@@ -66,14 +75,14 @@ func main() {
log.Printf("warning: failed to ensure workflow indexes: %v", err)
}
if orgIDs, err := services.ListOrgIDs(); err != nil {
log.Printf("warning: failed to list orgs for default step seeding: %v", err)
if instanceIDs, err := services.ListInstanceIDs(); err != nil {
log.Printf("warning: failed to list instances for default step seeding: %v", err)
} else {
for _, orgID := range orgIDs {
if created, updated, err := services.SeedDefaultSteps(orgID); err != nil {
log.Printf("warning: failed to seed default steps for org %s: %v", orgID, err)
for _, instanceID := range instanceIDs {
if created, updated, err := services.SeedDefaultSteps(instanceID); err != nil {
log.Printf("warning: failed to seed default steps for instance %s: %v", instanceID, err)
} else {
log.Printf("default steps seeded for org %s: %d created, %d updated", orgID, created, updated)
log.Printf("default steps seeded for instance %s: %d created, %d updated", instanceID, created, updated)
}
}
}
@@ -86,7 +95,6 @@ func main() {
}
log.Println("connected to Redis")
go func() {
ticker := time.NewTicker(2 * time.Minute)
defer ticker.Stop()
@@ -97,17 +105,14 @@ func main() {
}
}()
go func() {
if err := grpcserver.StartGRPC(9090); err != nil {
log.Fatalf("gRPC server error: %v", err)
}
}()
monitorsched.Start(context.Background())
r := gin.New()
r.Use(gin.Recovery())
r.Use(gin.LoggerWithConfig(gin.LoggerConfig{SkipPaths: []string{"/api/console/tunnel"}}))