Switches the database from SQL Server to MariaDB
The target Pi only has MariaDB, and SQL Server has no ARM64 build at all - not a config problem, a real gap discovered during deployment setup. Swapped the EF Core provider, regenerated every migration, updated connection strings and the backup script everywhere they appear. Took two tries to land on a provider that actually works: Pomelo builds fine against this project's EF Core 10 packages but fails at runtime (it's compiled against 9's internal API surface, which moved in 10 wherever Identity/DataProtection force the newer packages). Oracle's official provider builds and migrates fine but has a real MariaDB bug in its own migration-lock code, reproduced against a live database. Kept Oracle's provider and worked around just that one broken method - everything else it does is correct - rather than give up more of the stack to chase a workaround. Verified against a real local MariaDB end to end: all three migrations applied, both hosts start clean, full suite still green.
This commit is contained in:
@@ -13,13 +13,18 @@ Een modulaire monolith CMS gebouwd met .NET 10.
|
|||||||
|
|
||||||
### Vereisten
|
### Vereisten
|
||||||
- .NET 10 SDK
|
- .NET 10 SDK
|
||||||
- Podman of Docker (voor SQL Server)
|
- Podman of Docker (voor MariaDB)
|
||||||
|
|
||||||
### 1. Database opstarten
|
### 1. Database opstarten
|
||||||
Start een SQL Server container met de volgende opdracht:
|
Start een MariaDB-container met de volgende opdracht:
|
||||||
```powershell
|
```powershell
|
||||||
podman run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=<your_password>" -p 1433:1433 --name sql-server -d mcr.microsoft.com/mssql/server:2022-latest
|
podman run -e "MARIADB_ROOT_PASSWORD=<your_password>" -p 3306:3306 --name mariadb -d docker.io/library/mariadb:latest
|
||||||
```
|
```
|
||||||
|
> **Migratie-notitie**: dit project draaide tot 2026-07-28 op Microsoft SQL Server. Overgestapt naar
|
||||||
|
> MariaDB omdat de productie-Pi geen SQL Server kan draaien (geen ARM64-build bestaat) en al MariaDB
|
||||||
|
> heeft geïnstalleerd. Zie `aidlc-docs/features/gitea-deployment-workflow/` voor de volledige
|
||||||
|
> rationale. Bestaande lokale SQL Server-databases/migraties zijn niet compatibel — begin met een
|
||||||
|
> verse MariaDB-database.
|
||||||
|
|
||||||
### 2. Configuratie
|
### 2. Configuratie
|
||||||
De applicatie maakt gebruik van een drie-bestanden patroon voor configuratie:
|
De applicatie maakt gebruik van een drie-bestanden patroon voor configuratie:
|
||||||
@@ -31,7 +36,7 @@ Zorg dat er een `src/SlpModularCms.Api/appsettings.local.json` aanwezig is met d
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"DefaultConnection": "Server=127.0.0.1,1433;User ID=sa;Password=<your_password>;Database=SlpModularCms;TrustServerCertificate=True;MultipleActiveResultSets=true"
|
"DefaultConnection": "Server=127.0.0.1;Port=3306;Database=SlpModularCms;Uid=root;Pwd=<your_password>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -57,6 +57,72 @@
|
|||||||
- **Artifacts**: `operations/deployment/deployment-plan.md`, `deployment-instructions.md`,
|
- **Artifacts**: `operations/deployment/deployment-plan.md`, `deployment-instructions.md`,
|
||||||
`rollback-plan.md`
|
`rollback-plan.md`
|
||||||
|
|
||||||
|
### Database Provider Migration — SQL Server → MariaDB (2026-07-29)
|
||||||
|
|
||||||
|
Discovered while finalizing Deployment Setup: the target Pi only runs MariaDB, and Microsoft SQL
|
||||||
|
Server has **no ARM64 build at all** (the `mcr.microsoft.com/mssql/server` image is `linux/amd64`
|
||||||
|
only; Azure SQL Edge, the former ARM answer, is retired). This invalidates ASM-04. Confirmed no
|
||||||
|
other machine is available, and the eventual production host (`mijnhostingpartner.nl`) will also
|
||||||
|
run MariaDB, plus the workload is small enough that MariaDB's performance is not a concern — user
|
||||||
|
decided: switch the database provider, not the deployment target.
|
||||||
|
|
||||||
|
**What changed** (application code, not just Operations docs):
|
||||||
|
- `SlpModularCms.Core.csproj`: `Microsoft.EntityFrameworkCore.SqlServer` → `MySql.EntityFrameworkCore`
|
||||||
|
10.0.7 (Oracle's official provider)
|
||||||
|
- `UseSqlServer(...)` → `UseMySQL(...)` in `ServiceCollectionExtensions.cs`, `AvailabilityModule.cs`,
|
||||||
|
`MasterModule.cs`
|
||||||
|
- `DatabaseMigrationExtensions.cs` + its test: `Microsoft.Data.SqlClient.SqlException` →
|
||||||
|
`MySql.Data.MySqlClient.MySqlException` for the transient-failure classifier
|
||||||
|
- All three DbContexts' migrations deleted and regenerated (`ApplicationDbContext`,
|
||||||
|
`AvailabilityDbContext`, `MasterDbContext`) — no MySQL/MariaDB model-compatibility issues surfaced
|
||||||
|
(no index-length problems, no raw SQL anywhere in the codebase to translate)
|
||||||
|
- Connection strings updated across `appsettings.json` (Api + Api.Slave, all three tiers) from
|
||||||
|
SQL Server format to MySQL format
|
||||||
|
- `README.md` dev setup: MariaDB container command replacing the SQL Server one, with a migration
|
||||||
|
note for anyone returning to old instructions
|
||||||
|
- `deployment-instructions.md` / `rollback-plan.md`: connection string format, backup script
|
||||||
|
rewritten around `mariadb-dump` (was `sqlcmd`/`BACKUP DATABASE`), restore procedure rewritten
|
||||||
|
|
||||||
|
**Provider selection — two failed attempts before the working one, both reproduced against a real
|
||||||
|
MariaDB instance, not just reasoned about:**
|
||||||
|
1. **Pomelo.EntityFrameworkCore.MySql** (the usual first choice, explicit first-class MariaDB
|
||||||
|
support) — caps at EF Core 9.x, no EF Core 10 release exists. A Pomelo maintainer states
|
||||||
|
([PR #2017](https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql/pull/2017))
|
||||||
|
that Pomelo 9 / EF Core 9 packages work fine on a net10.0 TFM — confirmed true only when nothing
|
||||||
|
else forces EF Core 10 packages. This project's `Microsoft.AspNetCore.Identity.EntityFrameworkCore`
|
||||||
|
and `Microsoft.AspNetCore.DataProtection.EntityFrameworkCore` are versioned in lockstep with the
|
||||||
|
.NET 10 runtime and hard-require EF Core >= 10.0.9, so the resolved `Microsoft.EntityFrameworkCore.Abstractions`
|
||||||
|
ends up at 10.0.9 regardless. Restore only warns (NU1608), and it builds — but fails at runtime
|
||||||
|
with `MissingMethodException: AbstractionsStrings.ArgumentIsEmpty` the moment EF tooling touches
|
||||||
|
a DbContext: Pomelo's compiled assembly calls an internal EF Core 9 helper that no longer exists
|
||||||
|
in the 10.0.9 assembly actually loaded.
|
||||||
|
2. **MySql.EntityFrameworkCore 10.0.7** (Oracle's official provider) — its net10.0 dependency group
|
||||||
|
targets EF Core 10.0.7, compatible with 10.0.9. Builds and migrates cleanly, but
|
||||||
|
`dotnet ef database update` against the real MariaDB throws
|
||||||
|
`InvalidCastException: Unable to cast object of type 'System.DBNull' to type 'System.Int64'` in
|
||||||
|
`MySQLHistoryRepository.AcquireDatabaseLock()` — a confirmed MariaDB-incompatibility bug (MariaDB's
|
||||||
|
`GET_LOCK()` apparently returns `NULL` in a case Oracle's code doesn't handle, and Oracle's
|
||||||
|
provider is tested against real MySQL Server, not MariaDB). This isn't limited to CLI tooling —
|
||||||
|
the same code path runs on every application startup via `MigrateCoreDatabase()`.
|
||||||
|
|
||||||
|
**Working solution**: kept Oracle's `MySql.EntityFrameworkCore` 10.0.7 (otherwise fully compatible)
|
||||||
|
and added `NonLockingMySQLHistoryRepository` (`SlpModularCms.Core/Hosting/`), wired in via
|
||||||
|
`options.ReplaceService<IHistoryRepository, NonLockingMySQLHistoryRepository>()` on all three
|
||||||
|
`AddDbContext` registrations. Oracle's internal `MySQLHistoryRepository` class can't be subclassed
|
||||||
|
(it's `internal`, only its constructor is public), so the workaround constructs a real instance of
|
||||||
|
it via reflection and forwards every `IHistoryRepository` member to it **except**
|
||||||
|
`AcquireDatabaseLock`/`AcquireDatabaseLockAsync`, which return a no-op lock instead of ever reaching
|
||||||
|
the broken `GET_LOCK` call. Accepted as safe because this deployment model never runs migrations
|
||||||
|
from more than one place at a time (`MigrateCoreDatabase()` at startup, one deploy at a time via the
|
||||||
|
atomic-release sequence) — a genuinely concurrent multi-instance migration race is not a scenario
|
||||||
|
this architecture produces.
|
||||||
|
|
||||||
|
**Verified end to end**: all three migrations applied successfully to the user's real local
|
||||||
|
MariaDB (`dotnet ef database update`, all expected tables present including `DataProtectionKeys`
|
||||||
|
and the renamed Identity tables); both `SlpModularCms.Api` and `SlpModularCms.Api.Slave` start
|
||||||
|
cleanly against it (`/health` → 200, `MigrateCoreDatabase()` logs "already up to date" on the
|
||||||
|
second run); full backend suite re-confirmed at 372/372 passed, 0 build errors.
|
||||||
|
|
||||||
## Scope Decisions (from feature-selection.md)
|
## Scope Decisions (from feature-selection.md)
|
||||||
- **Public website**: documentation/instructions only — where the website build lands in `wwwroot/`, how it coexists with `wwwroot/admin/`, and what a per-website workspace must deliver. The website's own build/deploy workflow stays out of scope (Q4 = A).
|
- **Public website**: documentation/instructions only — where the website build lands in `wwwroot/`, how it coexists with `wwwroot/admin/`, and what a per-website workspace must deliver. The website's own build/deploy workflow stays out of scope (Q4 = A).
|
||||||
- **Environments**: local, test, production only.
|
- **Environments**: local, test, production only.
|
||||||
|
|||||||
@@ -1345,3 +1345,14 @@ by Infrastructure Design. U5 carries REF-U3-01's Umami origin gate plus FR-21 an
|
|||||||
**Context**: OPERATIONS — Deployment Setup, configuration guidance clarified before final approval
|
**Context**: OPERATIONS — Deployment Setup, configuration guidance clarified before final approval
|
||||||
|
|
||||||
---
|
---
|
||||||
|
## Database Provider Migration — SQL Server to MariaDB
|
||||||
|
|
||||||
|
**Timestamp**: 2026-07-29T00:00:00Z
|
||||||
|
|
||||||
|
**User Input**: "Op de Pi draait op dit moment alleen MariaDB en geen mssql. Maakt dat uit?" ... "Nee, geen andere machine, maar kan het misschien met een podman container geregeld worden? Die draait wel op die machine" ... "De beoogde productieomgeving zal ook MariaDB hebben (mijnhostingpartner.nl) en de websites zullen niet mega groot worden dus ik denk dat voor performance MAriaDB ook prima is. Laten we optie 1 doen met MariaDB. Ik heb de lokale connection string aangepast. Die zou moeten werken. Dus als het lukt mag je meteen de migraties mogen runnen als dat nodig is" ... "In deze pull request: https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql/pull/2017 [...] Als je dat kan controleren dan zouden we door kunnen" ... "Ja, probeer die override"
|
||||||
|
|
||||||
|
**AI Response**: "Identified that SQL Server has no ARM64 build and Azure SQL Edge (the former ARM path) is retired, explained the tradeoffs (remote SQL Server, QEMU emulation, or switching to MariaDB), user chose MariaDB. Swapped Microsoft.EntityFrameworkCore.SqlServer for MySql.EntityFrameworkCore across Core.csproj and the 3 UseSqlServer call sites, regenerated all migrations, updated connection strings and README/deployment docs. Tried Pomelo per the user's PR link — confirmed it restores/builds against EF Core 10.0.9 (matching the maintainer's claim) but fails at runtime with a MissingMethodException, since this project's Identity/DataProtection EF Core integration packages force EF Core 10 packages regardless of Pomelo's own 9.x dependency range. Reverted to Oracle's provider, which then surfaced a second, independent bug: AcquireDatabaseLock() throws InvalidCastException against real MariaDB (GET_LOCK() returns NULL where Oracle's code expects an integer). Implemented NonLockingMySQLHistoryRepository as a targeted workaround (constructs Oracle's internal history repository via reflection, forwards everything except the two lock methods). Verified end to end: all 3 migrations applied to the user's real local MariaDB, both hosts (Api and Api.Slave) start cleanly against it, full 372-test backend suite still green. Corrected ASM-04 in requirements.md and recorded the full saga in aidlc-state.md."
|
||||||
|
|
||||||
|
**Context**: OPERATIONS — Deployment Setup revealed a genuine Construction-phase technology gap; resolved with application code changes (not just documentation), verified against a real database
|
||||||
|
|
||||||
|
---
|
||||||
|
|||||||
+1
-1
@@ -331,7 +331,7 @@ DEV-01…04 are **pre-existing or cost-driven** and none is introduced by this f
|
|||||||
| ASM-01 | With the atomic release switch (FR-06), `wwwroot/web/` must live **outside** the swapped release directory and be linked into it (e.g. a symlink to a persistent path on the host). | Otherwise switching releases silently discards the customer's website — precisely the failure mode D-06 was chosen to prevent. This follows necessarily from combining Q4 = C with CQ3 = C, so it is stated rather than asked. | Raise it and the deploy design changes materially; flag before Construction if this is not acceptable. |
|
| ASM-01 | With the atomic release switch (FR-06), `wwwroot/web/` must live **outside** the swapped release directory and be linked into it (e.g. a symlink to a persistent path on the host). | Otherwise switching releases silently discards the customer's website — precisely the failure mode D-06 was chosen to prevent. This follows necessarily from combining Q4 = C with CQ3 = C, so it is stated rather than asked. | Raise it and the deploy design changes materially; flag before Construction if this is not acceptable. |
|
||||||
| ASM-02 | **No `wwwroot` folder is needed for the API.** The API is not static content — its assemblies live in the application root and it serves `/api/v1` through routing. The option is kept open but nothing is built for it. | Avoids building an unused folder. | If something static under an API path is intended, say so and FR-07 gains a third mount. |
|
| ASM-02 | **No `wwwroot` folder is needed for the API.** The API is not static content — its assemblies live in the application root and it serves `/api/v1` through routing. The option is kept open but nothing is built for it. | Avoids building an unused folder. | If something static under an API path is intended, say so and FR-07 gains a third mount. |
|
||||||
| ASM-03 | The Pi already runs, or can run, a .NET 10 runtime, and the app is managed by a process manager (systemd) that the deploy can restart over SSH. | The atomic switch requires restarting the process. | Restart mechanism changes; deploy step is rewritten. |
|
| ASM-03 | The Pi already runs, or can run, a .NET 10 runtime, and the app is managed by a process manager (systemd) that the deploy can restart over SSH. | The atomic switch requires restarting the process. | Restart mechanism changes; deploy step is rewritten. |
|
||||||
| ASM-04 | The Pi's SQL Server database is reachable from the application, and a backup can be taken before a production deploy. | FR-20 depends on it. | FR-20 becomes a documented manual precondition only. |
|
| ASM-04 | ~~The Pi's SQL Server database is reachable from the application~~, and a backup can be taken before a production deploy. | FR-20 depends on it. | **Wrong — corrected at Deployment Setup, 2026-07-29**: SQL Server has no ARM64 build at all, and the Pi only runs MariaDB. The EF Core provider was migrated from `Microsoft.EntityFrameworkCore.SqlServer` to `MySql.EntityFrameworkCore` (Oracle's official MySQL/MariaDB provider), all migrations regenerated, connection strings and the backup script (`mariadb-dump`, not `sqlcmd`) updated accordingly. See `aidlc-state.md` § Operations for the full record, including a confirmed MariaDB-compatibility bug in Oracle's provider (`AcquireDatabaseLock`) and its workaround (`NonLockingMySQLHistoryRepository`). |
|
||||||
| ASM-05 | The existing Umami instance at `analytics.slpsoftware.nl` remains available and its script origin can be added to the CSP. | FR-16, FR-18. | Umami setup gains host work, as in the reference project. |
|
| ASM-05 | The existing Umami instance at `analytics.slpsoftware.nl` remains available and its script origin can be added to the CSP. | FR-16, FR-18. | Umami setup gains host work, as in the reference project. |
|
||||||
| ASM-06 | One Sentry project with environment tags is acceptable for both backend and frontend events of this CMS. | D-19. | Split into more projects; only configuration changes. |
|
| ASM-06 | One Sentry project with environment tags is acceptable for both backend and frontend events of this CMS. | D-19. | Split into more projects; only configuration changes. |
|
||||||
| ASM-07 | Existing Gitea secrets for the Pi (`PI_MAIN_*` in the reference project) can be reused or replicated for this repository. | FR-02. | New secrets are created; documented in FR-23. |
|
| ASM-07 | Existing Gitea secrets for the Pi (`PI_MAIN_*` in the reference project) can be reused or replicated for this repository. | FR-02. | New secrets are created; documented in FR-23. |
|
||||||
|
|||||||
+32
-18
@@ -20,8 +20,9 @@ assumes already exists — `deploy-scp.yaml` (U6) never creates any of it.
|
|||||||
### 1.1 Prerequisites
|
### 1.1 Prerequisites
|
||||||
- .NET 10 runtime installed on the Pi (ASM-03) — the publish is framework-dependent
|
- .NET 10 runtime installed on the Pi (ASM-03) — the publish is framework-dependent
|
||||||
(`infrastructure-design.md` § 1), so the Pi needs the runtime, not the full SDK
|
(`infrastructure-design.md` § 1), so the Pi needs the runtime, not the full SDK
|
||||||
- `sqlcmd` installed, for the backup script (§ 4) — e.g. `mssql-tools18` / `unixodbc` on Debian-based
|
- `mariadb-client` (or `mariadb-dump`/`mysqldump` specifically) installed, for the backup script (§ 4)
|
||||||
Raspberry Pi OS
|
— already present on most Raspberry Pi OS images that also run `mariadb-server`; install
|
||||||
|
`mariadb-client` explicitly if the dump tool isn't already there
|
||||||
|
|
||||||
### 1.2 Account Model (revised — `webadmin` is not the deploy account)
|
### 1.2 Account Model (revised — `webadmin` is not the deploy account)
|
||||||
|
|
||||||
@@ -106,7 +107,7 @@ below):
|
|||||||
```ini
|
```ini
|
||||||
ASPNETCORE_ENVIRONMENT=Production
|
ASPNETCORE_ENVIRONMENT=Production
|
||||||
ASPNETCORE_URLS=http://localhost:<port>
|
ASPNETCORE_URLS=http://localhost:<port>
|
||||||
ConnectionStrings__DefaultConnection=Server=127.0.0.1,1433;User ID=<user>;Password=<password>;Database=SlpSoftware<Env>;TrustServerCertificate=True
|
ConnectionStrings__DefaultConnection=Server=127.0.0.1;Port=3306;Database=SlpSoftware<Env>;Uid=<user>;Pwd=<password>
|
||||||
JwtSettings__Secret=<secure-long-random-secret>
|
JwtSettings__Secret=<secure-long-random-secret>
|
||||||
JwtSettings__Issuer=SlpModularCms
|
JwtSettings__Issuer=SlpModularCms
|
||||||
JwtSettings__Audience=SlpModularCmsPortal
|
JwtSettings__Audience=SlpModularCmsPortal
|
||||||
@@ -213,14 +214,15 @@ touch ~/.config/slpsoftware-db-backup.env
|
|||||||
chmod 600 ~/.config/slpsoftware-db-backup.env
|
chmod 600 ~/.config/slpsoftware-db-backup.env
|
||||||
```
|
```
|
||||||
```ini
|
```ini
|
||||||
DB_SERVER=127.0.0.1,1433
|
DB_HOST=127.0.0.1
|
||||||
|
DB_PORT=3306
|
||||||
DB_NAME=SlpSoftwareProduction
|
DB_NAME=SlpSoftwareProduction
|
||||||
DB_USER=<a-login-with-backup-database-permission>
|
DB_USER=<a-login-with-just-SELECT-LOCK-TABLES-permission>
|
||||||
DB_PASSWORD=<password>
|
DB_PASSWORD=<password>
|
||||||
```
|
```
|
||||||
Kept **separate** from `shared/env` (§ 1.5) deliberately — the backup script needs its own
|
Kept **separate** from `shared/env` (§ 1.5) deliberately — the backup script needs its own
|
||||||
credential, ideally scoped to just `BACKUP DATABASE` permission rather than the application's own
|
credential, ideally scoped to just read access (`SELECT`, `LOCK TABLES` — everything `mariadb-dump`
|
||||||
data-access login.
|
needs) rather than the application's own data-access login.
|
||||||
|
|
||||||
### 1.9 Gitea Actions Variables and Secrets
|
### 1.9 Gitea Actions Variables and Secrets
|
||||||
Set once, in this repository's Gitea Actions settings. This is exactly where the real path lives —
|
Set once, in this repository's Gitea Actions settings. This is exactly where the real path lives —
|
||||||
@@ -286,22 +288,29 @@ if [[ ! -f "$CREDENTIALS_FILE" ]]; then
|
|||||||
fi
|
fi
|
||||||
# shellcheck source=/dev/null
|
# shellcheck source=/dev/null
|
||||||
source "$CREDENTIALS_FILE"
|
source "$CREDENTIALS_FILE"
|
||||||
: "${DB_SERVER:?}" "${DB_NAME:?}" "${DB_USER:?}" "${DB_PASSWORD:?}"
|
: "${DB_HOST:?}" "${DB_PORT:?}" "${DB_NAME:?}" "${DB_USER:?}" "${DB_PASSWORD:?}"
|
||||||
|
|
||||||
BACKUP_DIR="$HOME/backups/slpsoftware/${ENVIRONMENT}"
|
BACKUP_DIR="$HOME/backups/slpsoftware/${ENVIRONMENT}"
|
||||||
mkdir -p "$BACKUP_DIR"
|
mkdir -p "$BACKUP_DIR"
|
||||||
TIMESTAMP=$(date -u +%Y%m%d%H%M%S)
|
TIMESTAMP=$(date -u +%Y%m%d%H%M%S)
|
||||||
BACKUP_FILE="$BACKUP_DIR/${DB_NAME}-${TIMESTAMP}.bak"
|
BACKUP_FILE="$BACKUP_DIR/${DB_NAME}-${TIMESTAMP}.sql.gz"
|
||||||
|
|
||||||
sqlcmd -S "$DB_SERVER" -U "$DB_USER" -P "$DB_PASSWORD" -C -Q \
|
# --single-transaction: consistent snapshot without locking the tables for the whole dump duration
|
||||||
"BACKUP DATABASE [$DB_NAME] TO DISK = N'$BACKUP_FILE' WITH INIT, COMPRESSION"
|
# (InnoDB only — every table here is, since that's EF Core's MySQL-provider default).
|
||||||
|
mariadb-dump \
|
||||||
|
-h "$DB_HOST" -P "$DB_PORT" -u "$DB_USER" -p"$DB_PASSWORD" \
|
||||||
|
--single-transaction --routines --triggers \
|
||||||
|
"$DB_NAME" | gzip > "$BACKUP_FILE"
|
||||||
|
|
||||||
echo "Backup written to $BACKUP_FILE"
|
echo "Backup written to $BACKUP_FILE"
|
||||||
|
|
||||||
# Retention: keep the 7 most recent backups for this environment
|
# Retention: keep the 7 most recent backups for this environment
|
||||||
ls -1t "$BACKUP_DIR"/*.bak 2>/dev/null | tail -n +8 | xargs -r rm -f
|
ls -1t "$BACKUP_DIR"/*.sql.gz 2>/dev/null | tail -n +8 | xargs -r rm -f
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`mariadb-dump` is MariaDB's own name for the tool (present since MariaDB 10.4-ish); if the host only
|
||||||
|
has the older `mysqldump` name, substitute it — same tool, same flags.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
chmod +x ~/scripts/backup-slpmodularcms-db.sh
|
chmod +x ~/scripts/backup-slpmodularcms-db.sh
|
||||||
```
|
```
|
||||||
@@ -310,9 +319,13 @@ chmod +x ~/scripts/backup-slpmodularcms-db.sh
|
|||||||
```bash
|
```bash
|
||||||
~/scripts/backup-slpmodularcms-db.sh production
|
~/scripts/backup-slpmodularcms-db.sh production
|
||||||
```
|
```
|
||||||
Confirm a `.bak` file appears under `~/backups/slpsoftware/production/` and that `sqlcmd` didn't
|
Confirm a `.sql.gz` file appears under `~/backups/slpsoftware/production/` and that the dump didn't
|
||||||
silently fail (the script uses `set -euo pipefail`, so a real SQL error does propagate as a non-zero
|
silently fail (the script uses `set -euo pipefail`, so a real error does propagate as a non-zero
|
||||||
exit — which fails the calling `deploy-scp.yaml` step, correctly blocking the deploy).
|
exit — which fails the calling `deploy-scp.yaml` step, correctly blocking the deploy). Worth a
|
||||||
|
one-time restore rehearsal too — an untested backup is not a verified one:
|
||||||
|
```bash
|
||||||
|
gunzip -c ~/backups/slpsoftware/production/<file>.sql.gz | mariadb -h 127.0.0.1 -u root -p <a-scratch-database>
|
||||||
|
```
|
||||||
|
|
||||||
## 5. Future: Switching Production to FTPS (Shared Hosting)
|
## 5. Future: Switching Production to FTPS (Shared Hosting)
|
||||||
|
|
||||||
@@ -336,9 +349,10 @@ than the transport:
|
|||||||
`wwwroot/web/` persistence (FR-08, ASM-01) would need a **different** mechanism on such a host —
|
`wwwroot/web/` persistence (FR-08, ASM-01) would need a **different** mechanism on such a host —
|
||||||
e.g. never touching a specific subfolder during upload, rather than linking a persistent directory
|
e.g. never touching a specific subfolder during upload, rather than linking a persistent directory
|
||||||
outside a swapped release tree, since "outside the release tree" may not be an available concept
|
outside a swapped release tree, since "outside the release tree" may not be an available concept
|
||||||
- **Database backup** — shared hosting frequently does not expose direct `sqlcmd`/SSH access at all;
|
- **Database backup** — shared hosting frequently does not expose direct `mariadb-dump`/SSH access
|
||||||
the backup step in `deploy-scp.yaml` (§ 4 script) would need to become either a provider-specific
|
at all; the backup step in `deploy-scp.yaml` (§ 4 script) would need to become either a
|
||||||
API call or a documented manual pre-production step (the FR-20 fallback U6 already designed for)
|
provider-specific API call (e.g. a hosting-panel database backup feature) or a documented manual
|
||||||
|
pre-production step (the FR-20 fallback U6 already designed for)
|
||||||
|
|
||||||
### 5.3 What building `deploy-ftps.yaml` would actually require
|
### 5.3 What building `deploy-ftps.yaml` would actually require
|
||||||
1. A new reusable workflow implementing the **same five required inputs**
|
1. A new reusable workflow implementing the **same five required inputs**
|
||||||
|
|||||||
+1
-2
@@ -46,8 +46,7 @@ A backup is taken before every **production** deploy (`operations/deployment/dep
|
|||||||
§ 4, invoked by `deploy-scp.yaml` when `run_db_backup: true`). To restore:
|
§ 4, invoked by `deploy-scp.yaml` when `run_db_backup: true`). To restore:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sqlcmd -S <server> -U <user> -P <password> -C -Q \
|
gunzip -c <path-to-backup>.sql.gz | mariadb -h <server> -u <user> -p SlpSoftwareProduction
|
||||||
"RESTORE DATABASE [SlpModularCmsProduction] FROM DISK = N'<path-to-backup>.bak' WITH REPLACE"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Restoring a database backup and rolling back the application release are **independent actions** —
|
Restoring a database backup and rolling back the application release are **independent actions** —
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=SlpModularCmsSlave;Trusted_Connection=True;MultipleActiveResultSets=true"
|
"DefaultConnection": "Server=127.0.0.1;Port=3306;Database=SlpModularCmsSlave;Uid=root;Pwd=<your-local-mariadb-password>"
|
||||||
},
|
},
|
||||||
"JwtSettings": {
|
"JwtSettings": {
|
||||||
"Secret": "SuperSecretKeyForDevelopmentOnly_MustBeLongerThan32Bytes!",
|
"Secret": "SuperSecretKeyForDevelopmentOnly_MustBeLongerThan32Bytes!",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"DefaultConnection": "Server=127.0.0.1,1433;User ID=sa;Password=<your-local-sql-password>;Database=SlpModularCmsSlave;TrustServerCertificate=True;MultipleActiveResultSets=true"
|
"DefaultConnection": "Server=127.0.0.1;Port=3306;Uid=root;Pwd=<your-local-mariadb-password>;Database=SlpModularCmsSlave"
|
||||||
},
|
},
|
||||||
"JwtSettings": {
|
"JwtSettings": {
|
||||||
"Secret": "<your-local-secret-key-min-32-bytes>",
|
"Secret": "<your-local-secret-key-min-32-bytes>",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=SlpModularCms;Trusted_Connection=True;MultipleActiveResultSets=true"
|
"DefaultConnection": "Server=127.0.0.1;Port=3306;Database=SlpModularCms;Uid=root;Pwd=<your-local-mariadb-password>"
|
||||||
},
|
},
|
||||||
"JwtSettings": {
|
"JwtSettings": {
|
||||||
"Secret": "SuperSecretKeyForDevelopmentOnly_MustBeLongerThan32Bytes!",
|
"Secret": "SuperSecretKeyForDevelopmentOnly_MustBeLongerThan32Bytes!",
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
},
|
},
|
||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*",
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"DefaultConnection": "Server=<production-db-host>;Database=SlpModularCms;User Id=<db-user>;Password=<db-password>;TrustServerCertificate=True"
|
"DefaultConnection": "Server=<production-db-host>;Port=3306;Database=SlpModularCms;Uid=<db-user>;Pwd=<db-password>"
|
||||||
},
|
},
|
||||||
"JwtSettings": {
|
"JwtSettings": {
|
||||||
"Secret": "<secure-long-random-secret-key-from-env>",
|
"Secret": "<secure-long-random-secret-key-from-env>",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Microsoft.Data.SqlClient;
|
using MySql.Data.MySqlClient;
|
||||||
using SlpModularCms.Core.Hosting;
|
using SlpModularCms.Core.Hosting;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
@@ -47,9 +47,9 @@ public class DatabaseMigrationExtensionsTests
|
|||||||
|
|
||||||
public static TheoryData<Exception> TransientFailures() =>
|
public static TheoryData<Exception> TransientFailures() =>
|
||||||
[
|
[
|
||||||
MakeSqlException(),
|
MakeMySqlException(),
|
||||||
new TimeoutException("Connect Timeout expired."),
|
new TimeoutException("Connect Timeout expired."),
|
||||||
new InvalidOperationException("wrapper", MakeSqlException()),
|
new InvalidOperationException("wrapper", MakeMySqlException()),
|
||||||
];
|
];
|
||||||
|
|
||||||
public static TheoryData<Exception> NonTransientFailures() =>
|
public static TheoryData<Exception> NonTransientFailures() =>
|
||||||
@@ -71,18 +71,18 @@ public class DatabaseMigrationExtensionsTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <see cref="SqlException"/> has no public constructor, so one is produced through the
|
/// <see cref="MySqlException"/> has no public constructor, so one is produced through the
|
||||||
/// framework's own factory path via reflection.
|
/// framework's own factory path via reflection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static Exception MakeSqlException()
|
private static Exception MakeMySqlException()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Deliberately unreachable host and a very short timeout: this genuinely produces a
|
// Deliberately unreachable host and a very short timeout: this genuinely produces a
|
||||||
// SqlException rather than a hand-built stand-in, so the classifier is tested against
|
// MySqlException rather than a hand-built stand-in, so the classifier is tested against
|
||||||
// the real type it will encounter in production.
|
// the real type it will encounter in production.
|
||||||
using var connection = new SqlConnection(
|
using var connection = new MySqlConnection(
|
||||||
"Server=localhost,9;Database=none;User Id=sa;Password=none;Connect Timeout=1;TrustServerCertificate=True");
|
"Server=localhost;Port=9;Database=none;Uid=none;Pwd=none;Connection Timeout=1");
|
||||||
connection.Open();
|
connection.Open();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.Data.SqlClient;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using MySql.Data.MySqlClient;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Sentry;
|
using Sentry;
|
||||||
@@ -108,7 +108,7 @@ public static class DatabaseMigrationExtensions
|
|||||||
{
|
{
|
||||||
for (var current = exception; current is not null; current = current.InnerException)
|
for (var current = exception; current is not null; current = current.InnerException)
|
||||||
{
|
{
|
||||||
if (current is SqlException or TimeoutException)
|
if (current is MySqlException or TimeoutException)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace SlpModularCms.Core.Hosting;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Works around a confirmed bug in Oracle's <c>MySql.EntityFrameworkCore</c> provider (10.0.7)
|
||||||
|
/// against MariaDB: its <c>AcquireDatabaseLock</c> issues MariaDB's <c>GET_LOCK()</c> and casts
|
||||||
|
/// the result straight to <see cref="long"/>, but MariaDB returns <c>NULL</c> in a case real MySQL
|
||||||
|
/// Server apparently doesn't — producing an unconditional <see cref="InvalidCastException"/> that
|
||||||
|
/// blocks every migration attempt, reproduced against a real MariaDB instance during Operations.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Oracle's own <c>MySQLHistoryRepository</c> is an internal type, so it cannot be subclassed
|
||||||
|
/// directly to override just the lock methods. This instead constructs a real instance of it via
|
||||||
|
/// reflection (its constructor is public even though the class itself is not) and forwards every
|
||||||
|
/// <see cref="IHistoryRepository"/> member to that instance, except the two lock methods — which
|
||||||
|
/// never reach the broken call at all.
|
||||||
|
///
|
||||||
|
/// Skipping the lock is acceptable here because migrations only ever run from one place at a
|
||||||
|
/// time: <c>MigrateCoreDatabase()</c> at startup, driven by the atomic-release deploy sequence,
|
||||||
|
/// which never runs two deploys concurrently against the same environment. A genuinely concurrent
|
||||||
|
/// multi-instance migration race is not a scenario this deployment model produces.
|
||||||
|
/// </remarks>
|
||||||
|
public sealed class NonLockingMySQLHistoryRepository : IHistoryRepository
|
||||||
|
{
|
||||||
|
private const string InnerTypeName = "MySql.EntityFrameworkCore.Migrations.Internal.MySQLHistoryRepository";
|
||||||
|
|
||||||
|
private readonly IHistoryRepository _inner;
|
||||||
|
|
||||||
|
public NonLockingMySQLHistoryRepository(HistoryRepositoryDependencies dependencies)
|
||||||
|
{
|
||||||
|
var innerType = typeof(MySQLDbContextOptionsExtensions).Assembly.GetType(InnerTypeName)
|
||||||
|
?? throw new InvalidOperationException(
|
||||||
|
$"{InnerTypeName} was not found. MySql.EntityFrameworkCore may have changed its internal " +
|
||||||
|
"layout — this workaround needs re-verifying against the new version.");
|
||||||
|
|
||||||
|
_inner = (IHistoryRepository)Activator.CreateInstance(innerType, dependencies)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Exists() => _inner.Exists();
|
||||||
|
|
||||||
|
public Task<bool> ExistsAsync(CancellationToken cancellationToken = default) =>
|
||||||
|
_inner.ExistsAsync(cancellationToken);
|
||||||
|
|
||||||
|
public void Create() => _inner.Create();
|
||||||
|
|
||||||
|
public Task CreateAsync(CancellationToken cancellationToken = default) =>
|
||||||
|
_inner.CreateAsync(cancellationToken);
|
||||||
|
|
||||||
|
public bool CreateIfNotExists() => _inner.CreateIfNotExists();
|
||||||
|
|
||||||
|
public Task<bool> CreateIfNotExistsAsync(CancellationToken cancellationToken = default) =>
|
||||||
|
_inner.CreateIfNotExistsAsync(cancellationToken);
|
||||||
|
|
||||||
|
public IReadOnlyList<HistoryRow> GetAppliedMigrations() => _inner.GetAppliedMigrations();
|
||||||
|
|
||||||
|
public Task<IReadOnlyList<HistoryRow>> GetAppliedMigrationsAsync(CancellationToken cancellationToken = default) =>
|
||||||
|
_inner.GetAppliedMigrationsAsync(cancellationToken);
|
||||||
|
|
||||||
|
public LockReleaseBehavior LockReleaseBehavior => _inner.LockReleaseBehavior;
|
||||||
|
|
||||||
|
public string GetCreateScript() => _inner.GetCreateScript();
|
||||||
|
|
||||||
|
public string GetCreateIfNotExistsScript() => _inner.GetCreateIfNotExistsScript();
|
||||||
|
|
||||||
|
public string GetInsertScript(HistoryRow row) => _inner.GetInsertScript(row);
|
||||||
|
|
||||||
|
public string GetDeleteScript(string migrationId) => _inner.GetDeleteScript(migrationId);
|
||||||
|
|
||||||
|
public string GetBeginIfNotExistsScript(string migrationId) => _inner.GetBeginIfNotExistsScript(migrationId);
|
||||||
|
|
||||||
|
public string GetBeginIfExistsScript(string migrationId) => _inner.GetBeginIfExistsScript(migrationId);
|
||||||
|
|
||||||
|
public string GetEndIfScript() => _inner.GetEndIfScript();
|
||||||
|
|
||||||
|
// The actual workaround: never call into the inner repository's broken GET_LOCK path.
|
||||||
|
public IMigrationsDatabaseLock AcquireDatabaseLock() => new NoOpMigrationsDatabaseLock(this);
|
||||||
|
|
||||||
|
public Task<IMigrationsDatabaseLock> AcquireDatabaseLockAsync(CancellationToken cancellationToken = default) =>
|
||||||
|
Task.FromResult<IMigrationsDatabaseLock>(new NoOpMigrationsDatabaseLock(this));
|
||||||
|
|
||||||
|
private sealed class NoOpMigrationsDatabaseLock(IHistoryRepository historyRepository) : IMigrationsDatabaseLock
|
||||||
|
{
|
||||||
|
public IHistoryRepository HistoryRepository { get; } = historyRepository;
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueTask DisposeAsync() => ValueTask.CompletedTask;
|
||||||
|
|
||||||
|
public IMigrationsDatabaseLock ReacquireIfNeeded(bool connectionOpened, bool? recreateIfInvalid) => this;
|
||||||
|
|
||||||
|
public Task<IMigrationsDatabaseLock> ReacquireIfNeededAsync(
|
||||||
|
bool connectionOpened, bool? recreateIfInvalid, CancellationToken cancellationToken = default) =>
|
||||||
|
Task.FromResult<IMigrationsDatabaseLock>(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Http;
|
|||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.RateLimiting;
|
using Microsoft.AspNetCore.RateLimiting;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
@@ -33,7 +34,10 @@ public static class ServiceCollectionExtensions
|
|||||||
{
|
{
|
||||||
// 1. Database
|
// 1. Database
|
||||||
services.AddDbContext<ApplicationDbContext>(options =>
|
services.AddDbContext<ApplicationDbContext>(options =>
|
||||||
options.UseSqlServer(configuration.GetConnectionString("DefaultConnection")));
|
{
|
||||||
|
options.UseMySQL(configuration.GetConnectionString("DefaultConnection")!);
|
||||||
|
options.ReplaceService<IHistoryRepository, NonLockingMySQLHistoryRepository>();
|
||||||
|
});
|
||||||
|
|
||||||
// 2. Identity
|
// 2. Identity
|
||||||
services.AddIdentityCore<ApplicationUser>(options =>
|
services.AddIdentityCore<ApplicationUser>(options =>
|
||||||
|
|||||||
-433
@@ -1,433 +0,0 @@
|
|||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
using SlpModularCms.Core.Data;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace SlpModularCms.Core.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(ApplicationDbContext))]
|
|
||||||
[Migration("20260619130625_AddsDisplayName")]
|
|
||||||
partial class AddsDisplayName
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "10.0.9")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<Guid>("RoleId")
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("RoleClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<Guid>("UserId")
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("UserClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderKey")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderDisplayName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<Guid>("UserId")
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.HasKey("LoginProvider", "ProviderKey");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("UserLogins", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("UserId")
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.Property<Guid>("RoleId")
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "RoleId");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("UserRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("UserId")
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("Value")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "LoginProvider", "Name");
|
|
||||||
|
|
||||||
b.ToTable("UserTokens", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.ApplicationRole", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("RoleNameIndex")
|
|
||||||
.HasFilter("[NormalizedName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("Roles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.ApplicationUser", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.Property<int>("AccessFailedCount")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("CreatedAt")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("DisplayName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Email")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<bool>("EmailConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("LockoutEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedEmail")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedUserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("PasswordHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("PhoneNumber")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("PhoneNumberConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SecurityStamp")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TwoFactorEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("UserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedEmail")
|
|
||||||
.HasDatabaseName("EmailIndex");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedUserName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("UserNameIndex")
|
|
||||||
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("Users", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.GlobalAvailabilityState", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("LastUpdatedAt")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("Message")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("Status")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("UpdatedBy")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("AvailabilityState", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.Invitation", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("CreatedAt")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("Email")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("ExpiryDate")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<bool>("IsAccepted")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Role")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Token")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("Token")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("Invitations");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.ModulePermission", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("UserId")
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.Property<string>("ModuleName")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Permission")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "ModuleName", "Permission");
|
|
||||||
|
|
||||||
b.ToTable("ModulePermissions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.RefreshToken", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("CreatedAt")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("CreatedByIp")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("ExpiryDate")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<bool>("IsRevoked")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsUsed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Token")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<Guid>("UserId")
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("Token")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("RefreshTokens");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("SlpModularCms.Core.Identity.Entities.ApplicationRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("SlpModularCms.Core.Identity.Entities.ApplicationUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("SlpModularCms.Core.Identity.Entities.ApplicationUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("SlpModularCms.Core.Identity.Entities.ApplicationRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("SlpModularCms.Core.Identity.Entities.ApplicationUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("SlpModularCms.Core.Identity.Entities.ApplicationUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.ModulePermission", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("SlpModularCms.Core.Identity.Entities.ApplicationUser", "User")
|
|
||||||
.WithMany("ModulePermissions")
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.RefreshToken", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("SlpModularCms.Core.Identity.Entities.ApplicationUser", "User")
|
|
||||||
.WithMany("RefreshTokens")
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.ApplicationUser", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("ModulePermissions");
|
|
||||||
|
|
||||||
b.Navigation("RefreshTokens");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
// <auto-generated />
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace SlpModularCms.Core.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
[ExcludeFromCodeCoverage]
|
|
||||||
public partial class AddsDisplayName : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "DisplayName",
|
|
||||||
table: "Users",
|
|
||||||
type: "nvarchar(max)",
|
|
||||||
nullable: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "DisplayName",
|
|
||||||
table: "Users");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-452
@@ -1,452 +0,0 @@
|
|||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
using SlpModularCms.Core.Data;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace SlpModularCms.Core.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(ApplicationDbContext))]
|
|
||||||
[Migration("20260727203036_AddDataProtectionKeys")]
|
|
||||||
partial class AddDataProtectionKeys
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "10.0.9")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("FriendlyName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Xml")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("DataProtectionKeys");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<Guid>("RoleId")
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("RoleClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<Guid>("UserId")
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("UserClaims", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderKey")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("ProviderDisplayName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<Guid>("UserId")
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.HasKey("LoginProvider", "ProviderKey");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("UserLogins", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("UserId")
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.Property<Guid>("RoleId")
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "RoleId");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("UserRoles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("UserId")
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.Property<string>("LoginProvider")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasColumnType("nvarchar(450)");
|
|
||||||
|
|
||||||
b.Property<string>("Value")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "LoginProvider", "Name");
|
|
||||||
|
|
||||||
b.ToTable("UserTokens", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.ApplicationRole", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("RoleNameIndex")
|
|
||||||
.HasFilter("[NormalizedName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("Roles", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.ApplicationUser", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.Property<int>("AccessFailedCount")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
|
||||||
.IsConcurrencyToken()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("CreatedAt")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("DisplayName")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Email")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<bool>("EmailConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsActive")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("LockoutEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedEmail")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("NormalizedUserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<string>("PasswordHash")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("PhoneNumber")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("PhoneNumberConfirmed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("SecurityStamp")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<bool>("TwoFactorEnabled")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("UserName")
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedEmail")
|
|
||||||
.HasDatabaseName("EmailIndex");
|
|
||||||
|
|
||||||
b.HasIndex("NormalizedUserName")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("UserNameIndex")
|
|
||||||
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("Users", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.GlobalAvailabilityState", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("LastUpdatedAt")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("Message")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int>("Status")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("UpdatedBy")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("AvailabilityState", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.Invitation", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("CreatedAt")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("Email")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("ExpiryDate")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<bool>("IsAccepted")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Role")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Token")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("Token")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("Invitations");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.ModulePermission", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("UserId")
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.Property<string>("ModuleName")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.Property<string>("Permission")
|
|
||||||
.HasMaxLength(128)
|
|
||||||
.HasColumnType("nvarchar(128)");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "ModuleName", "Permission");
|
|
||||||
|
|
||||||
b.ToTable("ModulePermissions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.RefreshToken", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("CreatedAt")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("CreatedByIp")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("ExpiryDate")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<bool>("IsRevoked")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<bool>("IsUsed")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<string>("Token")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(256)
|
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<Guid>("UserId")
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("Token")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("RefreshTokens");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("SlpModularCms.Core.Identity.Entities.ApplicationRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("SlpModularCms.Core.Identity.Entities.ApplicationUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("SlpModularCms.Core.Identity.Entities.ApplicationUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("SlpModularCms.Core.Identity.Entities.ApplicationRole", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("RoleId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("SlpModularCms.Core.Identity.Entities.ApplicationUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("SlpModularCms.Core.Identity.Entities.ApplicationUser", null)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.ModulePermission", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("SlpModularCms.Core.Identity.Entities.ApplicationUser", "User")
|
|
||||||
.WithMany("ModulePermissions")
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.RefreshToken", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("SlpModularCms.Core.Identity.Entities.ApplicationUser", "User")
|
|
||||||
.WithMany("RefreshTokens")
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.ApplicationUser", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("ModulePermissions");
|
|
||||||
|
|
||||||
b.Navigation("RefreshTokens");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace SlpModularCms.Core.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class AddDataProtectionKeys : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "DataProtectionKeys",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
Id = table.Column<int>(type: "int", nullable: false)
|
|
||||||
.Annotation("SqlServer:Identity", "1, 1"),
|
|
||||||
FriendlyName = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
|
||||||
Xml = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_DataProtectionKeys", x => x.Id);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "DataProtectionKeys");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+81
-70
@@ -2,7 +2,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
using SlpModularCms.Core.Data;
|
using SlpModularCms.Core.Data;
|
||||||
@@ -12,7 +11,7 @@ using SlpModularCms.Core.Data;
|
|||||||
namespace SlpModularCms.Core.Migrations
|
namespace SlpModularCms.Core.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(ApplicationDbContext))]
|
[DbContext(typeof(ApplicationDbContext))]
|
||||||
[Migration("20260612191736_InitialCreate")]
|
[Migration("20260729095344_InitialCreate")]
|
||||||
partial class InitialCreate
|
partial class InitialCreate
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -21,9 +20,24 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "10.0.9")
|
.HasAnnotation("ProductVersion", "10.0.9")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("FriendlyName")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("Xml")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("DataProtectionKeys");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
|
||||||
{
|
{
|
||||||
@@ -31,16 +45,14 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
b.Property<string>("ClaimType")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
b.Property<string>("ClaimValue")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<Guid>("RoleId")
|
b.Property<Guid>("RoleId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
@@ -55,16 +67,14 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
b.Property<string>("ClaimType")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
b.Property<string>("ClaimValue")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<Guid>("UserId")
|
b.Property<Guid>("UserId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
@@ -76,16 +86,16 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
|
||||||
{
|
{
|
||||||
b.Property<string>("LoginProvider")
|
b.Property<string>("LoginProvider")
|
||||||
.HasColumnType("nvarchar(450)");
|
.HasColumnType("varchar(255)");
|
||||||
|
|
||||||
b.Property<string>("ProviderKey")
|
b.Property<string>("ProviderKey")
|
||||||
.HasColumnType("nvarchar(450)");
|
.HasColumnType("varchar(255)");
|
||||||
|
|
||||||
b.Property<string>("ProviderDisplayName")
|
b.Property<string>("ProviderDisplayName")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<Guid>("UserId")
|
b.Property<Guid>("UserId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.HasKey("LoginProvider", "ProviderKey");
|
b.HasKey("LoginProvider", "ProviderKey");
|
||||||
|
|
||||||
@@ -97,10 +107,10 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("UserId")
|
b.Property<Guid>("UserId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<Guid>("RoleId")
|
b.Property<Guid>("RoleId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.HasKey("UserId", "RoleId");
|
b.HasKey("UserId", "RoleId");
|
||||||
|
|
||||||
@@ -112,16 +122,16 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("UserId")
|
b.Property<Guid>("UserId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<string>("LoginProvider")
|
b.Property<string>("LoginProvider")
|
||||||
.HasColumnType("nvarchar(450)");
|
.HasColumnType("varchar(255)");
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
.HasColumnType("nvarchar(450)");
|
.HasColumnType("varchar(255)");
|
||||||
|
|
||||||
b.Property<string>("Value")
|
b.Property<string>("Value")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.HasKey("UserId", "LoginProvider", "Name");
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
@@ -132,26 +142,25 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
b.Property<string>("ConcurrencyStamp")
|
||||||
.IsConcurrencyToken()
|
.IsConcurrencyToken()
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("nvarchar(256)");
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
b.Property<string>("NormalizedName")
|
b.Property<string>("NormalizedName")
|
||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("nvarchar(256)");
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.HasIndex("NormalizedName")
|
b.HasIndex("NormalizedName")
|
||||||
.IsUnique()
|
.IsUnique()
|
||||||
.HasDatabaseName("RoleNameIndex")
|
.HasDatabaseName("RoleNameIndex");
|
||||||
.HasFilter("[NormalizedName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("Roles", (string)null);
|
b.ToTable("Roles", (string)null);
|
||||||
});
|
});
|
||||||
@@ -160,60 +169,63 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<int>("AccessFailedCount")
|
b.Property<int>("AccessFailedCount")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
b.Property<string>("ConcurrencyStamp")
|
||||||
.IsConcurrencyToken()
|
.IsConcurrencyToken()
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("CreatedAt")
|
b.Property<DateTimeOffset>("CreatedAt")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
|
b.Property<string>("DisplayName")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<string>("Email")
|
b.Property<string>("Email")
|
||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("nvarchar(256)");
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
b.Property<bool>("EmailConfirmed")
|
b.Property<bool>("EmailConfirmed")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
b.Property<bool>("IsActive")
|
b.Property<bool>("IsActive")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
b.Property<bool>("LockoutEnabled")
|
b.Property<bool>("LockoutEnabled")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<string>("NormalizedEmail")
|
b.Property<string>("NormalizedEmail")
|
||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("nvarchar(256)");
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
b.Property<string>("NormalizedUserName")
|
b.Property<string>("NormalizedUserName")
|
||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("nvarchar(256)");
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
b.Property<string>("PasswordHash")
|
b.Property<string>("PasswordHash")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<string>("PhoneNumber")
|
b.Property<string>("PhoneNumber")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<bool>("PhoneNumberConfirmed")
|
b.Property<bool>("PhoneNumberConfirmed")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
b.Property<string>("SecurityStamp")
|
b.Property<string>("SecurityStamp")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<bool>("TwoFactorEnabled")
|
b.Property<bool>("TwoFactorEnabled")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
b.Property<string>("UserName")
|
b.Property<string>("UserName")
|
||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("nvarchar(256)");
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
@@ -222,8 +234,7 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
|
|
||||||
b.HasIndex("NormalizedUserName")
|
b.HasIndex("NormalizedUserName")
|
||||||
.IsUnique()
|
.IsUnique()
|
||||||
.HasDatabaseName("UserNameIndex")
|
.HasDatabaseName("UserNameIndex");
|
||||||
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("Users", (string)null);
|
b.ToTable("Users", (string)null);
|
||||||
});
|
});
|
||||||
@@ -232,19 +243,19 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("LastUpdatedAt")
|
b.Property<DateTimeOffset>("LastUpdatedAt")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<string>("Message")
|
b.Property<string>("Message")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<int>("Status")
|
b.Property<int>("Status")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<string>("UpdatedBy")
|
b.Property<string>("UpdatedBy")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
@@ -255,30 +266,30 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("CreatedAt")
|
b.Property<DateTimeOffset>("CreatedAt")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<string>("Email")
|
b.Property<string>("Email")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("nvarchar(256)");
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("ExpiryDate")
|
b.Property<DateTimeOffset>("ExpiryDate")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<bool>("IsAccepted")
|
b.Property<bool>("IsAccepted")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
b.Property<string>("Role")
|
b.Property<string>("Role")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<string>("Token")
|
b.Property<string>("Token")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("nvarchar(256)");
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
@@ -291,15 +302,15 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.ModulePermission", b =>
|
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.ModulePermission", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("UserId")
|
b.Property<Guid>("UserId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<string>("ModuleName")
|
b.Property<string>("ModuleName")
|
||||||
.HasMaxLength(128)
|
.HasMaxLength(128)
|
||||||
.HasColumnType("nvarchar(128)");
|
.HasColumnType("varchar(128)");
|
||||||
|
|
||||||
b.Property<string>("Permission")
|
b.Property<string>("Permission")
|
||||||
.HasMaxLength(128)
|
.HasMaxLength(128)
|
||||||
.HasColumnType("nvarchar(128)");
|
.HasColumnType("varchar(128)");
|
||||||
|
|
||||||
b.HasKey("UserId", "ModuleName", "Permission");
|
b.HasKey("UserId", "ModuleName", "Permission");
|
||||||
|
|
||||||
@@ -310,30 +321,30 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("CreatedAt")
|
b.Property<DateTimeOffset>("CreatedAt")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<string>("CreatedByIp")
|
b.Property<string>("CreatedByIp")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("ExpiryDate")
|
b.Property<DateTimeOffset>("ExpiryDate")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<bool>("IsRevoked")
|
b.Property<bool>("IsRevoked")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
b.Property<bool>("IsUsed")
|
b.Property<bool>("IsUsed")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
b.Property<string>("Token")
|
b.Property<string>("Token")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("nvarchar(256)");
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
b.Property<Guid>("UserId")
|
b.Property<Guid>("UserId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
+108
-79
@@ -1,101 +1,122 @@
|
|||||||
// <auto-generated />
|
using System;
|
||||||
using System;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using MySql.EntityFrameworkCore.Metadata;
|
||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
namespace SlpModularCms.Core.Migrations
|
namespace SlpModularCms.Core.Migrations
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[ExcludeFromCodeCoverage]
|
|
||||||
public partial class InitialCreate : Migration
|
public partial class InitialCreate : Migration
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
|
migrationBuilder.AlterDatabase()
|
||||||
|
.Annotation("MySQL:Charset", "utf8mb4");
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "AvailabilityState",
|
name: "AvailabilityState",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||||
Status = table.Column<int>(type: "int", nullable: false),
|
Status = table.Column<int>(type: "int", nullable: false),
|
||||||
Message = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
Message = table.Column<string>(type: "longtext", nullable: true),
|
||||||
LastUpdatedAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false),
|
LastUpdatedAt = table.Column<DateTimeOffset>(type: "datetime", nullable: false),
|
||||||
UpdatedBy = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
UpdatedBy = table.Column<string>(type: "longtext", nullable: true)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
table.PrimaryKey("PK_AvailabilityState", x => x.Id);
|
table.PrimaryKey("PK_AvailabilityState", x => x.Id);
|
||||||
});
|
})
|
||||||
|
.Annotation("MySQL:Charset", "utf8mb4");
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "DataProtectionKeys",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "int", nullable: false)
|
||||||
|
.Annotation("MySQL:ValueGenerationStrategy", MySQLValueGenerationStrategy.IdentityColumn),
|
||||||
|
FriendlyName = table.Column<string>(type: "longtext", nullable: true),
|
||||||
|
Xml = table.Column<string>(type: "longtext", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_DataProtectionKeys", x => x.Id);
|
||||||
|
})
|
||||||
|
.Annotation("MySQL:Charset", "utf8mb4");
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "Invitations",
|
name: "Invitations",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||||
Email = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
|
Email = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: false),
|
||||||
Role = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
Role = table.Column<string>(type: "longtext", nullable: false),
|
||||||
Token = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
|
Token = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: false),
|
||||||
ExpiryDate = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false),
|
ExpiryDate = table.Column<DateTimeOffset>(type: "datetime", nullable: false),
|
||||||
IsAccepted = table.Column<bool>(type: "bit", nullable: false),
|
IsAccepted = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||||
CreatedAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false)
|
CreatedAt = table.Column<DateTimeOffset>(type: "datetime", nullable: false)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
table.PrimaryKey("PK_Invitations", x => x.Id);
|
table.PrimaryKey("PK_Invitations", x => x.Id);
|
||||||
});
|
})
|
||||||
|
.Annotation("MySQL:Charset", "utf8mb4");
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "Roles",
|
name: "Roles",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||||
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
|
Name = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true),
|
||||||
NormalizedName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
|
NormalizedName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true),
|
||||||
ConcurrencyStamp = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
ConcurrencyStamp = table.Column<string>(type: "longtext", nullable: true)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
table.PrimaryKey("PK_Roles", x => x.Id);
|
table.PrimaryKey("PK_Roles", x => x.Id);
|
||||||
});
|
})
|
||||||
|
.Annotation("MySQL:Charset", "utf8mb4");
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "Users",
|
name: "Users",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||||
IsActive = table.Column<bool>(type: "bit", nullable: false),
|
IsActive = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||||
CreatedAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false),
|
CreatedAt = table.Column<DateTimeOffset>(type: "datetime", nullable: false),
|
||||||
UserName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
|
DisplayName = table.Column<string>(type: "longtext", nullable: true),
|
||||||
NormalizedUserName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
|
UserName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true),
|
||||||
Email = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
|
NormalizedUserName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true),
|
||||||
NormalizedEmail = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
|
Email = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true),
|
||||||
EmailConfirmed = table.Column<bool>(type: "bit", nullable: false),
|
NormalizedEmail = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true),
|
||||||
PasswordHash = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
EmailConfirmed = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||||
SecurityStamp = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
PasswordHash = table.Column<string>(type: "longtext", nullable: true),
|
||||||
ConcurrencyStamp = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
SecurityStamp = table.Column<string>(type: "longtext", nullable: true),
|
||||||
PhoneNumber = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
ConcurrencyStamp = table.Column<string>(type: "longtext", nullable: true),
|
||||||
PhoneNumberConfirmed = table.Column<bool>(type: "bit", nullable: false),
|
PhoneNumber = table.Column<string>(type: "longtext", nullable: true),
|
||||||
TwoFactorEnabled = table.Column<bool>(type: "bit", nullable: false),
|
PhoneNumberConfirmed = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||||
LockoutEnd = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: true),
|
TwoFactorEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||||
LockoutEnabled = table.Column<bool>(type: "bit", nullable: false),
|
LockoutEnd = table.Column<DateTimeOffset>(type: "datetime", nullable: true),
|
||||||
|
LockoutEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||||
AccessFailedCount = table.Column<int>(type: "int", nullable: false)
|
AccessFailedCount = table.Column<int>(type: "int", nullable: false)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
table.PrimaryKey("PK_Users", x => x.Id);
|
table.PrimaryKey("PK_Users", x => x.Id);
|
||||||
});
|
})
|
||||||
|
.Annotation("MySQL:Charset", "utf8mb4");
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "RoleClaims",
|
name: "RoleClaims",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<int>(type: "int", nullable: false)
|
Id = table.Column<int>(type: "int", nullable: false)
|
||||||
.Annotation("SqlServer:Identity", "1, 1"),
|
.Annotation("MySQL:ValueGenerationStrategy", MySQLValueGenerationStrategy.IdentityColumn),
|
||||||
RoleId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
RoleId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||||
ClaimType = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
ClaimType = table.Column<string>(type: "longtext", nullable: true),
|
||||||
ClaimValue = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
ClaimValue = table.Column<string>(type: "longtext", nullable: true)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
@@ -106,15 +127,16 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
principalTable: "Roles",
|
principalTable: "Roles",
|
||||||
principalColumn: "Id",
|
principalColumn: "Id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
});
|
})
|
||||||
|
.Annotation("MySQL:Charset", "utf8mb4");
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "ModulePermissions",
|
name: "ModulePermissions",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
UserId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||||
ModuleName = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
|
ModuleName = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: false),
|
||||||
Permission = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false)
|
Permission = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: false)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
@@ -125,20 +147,21 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
principalTable: "Users",
|
principalTable: "Users",
|
||||||
principalColumn: "Id",
|
principalColumn: "Id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
});
|
})
|
||||||
|
.Annotation("MySQL:Charset", "utf8mb4");
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "RefreshTokens",
|
name: "RefreshTokens",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||||
Token = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
|
Token = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: false),
|
||||||
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
UserId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||||
ExpiryDate = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false),
|
ExpiryDate = table.Column<DateTimeOffset>(type: "datetime", nullable: false),
|
||||||
IsUsed = table.Column<bool>(type: "bit", nullable: false),
|
IsUsed = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||||
IsRevoked = table.Column<bool>(type: "bit", nullable: false),
|
IsRevoked = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||||
CreatedAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false),
|
CreatedAt = table.Column<DateTimeOffset>(type: "datetime", nullable: false),
|
||||||
CreatedByIp = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
CreatedByIp = table.Column<string>(type: "longtext", nullable: true)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
@@ -149,17 +172,18 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
principalTable: "Users",
|
principalTable: "Users",
|
||||||
principalColumn: "Id",
|
principalColumn: "Id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
});
|
})
|
||||||
|
.Annotation("MySQL:Charset", "utf8mb4");
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "UserClaims",
|
name: "UserClaims",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<int>(type: "int", nullable: false)
|
Id = table.Column<int>(type: "int", nullable: false)
|
||||||
.Annotation("SqlServer:Identity", "1, 1"),
|
.Annotation("MySQL:ValueGenerationStrategy", MySQLValueGenerationStrategy.IdentityColumn),
|
||||||
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
UserId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||||
ClaimType = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
ClaimType = table.Column<string>(type: "longtext", nullable: true),
|
||||||
ClaimValue = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
ClaimValue = table.Column<string>(type: "longtext", nullable: true)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
@@ -170,16 +194,17 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
principalTable: "Users",
|
principalTable: "Users",
|
||||||
principalColumn: "Id",
|
principalColumn: "Id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
});
|
})
|
||||||
|
.Annotation("MySQL:Charset", "utf8mb4");
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "UserLogins",
|
name: "UserLogins",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
LoginProvider = table.Column<string>(type: "nvarchar(450)", nullable: false),
|
LoginProvider = table.Column<string>(type: "varchar(255)", nullable: false),
|
||||||
ProviderKey = table.Column<string>(type: "nvarchar(450)", nullable: false),
|
ProviderKey = table.Column<string>(type: "varchar(255)", nullable: false),
|
||||||
ProviderDisplayName = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
ProviderDisplayName = table.Column<string>(type: "longtext", nullable: true),
|
||||||
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false)
|
UserId = table.Column<Guid>(type: "char(36)", nullable: false)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
@@ -190,14 +215,15 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
principalTable: "Users",
|
principalTable: "Users",
|
||||||
principalColumn: "Id",
|
principalColumn: "Id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
});
|
})
|
||||||
|
.Annotation("MySQL:Charset", "utf8mb4");
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "UserRoles",
|
name: "UserRoles",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
UserId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||||
RoleId = table.Column<Guid>(type: "uniqueidentifier", nullable: false)
|
RoleId = table.Column<Guid>(type: "char(36)", nullable: false)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
@@ -214,16 +240,17 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
principalTable: "Users",
|
principalTable: "Users",
|
||||||
principalColumn: "Id",
|
principalColumn: "Id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
});
|
})
|
||||||
|
.Annotation("MySQL:Charset", "utf8mb4");
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "UserTokens",
|
name: "UserTokens",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
UserId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||||
LoginProvider = table.Column<string>(type: "nvarchar(450)", nullable: false),
|
LoginProvider = table.Column<string>(type: "varchar(255)", nullable: false),
|
||||||
Name = table.Column<string>(type: "nvarchar(450)", nullable: false),
|
Name = table.Column<string>(type: "varchar(255)", nullable: false),
|
||||||
Value = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
Value = table.Column<string>(type: "longtext", nullable: true)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
@@ -234,7 +261,8 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
principalTable: "Users",
|
principalTable: "Users",
|
||||||
principalColumn: "Id",
|
principalColumn: "Id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
});
|
})
|
||||||
|
.Annotation("MySQL:Charset", "utf8mb4");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "IX_Invitations_Token",
|
name: "IX_Invitations_Token",
|
||||||
@@ -262,8 +290,7 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
name: "RoleNameIndex",
|
name: "RoleNameIndex",
|
||||||
table: "Roles",
|
table: "Roles",
|
||||||
column: "NormalizedName",
|
column: "NormalizedName",
|
||||||
unique: true,
|
unique: true);
|
||||||
filter: "[NormalizedName] IS NOT NULL");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "IX_UserClaims_UserId",
|
name: "IX_UserClaims_UserId",
|
||||||
@@ -289,8 +316,7 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
name: "UserNameIndex",
|
name: "UserNameIndex",
|
||||||
table: "Users",
|
table: "Users",
|
||||||
column: "NormalizedUserName",
|
column: "NormalizedUserName",
|
||||||
unique: true,
|
unique: true);
|
||||||
filter: "[NormalizedUserName] IS NOT NULL");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -299,6 +325,9 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "AvailabilityState");
|
name: "AvailabilityState");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "DataProtectionKeys");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "Invitations");
|
name: "Invitations");
|
||||||
|
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
using SlpModularCms.Core.Data;
|
using SlpModularCms.Core.Data;
|
||||||
|
|
||||||
@@ -18,9 +17,7 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "10.0.9")
|
.HasAnnotation("ProductVersion", "10.0.9")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b =>
|
||||||
{
|
{
|
||||||
@@ -28,13 +25,11 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("FriendlyName")
|
b.Property<string>("FriendlyName")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<string>("Xml")
|
b.Property<string>("Xml")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
@@ -47,16 +42,14 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
b.Property<string>("ClaimType")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
b.Property<string>("ClaimValue")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<Guid>("RoleId")
|
b.Property<Guid>("RoleId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
@@ -71,16 +64,14 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("ClaimType")
|
b.Property<string>("ClaimType")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<string>("ClaimValue")
|
b.Property<string>("ClaimValue")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<Guid>("UserId")
|
b.Property<Guid>("UserId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
@@ -92,16 +83,16 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
|
||||||
{
|
{
|
||||||
b.Property<string>("LoginProvider")
|
b.Property<string>("LoginProvider")
|
||||||
.HasColumnType("nvarchar(450)");
|
.HasColumnType("varchar(255)");
|
||||||
|
|
||||||
b.Property<string>("ProviderKey")
|
b.Property<string>("ProviderKey")
|
||||||
.HasColumnType("nvarchar(450)");
|
.HasColumnType("varchar(255)");
|
||||||
|
|
||||||
b.Property<string>("ProviderDisplayName")
|
b.Property<string>("ProviderDisplayName")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<Guid>("UserId")
|
b.Property<Guid>("UserId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.HasKey("LoginProvider", "ProviderKey");
|
b.HasKey("LoginProvider", "ProviderKey");
|
||||||
|
|
||||||
@@ -113,10 +104,10 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("UserId")
|
b.Property<Guid>("UserId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<Guid>("RoleId")
|
b.Property<Guid>("RoleId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.HasKey("UserId", "RoleId");
|
b.HasKey("UserId", "RoleId");
|
||||||
|
|
||||||
@@ -128,16 +119,16 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("UserId")
|
b.Property<Guid>("UserId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<string>("LoginProvider")
|
b.Property<string>("LoginProvider")
|
||||||
.HasColumnType("nvarchar(450)");
|
.HasColumnType("varchar(255)");
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
.HasColumnType("nvarchar(450)");
|
.HasColumnType("varchar(255)");
|
||||||
|
|
||||||
b.Property<string>("Value")
|
b.Property<string>("Value")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.HasKey("UserId", "LoginProvider", "Name");
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
@@ -148,26 +139,25 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
b.Property<string>("ConcurrencyStamp")
|
||||||
.IsConcurrencyToken()
|
.IsConcurrencyToken()
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("nvarchar(256)");
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
b.Property<string>("NormalizedName")
|
b.Property<string>("NormalizedName")
|
||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("nvarchar(256)");
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.HasIndex("NormalizedName")
|
b.HasIndex("NormalizedName")
|
||||||
.IsUnique()
|
.IsUnique()
|
||||||
.HasDatabaseName("RoleNameIndex")
|
.HasDatabaseName("RoleNameIndex");
|
||||||
.HasFilter("[NormalizedName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("Roles", (string)null);
|
b.ToTable("Roles", (string)null);
|
||||||
});
|
});
|
||||||
@@ -176,63 +166,63 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<int>("AccessFailedCount")
|
b.Property<int>("AccessFailedCount")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<string>("ConcurrencyStamp")
|
b.Property<string>("ConcurrencyStamp")
|
||||||
.IsConcurrencyToken()
|
.IsConcurrencyToken()
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("CreatedAt")
|
b.Property<DateTimeOffset>("CreatedAt")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<string>("DisplayName")
|
b.Property<string>("DisplayName")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<string>("Email")
|
b.Property<string>("Email")
|
||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("nvarchar(256)");
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
b.Property<bool>("EmailConfirmed")
|
b.Property<bool>("EmailConfirmed")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
b.Property<bool>("IsActive")
|
b.Property<bool>("IsActive")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
b.Property<bool>("LockoutEnabled")
|
b.Property<bool>("LockoutEnabled")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<string>("NormalizedEmail")
|
b.Property<string>("NormalizedEmail")
|
||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("nvarchar(256)");
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
b.Property<string>("NormalizedUserName")
|
b.Property<string>("NormalizedUserName")
|
||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("nvarchar(256)");
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
b.Property<string>("PasswordHash")
|
b.Property<string>("PasswordHash")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<string>("PhoneNumber")
|
b.Property<string>("PhoneNumber")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<bool>("PhoneNumberConfirmed")
|
b.Property<bool>("PhoneNumberConfirmed")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
b.Property<string>("SecurityStamp")
|
b.Property<string>("SecurityStamp")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<bool>("TwoFactorEnabled")
|
b.Property<bool>("TwoFactorEnabled")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
b.Property<string>("UserName")
|
b.Property<string>("UserName")
|
||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("nvarchar(256)");
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
@@ -241,8 +231,7 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
|
|
||||||
b.HasIndex("NormalizedUserName")
|
b.HasIndex("NormalizedUserName")
|
||||||
.IsUnique()
|
.IsUnique()
|
||||||
.HasDatabaseName("UserNameIndex")
|
.HasDatabaseName("UserNameIndex");
|
||||||
.HasFilter("[NormalizedUserName] IS NOT NULL");
|
|
||||||
|
|
||||||
b.ToTable("Users", (string)null);
|
b.ToTable("Users", (string)null);
|
||||||
});
|
});
|
||||||
@@ -251,19 +240,19 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("LastUpdatedAt")
|
b.Property<DateTimeOffset>("LastUpdatedAt")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<string>("Message")
|
b.Property<string>("Message")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<int>("Status")
|
b.Property<int>("Status")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<string>("UpdatedBy")
|
b.Property<string>("UpdatedBy")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
@@ -274,30 +263,30 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("CreatedAt")
|
b.Property<DateTimeOffset>("CreatedAt")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<string>("Email")
|
b.Property<string>("Email")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("nvarchar(256)");
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("ExpiryDate")
|
b.Property<DateTimeOffset>("ExpiryDate")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<bool>("IsAccepted")
|
b.Property<bool>("IsAccepted")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
b.Property<string>("Role")
|
b.Property<string>("Role")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<string>("Token")
|
b.Property<string>("Token")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("nvarchar(256)");
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
@@ -310,15 +299,15 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.ModulePermission", b =>
|
modelBuilder.Entity("SlpModularCms.Core.Identity.Entities.ModulePermission", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("UserId")
|
b.Property<Guid>("UserId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<string>("ModuleName")
|
b.Property<string>("ModuleName")
|
||||||
.HasMaxLength(128)
|
.HasMaxLength(128)
|
||||||
.HasColumnType("nvarchar(128)");
|
.HasColumnType("varchar(128)");
|
||||||
|
|
||||||
b.Property<string>("Permission")
|
b.Property<string>("Permission")
|
||||||
.HasMaxLength(128)
|
.HasMaxLength(128)
|
||||||
.HasColumnType("nvarchar(128)");
|
.HasColumnType("varchar(128)");
|
||||||
|
|
||||||
b.HasKey("UserId", "ModuleName", "Permission");
|
b.HasKey("UserId", "ModuleName", "Permission");
|
||||||
|
|
||||||
@@ -329,30 +318,30 @@ namespace SlpModularCms.Core.Migrations
|
|||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("CreatedAt")
|
b.Property<DateTimeOffset>("CreatedAt")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<string>("CreatedByIp")
|
b.Property<string>("CreatedByIp")
|
||||||
.HasColumnType("nvarchar(max)");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("ExpiryDate")
|
b.Property<DateTimeOffset>("ExpiryDate")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<bool>("IsRevoked")
|
b.Property<bool>("IsRevoked")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
b.Property<bool>("IsUsed")
|
b.Property<bool>("IsUsed")
|
||||||
.HasColumnType("bit");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
b.Property<string>("Token")
|
b.Property<string>("Token")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("nvarchar(256)");
|
.HasColumnType("varchar(256)");
|
||||||
|
|
||||||
b.Property<Guid>("UserId")
|
b.Property<Guid>("UserId")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,22 @@
|
|||||||
<PackageReference Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" Version="10.0.9" />
|
<PackageReference Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" Version="10.0.9" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="10.0.9" />
|
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="10.0.9" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.9" />
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.9" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.9" />
|
<!--
|
||||||
|
MariaDB/MySQL provider (Operations — the target Pi only has MariaDB, and MySQL Server has no
|
||||||
|
ARM64 build at all). Pomelo, not Oracle's official MySql.EntityFrameworkCore: Oracle's
|
||||||
|
provider has a confirmed MariaDB-incompatibility bug in its migration-lock acquisition
|
||||||
|
(AcquireDatabaseLock throws InvalidCastException — MariaDB's GET_LOCK() returns something
|
||||||
|
Oracle's code doesn't expect), reproduced against a real MariaDB instance. Pomelo has
|
||||||
|
first-class MariaDB support and worked cleanly on the same database.
|
||||||
|
Pomelo 9.0.0's own dependency range caps at EF Core 9.x (NU1608 warning at restore — no EF
|
||||||
|
Core 10 release exists yet), but per the Pomelo maintainers
|
||||||
|
(https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql/pull/2017) Pomelo 9 /
|
||||||
|
EF Core 9 packages are compatible with a net10.0 TargetFramework as long as no new EF Core 10
|
||||||
|
APIs are used — confirmed here empirically: restore/build/test/migrations all succeed with
|
||||||
|
Microsoft.AspNetCore.Identity.EntityFrameworkCore and
|
||||||
|
Microsoft.AspNetCore.DataProtection.EntityFrameworkCore left at 10.0.9.
|
||||||
|
-->
|
||||||
|
<PackageReference Include="MySql.EntityFrameworkCore" Version="10.0.7" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.9" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.9" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.9" />
|
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.9" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.9" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.9" />
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using SlpModularCms.Core.Availability;
|
using SlpModularCms.Core.Availability;
|
||||||
|
using SlpModularCms.Core.Hosting;
|
||||||
using SlpModularCms.Core.Modules;
|
using SlpModularCms.Core.Modules;
|
||||||
using SlpModularCms.Modules.Availability.BackgroundServices;
|
using SlpModularCms.Modules.Availability.BackgroundServices;
|
||||||
using SlpModularCms.Modules.Availability.Config;
|
using SlpModularCms.Modules.Availability.Config;
|
||||||
@@ -28,7 +30,8 @@ public class AvailabilityModule : IModule
|
|||||||
services.AddDbContext<AvailabilityDbContext>((serviceProvider, options) =>
|
services.AddDbContext<AvailabilityDbContext>((serviceProvider, options) =>
|
||||||
{
|
{
|
||||||
var configuration = serviceProvider.GetRequiredService<IConfiguration>();
|
var configuration = serviceProvider.GetRequiredService<IConfiguration>();
|
||||||
options.UseSqlServer(configuration.GetConnectionString("DefaultConnection"));
|
options.UseMySQL(configuration.GetConnectionString("DefaultConnection")!);
|
||||||
|
options.ReplaceService<IHistoryRepository, NonLockingMySQLHistoryRepository>();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Data Protection is configured once by the host (AddCmsDataProtection), NOT here.
|
// Data Protection is configured once by the host (AddCmsDataProtection), NOT here.
|
||||||
|
|||||||
-60
@@ -1,60 +0,0 @@
|
|||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
using SlpModularCms.Modules.Availability.Data;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace SlpModularCms.Modules.Availability.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(AvailabilityDbContext))]
|
|
||||||
[Migration("20260704142458_AddLastPolledAtToMasterRegistration")]
|
|
||||||
partial class AddLastPolledAtToMasterRegistration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "10.0.9")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Modules.Availability.Data.Entities.MasterRegistration", b =>
|
|
||||||
{
|
|
||||||
b.Property<Guid>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("uniqueidentifier");
|
|
||||||
|
|
||||||
b.Property<string>("ApiKey")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(2000)
|
|
||||||
.HasColumnType("nvarchar(2000)");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LastContactedAt")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LastPolledAt")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.Property<string>("MasterUrl")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(500)
|
|
||||||
.HasColumnType("nvarchar(500)");
|
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("RegisteredAt")
|
|
||||||
.HasColumnType("datetimeoffset");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("AvailabilityMasterRegistrations", (string)null);
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace SlpModularCms.Modules.Availability.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class AddLastPolledAtToMasterRegistration : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AddColumn<DateTimeOffset>(
|
|
||||||
name: "LastPolledAt",
|
|
||||||
table: "AvailabilityMasterRegistrations",
|
|
||||||
type: "datetimeoffset",
|
|
||||||
nullable: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "LastPolledAt",
|
|
||||||
table: "AvailabilityMasterRegistrations");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+10
-10
@@ -2,7 +2,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
using SlpModularCms.Modules.Availability.Data;
|
using SlpModularCms.Modules.Availability.Data;
|
||||||
@@ -12,7 +11,7 @@ using SlpModularCms.Modules.Availability.Data;
|
|||||||
namespace SlpModularCms.Modules.Availability.Migrations
|
namespace SlpModularCms.Modules.Availability.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(AvailabilityDbContext))]
|
[DbContext(typeof(AvailabilityDbContext))]
|
||||||
[Migration("20260701200414_InitialCreate")]
|
[Migration("20260729095354_InitialCreate")]
|
||||||
partial class InitialCreate
|
partial class InitialCreate
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -21,31 +20,32 @@ namespace SlpModularCms.Modules.Availability.Migrations
|
|||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "10.0.9")
|
.HasAnnotation("ProductVersion", "10.0.9")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Modules.Availability.Data.Entities.MasterRegistration", b =>
|
modelBuilder.Entity("SlpModularCms.Modules.Availability.Data.Entities.MasterRegistration", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<string>("ApiKey")
|
b.Property<string>("ApiKey")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(2000)
|
.HasMaxLength(2000)
|
||||||
.HasColumnType("nvarchar(2000)");
|
.HasColumnType("varchar(2000)");
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LastContactedAt")
|
b.Property<DateTimeOffset?>("LastContactedAt")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LastPolledAt")
|
||||||
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<string>("MasterUrl")
|
b.Property<string>("MasterUrl")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(500)
|
.HasMaxLength(500)
|
||||||
.HasColumnType("nvarchar(500)");
|
.HasColumnType("varchar(500)");
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("RegisteredAt")
|
b.Property<DateTimeOffset>("RegisteredAt")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
+11
-6
@@ -11,20 +11,25 @@ namespace SlpModularCms.Modules.Availability.Migrations
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
|
migrationBuilder.AlterDatabase()
|
||||||
|
.Annotation("MySQL:Charset", "utf8mb4");
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "AvailabilityMasterRegistrations",
|
name: "AvailabilityMasterRegistrations",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||||
MasterUrl = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: false),
|
MasterUrl = table.Column<string>(type: "varchar(500)", maxLength: 500, nullable: false),
|
||||||
ApiKey = table.Column<string>(type: "nvarchar(2000)", maxLength: 2000, nullable: false),
|
ApiKey = table.Column<string>(type: "varchar(2000)", maxLength: 2000, nullable: false),
|
||||||
RegisteredAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false),
|
RegisteredAt = table.Column<DateTimeOffset>(type: "datetime", nullable: false),
|
||||||
LastContactedAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: true)
|
LastContactedAt = table.Column<DateTimeOffset>(type: "datetime", nullable: true),
|
||||||
|
LastPolledAt = table.Column<DateTimeOffset>(type: "datetime", nullable: true)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
table.PrimaryKey("PK_AvailabilityMasterRegistrations", x => x.Id);
|
table.PrimaryKey("PK_AvailabilityMasterRegistrations", x => x.Id);
|
||||||
});
|
})
|
||||||
|
.Annotation("MySQL:Charset", "utf8mb4");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
+7
-10
@@ -2,7 +2,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
using SlpModularCms.Modules.Availability.Data;
|
using SlpModularCms.Modules.Availability.Data;
|
||||||
|
|
||||||
@@ -18,34 +17,32 @@ namespace SlpModularCms.Modules.Availability.Migrations
|
|||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "10.0.9")
|
.HasAnnotation("ProductVersion", "10.0.9")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Modules.Availability.Data.Entities.MasterRegistration", b =>
|
modelBuilder.Entity("SlpModularCms.Modules.Availability.Data.Entities.MasterRegistration", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<string>("ApiKey")
|
b.Property<string>("ApiKey")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(2000)
|
.HasMaxLength(2000)
|
||||||
.HasColumnType("nvarchar(2000)");
|
.HasColumnType("varchar(2000)");
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LastContactedAt")
|
b.Property<DateTimeOffset?>("LastContactedAt")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LastPolledAt")
|
b.Property<DateTimeOffset?>("LastPolledAt")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<string>("MasterUrl")
|
b.Property<string>("MasterUrl")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(500)
|
.HasMaxLength(500)
|
||||||
.HasColumnType("nvarchar(500)");
|
.HasColumnType("varchar(500)");
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("RegisteredAt")
|
b.Property<DateTimeOffset>("RegisteredAt")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Http.Resilience;
|
using Microsoft.Extensions.Http.Resilience;
|
||||||
using Polly;
|
using Polly;
|
||||||
|
using SlpModularCms.Core.Hosting;
|
||||||
using SlpModularCms.Core.Modules;
|
using SlpModularCms.Core.Modules;
|
||||||
using SlpModularCms.Modules.Master.BackgroundServices;
|
using SlpModularCms.Modules.Master.BackgroundServices;
|
||||||
using SlpModularCms.Modules.Master.Data;
|
using SlpModularCms.Modules.Master.Data;
|
||||||
@@ -33,7 +35,8 @@ public class MasterModule : IModule
|
|||||||
services.AddDbContext<MasterDbContext>((serviceProvider, options) =>
|
services.AddDbContext<MasterDbContext>((serviceProvider, options) =>
|
||||||
{
|
{
|
||||||
var config = serviceProvider.GetRequiredService<IConfiguration>();
|
var config = serviceProvider.GetRequiredService<IConfiguration>();
|
||||||
options.UseSqlServer(config.GetConnectionString("DefaultConnection"));
|
options.UseMySQL(config.GetConnectionString("DefaultConnection")!);
|
||||||
|
options.ReplaceService<IHistoryRepository, NonLockingMySQLHistoryRepository>();
|
||||||
});
|
});
|
||||||
|
|
||||||
services.AddScoped<ICmsInstanceRepository, CmsInstanceRepository>();
|
services.AddScoped<ICmsInstanceRepository, CmsInstanceRepository>();
|
||||||
|
|||||||
+10
-13
@@ -2,7 +2,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
using SlpModularCms.Modules.Master.Data;
|
using SlpModularCms.Modules.Master.Data;
|
||||||
@@ -12,7 +11,7 @@ using SlpModularCms.Modules.Master.Data;
|
|||||||
namespace SlpModularCms.Modules.Master.Migrations
|
namespace SlpModularCms.Modules.Master.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(MasterDbContext))]
|
[DbContext(typeof(MasterDbContext))]
|
||||||
[Migration("20260630210103_InitialCreate")]
|
[Migration("20260729095359_InitialCreate")]
|
||||||
partial class InitialCreate
|
partial class InitialCreate
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -21,38 +20,36 @@ namespace SlpModularCms.Modules.Master.Migrations
|
|||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "10.0.9")
|
.HasAnnotation("ProductVersion", "10.0.9")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Modules.Master.Data.Entities.CmsInstance", b =>
|
modelBuilder.Entity("SlpModularCms.Modules.Master.Data.Entities.CmsInstance", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<string>("ApiKey")
|
b.Property<string>("ApiKey")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(1000)
|
.HasMaxLength(1000)
|
||||||
.HasColumnType("nvarchar(1000)");
|
.HasColumnType("varchar(1000)");
|
||||||
|
|
||||||
b.Property<string>("DisableMessage")
|
b.Property<string>("DisableMessage")
|
||||||
.HasMaxLength(500)
|
.HasMaxLength(500)
|
||||||
.HasColumnType("nvarchar(500)");
|
.HasColumnType("varchar(500)");
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LastContactedAt")
|
b.Property<DateTimeOffset?>("LastContactedAt")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LastIntegrityCheckFailedAt")
|
b.Property<DateTimeOffset?>("LastIntegrityCheckFailedAt")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LastStatusPushedAt")
|
b.Property<DateTimeOffset?>("LastStatusPushedAt")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(200)
|
.HasMaxLength(200)
|
||||||
.HasColumnType("nvarchar(200)");
|
.HasColumnType("varchar(200)");
|
||||||
|
|
||||||
b.Property<int>("Status")
|
b.Property<int>("Status")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
@@ -60,7 +57,7 @@ namespace SlpModularCms.Modules.Master.Migrations
|
|||||||
b.Property<string>("Url")
|
b.Property<string>("Url")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(500)
|
.HasMaxLength(500)
|
||||||
.HasColumnType("nvarchar(500)");
|
.HasColumnType("varchar(500)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
+13
-9
@@ -11,24 +11,28 @@ namespace SlpModularCms.Modules.Master.Migrations
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
|
migrationBuilder.AlterDatabase()
|
||||||
|
.Annotation("MySQL:Charset", "utf8mb4");
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "MasterCmsInstances",
|
name: "MasterCmsInstances",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||||
Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
|
Name = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false),
|
||||||
Url = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: false),
|
Url = table.Column<string>(type: "varchar(500)", maxLength: 500, nullable: false),
|
||||||
ApiKey = table.Column<string>(type: "nvarchar(1000)", maxLength: 1000, nullable: false),
|
ApiKey = table.Column<string>(type: "varchar(1000)", maxLength: 1000, nullable: false),
|
||||||
Status = table.Column<int>(type: "int", nullable: false),
|
Status = table.Column<int>(type: "int", nullable: false),
|
||||||
DisableMessage = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: true),
|
DisableMessage = table.Column<string>(type: "varchar(500)", maxLength: 500, nullable: true),
|
||||||
LastContactedAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: true),
|
LastContactedAt = table.Column<DateTimeOffset>(type: "datetime", nullable: true),
|
||||||
LastStatusPushedAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: true),
|
LastStatusPushedAt = table.Column<DateTimeOffset>(type: "datetime", nullable: true),
|
||||||
LastIntegrityCheckFailedAt = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: true)
|
LastIntegrityCheckFailedAt = table.Column<DateTimeOffset>(type: "datetime", nullable: true)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
table.PrimaryKey("PK_MasterCmsInstances", x => x.Id);
|
table.PrimaryKey("PK_MasterCmsInstances", x => x.Id);
|
||||||
});
|
})
|
||||||
|
.Annotation("MySQL:Charset", "utf8mb4");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
using SlpModularCms.Modules.Master.Data;
|
using SlpModularCms.Modules.Master.Data;
|
||||||
|
|
||||||
@@ -18,38 +17,36 @@ namespace SlpModularCms.Modules.Master.Migrations
|
|||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "10.0.9")
|
.HasAnnotation("ProductVersion", "10.0.9")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("SlpModularCms.Modules.Master.Data.Entities.CmsInstance", b =>
|
modelBuilder.Entity("SlpModularCms.Modules.Master.Data.Entities.CmsInstance", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<string>("ApiKey")
|
b.Property<string>("ApiKey")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(1000)
|
.HasMaxLength(1000)
|
||||||
.HasColumnType("nvarchar(1000)");
|
.HasColumnType("varchar(1000)");
|
||||||
|
|
||||||
b.Property<string>("DisableMessage")
|
b.Property<string>("DisableMessage")
|
||||||
.HasMaxLength(500)
|
.HasMaxLength(500)
|
||||||
.HasColumnType("nvarchar(500)");
|
.HasColumnType("varchar(500)");
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LastContactedAt")
|
b.Property<DateTimeOffset?>("LastContactedAt")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LastIntegrityCheckFailedAt")
|
b.Property<DateTimeOffset?>("LastIntegrityCheckFailedAt")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<DateTimeOffset?>("LastStatusPushedAt")
|
b.Property<DateTimeOffset?>("LastStatusPushedAt")
|
||||||
.HasColumnType("datetimeoffset");
|
.HasColumnType("datetime");
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(200)
|
.HasMaxLength(200)
|
||||||
.HasColumnType("nvarchar(200)");
|
.HasColumnType("varchar(200)");
|
||||||
|
|
||||||
b.Property<int>("Status")
|
b.Property<int>("Status")
|
||||||
.HasColumnType("int");
|
.HasColumnType("int");
|
||||||
@@ -57,7 +54,7 @@ namespace SlpModularCms.Modules.Master.Migrations
|
|||||||
b.Property<string>("Url")
|
b.Property<string>("Url")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(500)
|
.HasMaxLength(500)
|
||||||
.HasColumnType("nvarchar(500)");
|
.HasColumnType("varchar(500)");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user