# Data Layer `internal/data` is the persistence composition root. It owns the shared database/runtime container (`Data`), database clients, configuration storage, and the Wire `ProviderSet`. Business repositories live in submodules so a new feature can be found by its domain instead of by scanning one large package. ## Modules - `internal/data/system` contains the built-in administration domain: users, authorities, APIs, permissions, menus, organization, dictionaries, parameters, tokens, security, audit/logging, media, announcements, tasks, versions, exports, bootstrap seeding, and system migrations. - `internal/data/payment` contains payment configuration and payment-order persistence. Provider SDK implementations are separate in `internal/integration/payment`. - `internal/data/migration` contains the version-table runner used by the root migration coordinator. It stays under data because it executes and records database schema steps. - `internal/adminsurface` contains the small menu/API metadata contract used when a business module contributes pages to the administration UI. It lives outside `data` because the contract itself is not persistence code. The root package intentionally keeps only cross-cutting infrastructure: database lifecycle/reloads, runtime configuration persistence, data-scope auditing, integration configuration storage, and migration orchestration. Repositories depend on narrow module seams (`system.Provider` and `payment.Provider`) rather than importing the root implementation details. First-install and configuration-management orchestration lives in `internal/initialize`. It implements `biz.InitializationRepo` through a narrow backend interface that `*data.Data` satisfies. This keeps administrator/menu/API seeding out of the database lifecycle package while retaining one migration entry point. Non-database adapters remain under `internal/integration` (storage, email, payment SDKs, and cache). Their constructors are provided by `internal/integration.ProviderSet`, separate from the data provider set. GORM and pagination helpers live beside the data layer; stateless payment parsing lives in `internal/utils/paymentutil`; admin JWT handling lives in `internal/security/adminauth`. ## Migration and bootstrap There is one migration execution entry point: `migrateAll` in the root data package. The root owns the shared integration-configuration table and appends the steps returned by `system.Migrations()` and `payment.Migrations()`. Migrations create schemas and module-required fixed records only. Initial business data is separate: `initialize.Repo` invokes `system.SeedSystem` only from the explicit first-install flow to create the administrator, roles, menus, APIs, departments, policies, and module-provided administration surfaces.