Skip to main content

database-change

Changes the DotNetForge CMS database schema or seed data safely: entity in src/DotNetForge.Shared/Entities, fluent configuration in DotNetForgeDbContext, EF Core migrations in src/DotNetForge.Data/Database/Providers/<Database>/Migrations via the pinned dotnet-ef tool, idempotent DataSeeder changes, migrations for every SQL provider (SQLite DotNetForgeDbContext, PostgreSqlDbContext, SqlServerDbContext, MySqlDbContext; MongoDB needs none), and .docs/architecture/database.md. Use when asked to add or change a table, column, index, relationship, enum stored in the DB, or seed data, or to create/fix a migration.

Source facts

Repository
Albadit/DotNetForge
Last source activity
October 6, 2026 at 02:19
Detected SKILL.md language
English
Stars
0
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
database-change
description
Changes the DotNetForge CMS database schema or seed data safely: entity in src/DotNetForge.Shared/Entities, fluent configuration in DotNetForgeDbContext, EF Core migrations in src/DotNetForge.Data/Database/Providers/<Database>/Migrations via the pinned dotnet-ef tool, idempotent DataSeeder changes, migrations for every SQL provider (SQLite DotNetForgeDbContext, PostgreSqlDbContext, SqlServerDbContext, MySqlDbContext; MongoDB needs none), and .docs/architecture/database.md. Use when asked to add or change a table, column, index, relationship, enum stored in the DB, or seed data, or to create/fix a migration.
# Database change Read first: `.docs/architecture/database.md`. ## Steps 1. **Entity** - add/change the class in `src/DotNetForge.Shared/Entities/` (plain POCO, `Guid Id = Guid.NewGuid()`, `TenantId` for tenant-scoped data, UTC `DateTime`s). Enums go in `src/DotNetForge.Shared/Enums/Enums.cs` (stored as int - append values, never renumber). 2. **Mapping** - in `DotNetForgeDbContext.OnModelCreating`: key, `IsRequired()`, `HasMaxLength(...)` for every string, indexes (unique ones include `TenantId` for tenant-scoped data), relationships + delete behaviour, `Ignore(...)` for computed properties. New table → add a `DbSet<T>` property. 3. **Migrations - one per SQL provider** (from the repository root; generating never connects to a database): ```bash dotnet tool restore for ctx in DotNetForgeDbContext:Sqlite PostgreSqlDbContext:PostgreSql \ SqlServerDbContext:SqlServer MySqlDbContext:MySql; do dotnet ef migrations add <PascalCaseName> --project src/DotNetForge.Data --startup-project src/DotNetForge.Data \ --context "${ctx%%:*}" --output-dir "Database/Providers/${ctx#*:}/Migrations" done ``` Then: - Strip the UTF-8 BOM EF writes (`.editorconfig` charset is `utf-8`; `dotnet format` flags `CHARSET`). - Check there is exactly one `<Context>ModelSnapshot.cs` per folder; don't pass `--namespace`, EF then writes the snapshot elsewhere. - `dotnet ef migrations has-pending-model-changes --context <Context>` must report no changes. - Read the generated `Up`/`Down` of all four. Indexed strings need `HasMaxLength` (SQL Server/MySQL can't index unbounded text). Integer keys that get explicit values must not become identity columns (SQL Server; see `SqlServerDbContext`). - Never edit an already-committed migration: add a new one. 4. **Apply** - every provider prepares its schema at startup (`DatabaseInitializer` → the provider's `InitializeSchemaAsync`: migrations, or `EnsureCreated` for MongoDB, which adds new collections/indexes but never changes existing indexes). - Verify on real servers with the integration tests: `DNF_TEST_POSTGRES`, `DNF_TEST_SQLSERVER`, `DNF_TEST_MYSQL`, `DNF_TEST_MONGODB` (`docker compose -f docker/compose.dev.yml --profile <db> up -d`; `.docs/guides/testing.md#databases`). - Writing `DateTime` values: always UTC. 5. **Seed data** - only in `src/DotNetForge.Data/DataSeeder.cs`, guarded so it is idempotent (it runs on every start). Use constants from `src/DotNetForge.Shared/Constants`. 6. **Callers** - update view models, `PageService`-style mapping, API projections; unique-index violations surface as `DbUpdateException` - validate in the owning service first. Queries stay single-table (no joins, no navigation properties across tables) so MongoDB can run them (`.docs/database/mongodb.md#query-rules`). 7. **Tests** - build and run both test projects; integration tests migrate a fresh SQLite DB, and with a `DNF_TEST_*` server a fresh database of that kind per test, which catches broken migrations. New string columns: add a length check in the owning service (PostgreSQL, SQL Server and MySQL enforce `HasMaxLength`, SQLite does not). 8. **Docs** - `.docs/architecture/database.md` (table row, ER diagram if relationships changed, migrations table, seeding table); feature docs that describe the entity's fields. 9. Run the **verify** skill. ## Don't - Use raw SQL, `EnsureCreated`, or `Database.Migrate` from anywhere but `DatabaseInitializer`. - Add a migration for only some of the SQL providers. - Reference `DotNetForge.Data` from `DotNetForge.Core` (add a store interface in `Shared/Stores` instead). - Delete `storage/dotnetforge.db` on someone else's machine; locally it resets the CMS to the setup wizard.
View on GitHub