Understand onepixel database topology by environment, data ownership across app/events stores, and initialization/migration behavior.
Use this skill when changing config, models, controllers, or test setup that touches persistence.
onepixel.local.env):
sqlite (DB_DIALECT=sqlite, DATABASE_URL=app.db)duckdb (EVENTDB_DIALECT=duckdb, EVENTDB_URL=events.db)USE_FILE_DB=true enables file-backed providers.ENV=test + onepixel.test.env):
sqlite (app.db)duckdb (events.db)onepixel_backend/tests/providers to inject test DB providers.onepixel.production.env):
USE_FILE_DB=falsepostgres (DB_DIALECT=postgres).postgres by default because COMMON_APP_EVENT_DB=true and EVENTDB_DIALECT=postgres.clickhouse for events when EVENTDB_DIALECT=clickhouse and COMMON_APP_EVENT_DB=false.users (models.User)url_groups (models.UrlGroup)urls (models.Url)events_redirect (models.EventRedirect)./GeoLite2-City.mmdb), opened by db.GetGeoIPDB() for enrichment; not managed by GORM migrations.src/db/init.go:
GetAppDB, GetEventsDB, and GetGeoIPDB each guarded by sync.Once.src/main.go eagerly initializes all three DB clients.db.init() based on config.UseFileDB:
sqlite, duckdbpostgres, clickhousesrc/db/providers.go:
postgres/clickhouse open with retry (attemptToOpen, 10 attempts with 1s delay).sqlite/duckdb open directly.AutoMigrate in src/db/init.go.GetAppDB):
User, UrlGroup, Url.lo.Must0), so startup/first access fails fast.GetEventsDB):
EventRedirect.lo.TryWithErrorValue + applogger.Error).tests/providers/test_db_providers.go overrides sqlite and duckdb providers via db.InjectDBProvider._ "onepixel_backend/tests/providers").make test_clean removes app.db and events.db before each test suite target.ENV=test also changes cwd to repo root in src/config/env.go, ensuring relative DB paths resolve consistently.