Files
worker/app/models/drop.go
Gleb Tv 2c7a0236da feat: publish standalone worker
Separate worker packaging and service lifecycle from the control plane.
2026-07-13 17:55:14 +03:00

97 строки
4.1 KiB
Go

package models
import (
"fmt"
"strings"
"rsgit.ru/rsmon/rsmon/app/models/authidentity"
)
// Drop removes all test data from the database.
// It uses TRUNCATE ... CASCADE for join tables and deletes leaf-to-root for main tables.
// Safe to call from multiple goroutines within a single test binary; concurrent calls
// from separate test binaries are serialized by the advisory lock in Migrate().
func Drop() {
var dbname string
if err := DB().Raw("SELECT current_database()").Scan(&dbname).Error; err != nil {
panic(fmt.Sprintf("Drop: cannot read database name: %v", err))
}
if !strings.Contains(dbname, "test") {
panic(fmt.Sprintf(
"Drop() refused: database '%s' is not a test database. "+
"Set DATABASE_NAME=rsmon_test to run tests safely.", dbname,
))
}
// Truncate many2many join tables first to avoid FK violations.
DB().Exec("TRUNCATE event_checks, event_messages, notification_contacts, notification_groups RESTART IDENTITY CASCADE")
// Delete main tables in dependency order (leaf tables first).
DB().Where("1=1").Delete(&NotificationDelivery{})
DB().Where("1=1").Delete(&TaskReplay{})
DB().Where("1=1").Delete(&TelegramBotMessage{})
DB().Where("1=1").Delete(&TelegramBotStatus{})
DB().Where("1=1").Delete(&Task{})
DB().Where("1=1").Delete(&Access{})
DB().Where("1=1").Delete(&Invite{})
DB().Where("1=1").Delete(&Message{})
DB().Where("1=1").Delete(&Event{})
// Durable network-diagnostic rows reference checks, monitors, and workers.
DB().Where("1=1").Delete(&DiagnosticAuditEvent{})
DB().Where("1=1").Delete(&CheckAttempt{})
// CheckRegionResult FKs check_id; it must be cleared before Check.
DB().Where("1=1").Delete(&CheckRegionResult{})
DB().Where("1=1").Delete(&Check{})
DB().Where("1=1").Delete(&Notification{})
// DNSRecord FKs monitor_id; it must be cleared before Monitor.
DB().Where("1=1").Delete(&DNSRecord{})
DB().Where("1=1").Delete(&Monitor{})
DB().Where("1=1").Delete(&Group{})
DB().Where("1=1").Delete(&Contact{})
DB().Where("1=1").Delete(&NotificationCredential{})
DB().Where("1=1").Delete(&WorkerLogEvent{})
DB().Where("1=1").Delete(&WorkerNode{})
DB().Where("1=1").Delete(&LLM{})
DB().Where("1=1").Delete(&Region{})
// Inventory (docs/plans/inventory-management.md §6): leaf tables
// (sites, deployments, server_ips) reference accounts/servers, so
// they must be cleared before Server is deleted.
DB().Where("1=1").Delete(&Deployment{})
DB().Where("1=1").Delete(&SiteRepo{})
DB().Where("1=1").Delete(&Site{})
DB().Where("1=1").Delete(&Repo{})
DB().Where("1=1").Delete(&ServerIp{})
DB().Where("1=1").Delete(&Domain{})
DB().Where("1=1").Delete(&Server{})
// Account-scoped tag metadata (account_id FK to accounts(id)).
// Cleared before Account so a future cascade change cannot orphan
// rows mid-truncate.
DB().Where("1=1").Delete(&Tag{})
// Status pages (docs/plans/status-pages.md §3.1–3.5). Children
// reference status_pages(id) with ON DELETE CASCADE so GORM
// ordering would already wipe them, but we delete them
// explicitly so the test DB stays clean even if a future model
// change drops the cascade.
DB().Where("1=1").Delete(&StatusPageDomain{})
DB().Unscoped().Where("1=1").Delete(&Maintenance{})
DB().Where("1=1").Delete(&StatusPageMaintenance{})
DB().Where("1=1").Delete(&StatusPageIncident{})
DB().Where("1=1").Delete(&StatusPageDelivery{})
DB().Where("1=1").Delete(&StatusPageDigestSchedule{})
DB().Where("1=1").Delete(&StatusPageSubscriber{})
DB().Unscoped().Where("1=1").Delete(&StatusPage{})
DB().Where("1=1").Delete(&SubscriptionEvent{})
DB().Where("1=1").Delete(&Subscription{})
DB().Where("1=1").Delete(&Account{})
DB().Unscoped().Where("1=1").Delete(&authidentity.AuthIdentity{})
// User has a unique email index, so test fixtures must be physically
// removed rather than soft-deleted between tests.
DB().Unscoped().Where("1=1").Delete(&User{})
// A few audited tables added by feature migrations can retain a user FK that
// is intentionally not modeled as an association. CASCADE keeps fixture
// cleanup deterministic instead of silently leaving unique emails behind.
DB().Exec("TRUNCATE users CASCADE")
DB().Exec("TRUNCATE regions CASCADE")
}