Move production persistence from the local SQLite file to Supabase Postgres without breaking local development. The application code now supports both providers through configuration:
Database:Provider=sqliteusesConnectionStrings:SiteContextDatabase:Provider=postgresusesConnectionStrings:Postgres
- Local development defaults to SQLite.
- Existing EF Core migrations under
Migrations/were generated against SQLite. - Production target is Supabase Postgres.
- Initial connectivity should use the Supabase session pooler because it supports IPv4 for both local development and first deployment.
- Uploaded files still live under
wwwroot/Uploads, so storage cutover remains a separate task.
- Provision the Supabase Postgres database and collect the session pooler connection string for initial rollout.
- Switch a local development environment to Postgres with
Database__Provider=postgresandConnectionStrings__Postgres=...using the session pooler. - Create a PostgreSQL baseline migration in the dedicated
Modisette.PostgresMigrationproject so the existing SQLite migration history can stay intact. - Apply the Postgres migration to an empty Supabase database.
- Export the current SQLite data and import it into Postgres.
- Validate the app locally against Postgres before any deployment cutover.
- Update the Render production environment to use the Postgres provider and session pooler connection string.
- Deploy and verify CRUD, contact submissions, and admin login on the hosted site.
- After initial deployment is stable, reevaluate direct Postgres connectivity from the hosting environment and switch from the session pooler to the direct connection string only if IPv6 connectivity is confirmed or an IPv4-capable direct option is available.
The current migrations include SQLite-specific annotations such as Sqlite:Autoincrement. That means the safest cutover is usually one of these approaches:
- Create a fresh Postgres baseline migration once the model is stable.
- Or maintain provider-specific migrations if you need both providers to evolve independently.
For this project, a fresh Postgres baseline in a separate migrations assembly is the lower-complexity path.
- Keep SQLite as the default local provider.
- Add Postgres provider support in application startup and design-time EF tooling.
- Create the first Postgres baseline migration.
- Add a small one-time data migration path from SQLite to Postgres.
- Cut production over to Supabase using the session pooler.
- After launch, test whether the production host can use Supabase's direct connection path safely and reliably.
- Later, switch production from session pooler to direct connection if IPv6 support is verified and the operational tradeoff is worthwhile.
- Later, remove SQLite entirely if local file-based development is no longer useful.
dotnet build --configuration Release modisette.slndotnet test --configuration Release modisette.slndotnet ef dbcontext infowith SQLite settingsdotnet ef dbcontext infowith Postgres settingsdotnet ef database updateagainst a disposable Postgres database- Manual verification of contact form persistence, admin CRUD, and content reads