The Estimate is validated
Some checks failed
Dotnet build and test / build (pull_request) Failing after 7m28s
Some checks failed
Dotnet build and test / build (pull_request) Failing after 7m28s
This commit is contained in:
parent
848f8be42f
commit
2484876c5b
20 changed files with 5392 additions and 218 deletions
27
.vscode/launch.json
vendored
27
.vscode/launch.json
vendored
|
|
@ -4,6 +4,22 @@
|
|||
// Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "PostIt Desktop",
|
||||
"type": "dotnet",
|
||||
"request": "launch",
|
||||
"projectPath": "${workspaceFolder}/src/PostIt/PostIt.Desktop/PostIt.Desktop.csproj"
|
||||
},
|
||||
{
|
||||
"name": "PostIt Desktop local",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/src/PostIt/PostIt.Desktop/bin/Debug/net10.0/PostIt.Desktop.dll",
|
||||
"env": {
|
||||
"POSTIT_SETTINGS_JSON": "/home/paul/Workspace/yavsc/src/PostIt/PostIt/postit-settings.json"
|
||||
},
|
||||
"preLaunchTask": "dotnet: build-postit-desktop"
|
||||
},
|
||||
{
|
||||
"name": "Android Debug",
|
||||
"type": "mono",
|
||||
|
|
@ -20,10 +36,10 @@
|
|||
"port": 55555
|
||||
},
|
||||
{
|
||||
"name": "API",
|
||||
"name": "Yavsc API",
|
||||
"type": "dotnet",
|
||||
"request": "launch",
|
||||
"projectPath": "${workspaceFolder}/src/Api/Api.csproj"
|
||||
"projectPath": "${workspaceFolder}/src/Yavsc.Api/Yavsc.Api.csproj"
|
||||
},
|
||||
{
|
||||
"name": "Yavsc Org",
|
||||
|
|
@ -37,12 +53,7 @@
|
|||
"request": "launch",
|
||||
"projectPath": "${workspaceFolder}/src/Yavsc.Blogs/Yavsc.Blogs.csproj"
|
||||
},
|
||||
{
|
||||
"name": "PostIt Desktop",
|
||||
"type": "dotnet",
|
||||
"request": "launch",
|
||||
"projectPath": "${workspaceFolder}/src/PostIt/PostIt.Desktop/PostIt.Desktop.csproj",
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Test PostIt.Android launch (Xamarin.UITest)",
|
||||
"type": "coreclr",
|
||||
|
|
|
|||
19
.vscode/tasks.json
vendored
19
.vscode/tasks.json
vendored
|
|
@ -69,7 +69,7 @@
|
|||
{
|
||||
"label": "test api backend (npgsql)",
|
||||
"type": "process",
|
||||
"problemMatcher": ["$msCompile"],
|
||||
"problemMatcher": "$msCompile",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"test",
|
||||
|
|
@ -80,7 +80,7 @@
|
|||
"options": {
|
||||
"cwd": "src/Yavsc.Api.Test",
|
||||
"env": {
|
||||
"YAVSC_API_TEST_DB_PROVIDER": "npgsql",
|
||||
"YAVSC_API_TEST_DB_PROVIDER": "npgsql"
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
|
|
@ -101,6 +101,21 @@
|
|||
"kind": "build"
|
||||
},
|
||||
"isBackground": true
|
||||
},
|
||||
{
|
||||
"label": "dotnet: build-postit-desktop",
|
||||
"type": "process",
|
||||
"isBuildCommand": true,
|
||||
"isTestCommand": false,
|
||||
"isBackground": true,
|
||||
"command": "dotnet",
|
||||
"args": ["build", "/property:GenerateFullPaths=true"],
|
||||
"options": {
|
||||
"cwd": "src/PostIt/PostIt.Desktop"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
# Read me
|
||||
|
||||
## Note aux icones
|
||||
|
||||
㝉®🅬⛒⛑🩎🩺🞫🞮🞕🞖🞆🔴🔵🔲🖂🔧🔩🔐🔌💾💼💬💭👿👾🏷🎯🏹🌍🎎💩
|
||||
|
|
@ -22,7 +22,7 @@ public partial class AuthenticationSettings : ObservableObject
|
|||
|
||||
public const string DefaultClientId = "postit";
|
||||
|
||||
public static readonly string[] DefaultScopes = { "blogs" };
|
||||
public static readonly string[] DefaultScopes = { "blogs", "api" };
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string Authority { get; set; }
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ namespace PostIt.ViewModels;
|
|||
|
||||
public partial class Settings : ViewModelBase
|
||||
{
|
||||
public string SettingsFileName {get; private set;} = "postit-settings.json";
|
||||
[JsonIgnore]
|
||||
public string? SettingsFileFullName { get; private set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial AuthenticationSettings Authentication { get; set; } = new();
|
||||
|
|
@ -39,6 +40,60 @@ public partial class Settings : ViewModelBase
|
|||
[JsonIgnore]
|
||||
public partial StatusNotice ActionStatus { get; set; } = StatusNotice.Info("Pret.");
|
||||
|
||||
|
||||
public bool Loaded { get; private set; } = false;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// True when the in-memory state has drifted from the last
|
||||
/// <see cref="Load"/> or <see cref="Save"/> snapshot. The
|
||||
/// Settings page binds the Sauver button's <c>IsEnabled</c> to
|
||||
/// this flag, so it only enables when the user has actually
|
||||
/// touched something since the last load / save. Cleared by
|
||||
/// <see cref="Load"/> (and by <see cref="ApplyJson"/>), set by
|
||||
/// every successful setter on the four top-level mutable
|
||||
/// properties and on the sub-properties of
|
||||
/// <see cref="Authentication"/>.
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
public partial bool IsDirty { get; private set; } = false;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guards every mutation of the observable state. <c>[ObservableProperty]</c>
|
||||
/// generates setters that call <c>SetProperty(...)</c> which fires
|
||||
/// <c>PropertyChanged</c>. Avalonia bindings consume that event on
|
||||
/// the UI thread, and a stray background-thread update is exactly
|
||||
/// what crashed <c>DataValidationErrors.SetErrors</c> on
|
||||
/// <c>postit://callback</c> re-launches. The lock makes mutations
|
||||
/// atomic; <see cref="OnPropertyChanged(PropertyChangedEventArgs)"/>
|
||||
/// then marshals the notification onto the UI thread so bindings
|
||||
/// observe the change on the right thread.
|
||||
/// </summary>
|
||||
private readonly object _mutationGate = new();
|
||||
|
||||
/// <summary>
|
||||
/// Scopes the PostIt client always requires from the OIDC provider,
|
||||
/// regardless of what the user has in their settings file.
|
||||
///
|
||||
/// <para>PostIt calls into the Blog API (and any other Yavsc API
|
||||
/// gated by an <c>[Authorize("…Scope")]</c> policy) and is silent
|
||||
/// about the contract: a missing scope here surfaces as a 401
|
||||
/// on the very first API call after login, with no obvious link
|
||||
/// to the settings. The "feature" scopes the user must opt into
|
||||
/// (e.g. <c>blogs</c>) are still their choice — we only force the
|
||||
/// structural ones that OIDC itself needs.</para>
|
||||
/// </summary>
|
||||
private static readonly string[] BuiltInScopes = new[]
|
||||
{
|
||||
"openid", // OIDC: required for the id_token
|
||||
"profile", // OIDC: standard profile claims
|
||||
"offline_access", // OIDC: required to receive a refresh_token
|
||||
"blogs",
|
||||
"api"
|
||||
};
|
||||
private readonly string DEFAULT_SETTINGS_FILENAME = "postit-settings.json";
|
||||
|
||||
public void SetActionStatus(string message, StatusSeverity severity = StatusSeverity.Info)
|
||||
{
|
||||
ActionStatus = severity switch
|
||||
|
|
@ -86,35 +141,6 @@ public partial class Settings : ViewModelBase
|
|||
MarkDirty();
|
||||
}
|
||||
|
||||
public bool Loaded { get; private set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// True when the in-memory state has drifted from the last
|
||||
/// <see cref="Load"/> or <see cref="Save"/> snapshot. The
|
||||
/// Settings page binds the Sauver button's <c>IsEnabled</c> to
|
||||
/// this flag, so it only enables when the user has actually
|
||||
/// touched something since the last load / save. Cleared by
|
||||
/// <see cref="Load"/> (and by <see cref="ApplyJson"/>), set by
|
||||
/// every successful setter on the four top-level mutable
|
||||
/// properties and on the sub-properties of
|
||||
/// <see cref="Authentication"/>.
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
public partial bool IsDirty { get; private set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Guards every mutation of the observable state. <c>[ObservableProperty]</c>
|
||||
/// generates setters that call <c>SetProperty(...)</c> which fires
|
||||
/// <c>PropertyChanged</c>. Avalonia bindings consume that event on
|
||||
/// the UI thread, and a stray background-thread update is exactly
|
||||
/// what crashed <c>DataValidationErrors.SetErrors</c> on
|
||||
/// <c>postit://callback</c> re-launches. The lock makes mutations
|
||||
/// atomic; <see cref="OnPropertyChanged(PropertyChangedEventArgs)"/>
|
||||
/// then marshals the notification onto the UI thread so bindings
|
||||
/// observe the change on the right thread.
|
||||
/// </summary>
|
||||
private readonly object _mutationGate = new();
|
||||
|
||||
/// <summary>
|
||||
/// Build OidcClient options configured for Authorization Code + PKCE
|
||||
/// (no client secret). The browser implementation should be supplied
|
||||
|
|
@ -178,27 +204,6 @@ public partial class Settings : ViewModelBase
|
|||
Authentication.RefreshScopeListText();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scopes the PostIt client always requires from the OIDC provider,
|
||||
/// regardless of what the user has in their settings file.
|
||||
///
|
||||
/// <para>PostIt calls into the Blog API (and any other Yavsc API
|
||||
/// gated by an <c>[Authorize("…Scope")]</c> policy) and is silent
|
||||
/// about the contract: a missing scope here surfaces as a 401
|
||||
/// on the very first API call after login, with no obvious link
|
||||
/// to the settings. The "feature" scopes the user must opt into
|
||||
/// (e.g. <c>blogs</c>) are still their choice — we only force the
|
||||
/// structural ones that OIDC itself needs.</para>
|
||||
/// </summary>
|
||||
private static readonly string[] BuiltInScopes = new[]
|
||||
{
|
||||
"openid", // OIDC: required for the id_token
|
||||
"profile", // OIDC: standard profile claims
|
||||
"offline_access", // OIDC: required to receive a refresh_token
|
||||
"blogs",
|
||||
"api"
|
||||
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Merge user-configured scopes with the built-in ones. User scopes
|
||||
|
|
@ -255,7 +260,14 @@ public partial class Settings : ViewModelBase
|
|||
&& !string.IsNullOrWhiteSpace(envJson))
|
||||
{
|
||||
Console.WriteLine("🔎 Loading settings from POSTIT_SETTINGS_JSON environment variable.");
|
||||
ApplyJson(envJson, "POSTIT_SETTINGS_JSON");
|
||||
FileInfo configByEnvFileInfo = new FileInfo(envJson);
|
||||
if (!configByEnvFileInfo.Exists)
|
||||
{
|
||||
throw new Exception($"🩎 Settings file not found at {configByEnvFileInfo.FullName}");
|
||||
}
|
||||
string json = File.ReadAllText(configByEnvFileInfo.FullName);
|
||||
ApplyJson(json, "POSTIT_SETTINGS_JSON");
|
||||
SettingsFileFullName = configByEnvFileInfo.FullName;
|
||||
Loaded = true;
|
||||
return;
|
||||
}
|
||||
|
|
@ -264,9 +276,22 @@ public partial class Settings : ViewModelBase
|
|||
"PostIt"
|
||||
);
|
||||
|
||||
string configPath = Path.Combine(configDir, SettingsFileName);
|
||||
if (SettingsFileFullName is not null)
|
||||
{
|
||||
// Already set by a previous Load() or by the environment
|
||||
// variable path above. Use it as-is.
|
||||
}
|
||||
else if (Environment.GetEnvironmentVariable("POSTIT_SETTINGS_JSON") is string envPath
|
||||
&& !string.IsNullOrWhiteSpace(envPath))
|
||||
{
|
||||
SettingsFileFullName = envPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
SettingsFileFullName = Path.Combine(configDir, "postit-settings.json");
|
||||
}
|
||||
|
||||
FileInfo configFileInfo = new FileInfo(configPath);
|
||||
FileInfo configFileInfo = new FileInfo(SettingsFileFullName);
|
||||
|
||||
if (!configFileInfo.Exists)
|
||||
{
|
||||
|
|
@ -295,6 +320,7 @@ public partial class Settings : ViewModelBase
|
|||
using var reader = new StreamReader(stream);
|
||||
var json = reader.ReadToEnd();
|
||||
ApplyJson(json, $"user file {configFileInfo.FullName}");
|
||||
SettingsFileFullName = configFileInfo.FullName;
|
||||
Loaded = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -458,11 +484,17 @@ public partial class Settings : ViewModelBase
|
|||
{
|
||||
SetActionStatus("Enregistrement des parametres...", StatusSeverity.Info);
|
||||
|
||||
var configDir = Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||
"PostIt");
|
||||
Directory.CreateDirectory(configDir);
|
||||
var configPath = Path.Combine(configDir, SettingsFileName);
|
||||
if (SettingsFileFullName is null)
|
||||
{
|
||||
var configDir = Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||
"PostIt");
|
||||
Directory.CreateDirectory(configDir);
|
||||
SettingsFileFullName = Path.Combine(configDir, DEFAULT_SETTINGS_FILENAME);
|
||||
}
|
||||
|
||||
var configPath = SettingsFileFullName!;
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(configPath)!);
|
||||
|
||||
lock (_mutationGate)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"Authentication": {
|
||||
"ClientId": "postit",
|
||||
"Authority": "https://yavsc.pschneider.fr"
|
||||
},
|
||||
"RedirectUri": "postit://callback",
|
||||
"DarkMode": false,
|
||||
"ApiUrl": "https://api.pschneider.fr/api/v1/",
|
||||
"Scopes": [
|
||||
"openid",
|
||||
"profile",
|
||||
"offline_access",
|
||||
"blogs"
|
||||
]
|
||||
}
|
||||
17
src/PostIt/PostIt/postit-settings-sample.json
Normal file
17
src/PostIt/PostIt/postit-settings-sample.json
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"Authentication": {
|
||||
"ClientId": "postit",
|
||||
"Authority": "https://yavsc.pschneider.fr",
|
||||
"Scopes": [
|
||||
"openid",
|
||||
"profile",
|
||||
"offline_access",
|
||||
"blogs",
|
||||
"api"
|
||||
],
|
||||
"RedirectUri": "postit://callback"
|
||||
},
|
||||
"DarkMode": false,
|
||||
"ApiUrl": "https://api.pschneider.fr/api/v1/"
|
||||
|
||||
}
|
||||
|
|
@ -1,15 +1,21 @@
|
|||
{
|
||||
"Authentication": {
|
||||
"ClientId": "postit",
|
||||
"Authority": "https://yavsc.pschneider.fr/"
|
||||
},
|
||||
"RedirectUri": "postit://callback",
|
||||
"DarkMode": true,
|
||||
"ApiUrl": "https://api.pschneider.fr/api/v1/",
|
||||
"Authentication": {
|
||||
"Authority": "https://localhost:5001",
|
||||
"ClientId": "postit",
|
||||
"Scopes": [
|
||||
"openid",
|
||||
"profile",
|
||||
"offline_access",
|
||||
"blogs"
|
||||
]
|
||||
}
|
||||
"blogs",
|
||||
"api"
|
||||
],
|
||||
"RedirectUri": "postit://callback"
|
||||
},
|
||||
"DarkMode": true,
|
||||
"BlogsApiUrl": "https://localhost:5003/api/v1/",
|
||||
"ApiUrl": "https://localhost:5005/api/v1/",
|
||||
"SearchText": "",
|
||||
"ProviderOngoingRequestsSortOption": "",
|
||||
"Loaded": true,
|
||||
"IsDirty": true,
|
||||
"CanNavigateNext": false,
|
||||
"CanNavigatePrevious": true,
|
||||
"SaveCommand": {}
|
||||
}
|
||||
|
|
@ -114,7 +114,7 @@ public sealed class BillingControllerTests : IClassFixture<ApiWebServerFixture>
|
|||
var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
||||
|
||||
db.Database.ExecuteSqlInterpolated($@"
|
||||
INSERT INTO ""NominativeServiceCommand""
|
||||
INSERT INTO ""NominativeServiceCommands""
|
||||
(""ActivityCode"", ""ClientId"", ""Consent"", ""DateCreated"", ""DateModified"", ""Description"", ""Discriminator"", ""PerformerId"", ""Status"", ""UserCreated"", ""UserModified"")
|
||||
VALUES
|
||||
({"dev"}, {"bob"}, {true}, {DateTime.UtcNow.AddMinutes(-5)}, {DateTime.UtcNow.AddMinutes(-4)}, {"Legacy malformed row"}, {""}, {"alice"}, {(int)QueryStatus.Accepted}, {"alice"}, {"alice"});
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ public sealed class EstimateApiControllerTests : IClassFixture<ApiWebServerFixtu
|
|||
|
||||
var response = await http.PostAsJsonAsync(
|
||||
"/api/v1/estimate",
|
||||
NewEstimatePayload(commandId, clientId: "bob", ownerId: "alice"),
|
||||
NewEstimatePayload(commandId, clientId: "bob"),
|
||||
TestContext.Current.CancellationToken);
|
||||
var body = await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using Npgsql;
|
|||
using Yavsc.Controllers;
|
||||
using Yavsc.Interfaces.Workflow;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Billing;
|
||||
using Yavsc.Models.Google.Messaging;
|
||||
using Yavsc.Models.Haircut;
|
||||
using Yavsc.Models.Messaging;
|
||||
|
|
@ -38,7 +39,8 @@ public sealed class ApiWebServerFixture : WebHostFixture
|
|||
{
|
||||
var npgsqlConnectionString = EnsureNpgsqlDatabaseCreated();
|
||||
builder.Services.AddDbContext<ApplicationDbContext>(opt =>
|
||||
opt.UseNpgsql(npgsqlConnectionString));
|
||||
opt.UseNpgsql(npgsqlConnectionString,
|
||||
x => x.MigrationsAssembly("Yavsc.Org")));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -99,7 +101,18 @@ public sealed class ApiWebServerFixture : WebHostFixture
|
|||
using (var scope = app.Services.CreateScope())
|
||||
{
|
||||
var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
||||
db.Database.EnsureCreated();
|
||||
if (UseNpgsqlProvider())
|
||||
{
|
||||
// Apply the EF Core migrations (Yavsc.Org assembly) so the
|
||||
// test database schema matches the production provider.
|
||||
// EnsureCreated must not be used here: it would create the
|
||||
// schema without the migrations history and break Migrate().
|
||||
db.Database.Migrate();
|
||||
}
|
||||
else
|
||||
{
|
||||
db.Database.EnsureCreated();
|
||||
}
|
||||
}
|
||||
|
||||
await Task.CompletedTask;
|
||||
|
|
@ -303,17 +316,23 @@ public sealed class ApiWebServerFixture : WebHostFixture
|
|||
{
|
||||
if (UseNpgsqlProvider())
|
||||
{
|
||||
db.Set<UserActivity>().RemoveRange(db.Set<UserActivity>());
|
||||
db.Set<Activity>().RemoveRange(db.Set<Activity>());
|
||||
db.Set<PerformerProfile>().RemoveRange(db.Set<PerformerProfile>());
|
||||
db.Set<ApplicationUser>().RemoveRange(db.Set<ApplicationUser>());
|
||||
db.Set<Location>().RemoveRange(db.Set<Location>());
|
||||
db.Set<RdvQuery>().RemoveRange(db.Set<RdvQuery>());
|
||||
db.Set<HairCutQuery>().RemoveRange(db.Set<HairCutQuery>());
|
||||
db.Set<HairMultiCutQuery>().RemoveRange(db.Set<HairMultiCutQuery>());
|
||||
db.Set<HairPrestation>().RemoveRange(db.Set<HairPrestation>());
|
||||
db.Set<HairPrestationCollectionItem>().RemoveRange(db.Set<HairPrestationCollectionItem>());
|
||||
|
||||
// Purge only the tables of the test graph, children before
|
||||
// parents, so no DELETE violates a foreign key. Estimate and
|
||||
// CommandLine reference NominativeServiceCommand (CommandId) and
|
||||
// must be deleted before the Rdv/HairCut/HairMultiCut queries.
|
||||
db.Set<CommandLine>().RemoveRange(db.Set<CommandLine>());
|
||||
db.Set<Estimate>().RemoveRange(db.Set<Estimate>());
|
||||
db.Set<RdvQuery>().RemoveRange(db.Set<RdvQuery>());
|
||||
db.Set<HairCutQuery>().RemoveRange(db.Set<HairCutQuery>());
|
||||
db.Set<HairMultiCutQuery>().RemoveRange(db.Set<HairMultiCutQuery>());
|
||||
db.Set<HairPrestationCollectionItem>().RemoveRange(db.Set<HairPrestationCollectionItem>());
|
||||
db.Set<HairPrestation>().RemoveRange(db.Set<HairPrestation>());
|
||||
db.Set<UserActivity>().RemoveRange(db.Set<UserActivity>());
|
||||
db.Set<PerformerProfile>().RemoveRange(db.Set<PerformerProfile>());
|
||||
db.Set<Activity>().RemoveRange(db.Set<Activity>());
|
||||
db.Set<ApplicationUser>().RemoveRange(db.Set<ApplicationUser>());
|
||||
db.Set<Location>().RemoveRange(db.Set<Location>());
|
||||
|
||||
db.SaveChanges();
|
||||
return;
|
||||
}
|
||||
|
|
@ -321,72 +340,6 @@ public sealed class ApiWebServerFixture : WebHostFixture
|
|||
db.Database.EnsureDeleted();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static IReadOnlyList<IEntityType> GetDeletionOrder(IModel model)
|
||||
{
|
||||
var entityTypes = model
|
||||
.GetEntityTypes()
|
||||
.Where(et =>
|
||||
et.ClrType is not null &&
|
||||
!et.IsOwned() &&
|
||||
et.FindPrimaryKey() is not null)
|
||||
.ToArray();
|
||||
|
||||
var included = new HashSet<IEntityType>(entityTypes);
|
||||
var dependencies = new Dictionary<IEntityType, HashSet<IEntityType>>();
|
||||
|
||||
foreach (var entityType in entityTypes)
|
||||
{
|
||||
var principals = entityType
|
||||
.GetForeignKeys()
|
||||
.Where(fk => !fk.IsOwnership)
|
||||
.Select(fk => fk.PrincipalEntityType)
|
||||
.Where(included.Contains)
|
||||
.ToHashSet();
|
||||
|
||||
dependencies[entityType] = principals;
|
||||
}
|
||||
|
||||
var queue = new Queue<IEntityType>(
|
||||
dependencies.Where(kvp => kvp.Value.Count == 0).Select(kvp => kvp.Key));
|
||||
|
||||
var order = new List<IEntityType>(entityTypes.Length);
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
var current = queue.Dequeue();
|
||||
if (!order.Contains(current))
|
||||
{
|
||||
order.Add(current);
|
||||
}
|
||||
|
||||
foreach (var kvp in dependencies)
|
||||
{
|
||||
if (!kvp.Value.Remove(current) || kvp.Value.Count != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!order.Contains(kvp.Key) && !queue.Contains(kvp.Key))
|
||||
{
|
||||
queue.Enqueue(kvp.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If cycles remain (rare), append unresolved types last and rely on DB cascades.
|
||||
foreach (var entityType in entityTypes)
|
||||
{
|
||||
if (!order.Contains(entityType))
|
||||
{
|
||||
order.Add(entityType);
|
||||
}
|
||||
}
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
public void ResetAndSeedRdvQueryGraph()
|
||||
{
|
||||
ResetAndSeedActivityGraph();
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ namespace Yavsc.Controllers
|
|||
|
||||
if (estimate.CommandId != null)
|
||||
{
|
||||
var query = _context.Set<NominativeServiceCommand>()
|
||||
var query = _context.NominativeServiceCommands
|
||||
.FirstOrDefault(q => q.Id == estimate.CommandId);
|
||||
if (query == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "https://localhost:6001",
|
||||
"sslPort": 6001
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": false,
|
||||
"applicationUrl": "https://localhost:6001",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"Site": {
|
||||
"Authority": "https://localhost:5001",
|
||||
"Audience": ["api"],
|
||||
"CorsAllowedOrigins": [
|
||||
"https://localhost:5003",
|
||||
"https://yavsc.pschneider.fr"
|
||||
|
|
|
|||
4714
src/Yavsc.Org/Migrations/20260913191414_NominativeServiceCommand.Designer.cs
generated
Normal file
4714
src/Yavsc.Org/Migrations/20260913191414_NominativeServiceCommand.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,423 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Yavsc.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class NominativeServiceCommand : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Estimates_NominativeServiceCommand_CommandId",
|
||||
table: "Estimates");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_HairPrestationCollectionItem_NominativeServiceCommand_Query~",
|
||||
table: "HairPrestationCollectionItem");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NominativeServiceCommand_Activities_ActivityCode",
|
||||
table: "NominativeServiceCommand");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NominativeServiceCommand_AspNetUsers_ClientId",
|
||||
table: "NominativeServiceCommand");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NominativeServiceCommand_BrusherProfile_SelectedProfileUser~",
|
||||
table: "NominativeServiceCommand");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NominativeServiceCommand_GitRepositoryReference_GitId",
|
||||
table: "NominativeServiceCommand");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NominativeServiceCommand_HairPrestation_PrestationId",
|
||||
table: "NominativeServiceCommand");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NominativeServiceCommand_Locations_HairMultiCutQuery_Locati~",
|
||||
table: "NominativeServiceCommand");
|
||||
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NominativeServiceCommand_Locations_RdvQuery_LocationId",
|
||||
table: "NominativeServiceCommand");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NominativeServiceCommand_PayPalPayment_PaymentId",
|
||||
table: "NominativeServiceCommand");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NominativeServiceCommand_Performers_PerformerId",
|
||||
table: "NominativeServiceCommand");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_ProjectBuildConfiguration_NominativeServiceCommand_ProjectId",
|
||||
table: "ProjectBuildConfiguration");
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_NominativeServiceCommand",
|
||||
table: "NominativeServiceCommand");
|
||||
|
||||
migrationBuilder.RenameTable(
|
||||
name: "NominativeServiceCommand",
|
||||
newName: "NominativeServiceCommands");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_NominativeServiceCommand_SelectedProfileUserId",
|
||||
table: "NominativeServiceCommands",
|
||||
newName: "IX_NominativeServiceCommands_SelectedProfileUserId");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_NominativeServiceCommand_RdvQuery_LocationId",
|
||||
table: "NominativeServiceCommands",
|
||||
newName: "IX_NominativeServiceCommands_RdvQuery_LocationId");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_NominativeServiceCommand_PrestationId",
|
||||
table: "NominativeServiceCommands",
|
||||
newName: "IX_NominativeServiceCommands_PrestationId");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_NominativeServiceCommand_PerformerId",
|
||||
table: "NominativeServiceCommands",
|
||||
newName: "IX_NominativeServiceCommands_PerformerId");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_NominativeServiceCommand_PaymentId",
|
||||
table: "NominativeServiceCommands",
|
||||
newName: "IX_NominativeServiceCommands_PaymentId");
|
||||
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_NominativeServiceCommand_HairMultiCutQuery_LocationId",
|
||||
table: "NominativeServiceCommands",
|
||||
newName: "IX_NominativeServiceCommands_HairMultiCutQuery_LocationId");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_NominativeServiceCommand_GitId",
|
||||
table: "NominativeServiceCommands",
|
||||
newName: "IX_NominativeServiceCommands_GitId");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_NominativeServiceCommand_ClientId",
|
||||
table: "NominativeServiceCommands",
|
||||
newName: "IX_NominativeServiceCommands_ClientId");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_NominativeServiceCommand_ActivityCode",
|
||||
table: "NominativeServiceCommands",
|
||||
newName: "IX_NominativeServiceCommands_ActivityCode");
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_NominativeServiceCommands",
|
||||
table: "NominativeServiceCommands",
|
||||
column: "Id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Estimates_NominativeServiceCommands_CommandId",
|
||||
table: "Estimates",
|
||||
column: "CommandId",
|
||||
principalTable: "NominativeServiceCommands",
|
||||
principalColumn: "Id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_HairPrestationCollectionItem_NominativeServiceCommands_Quer~",
|
||||
table: "HairPrestationCollectionItem",
|
||||
column: "QueryId",
|
||||
principalTable: "NominativeServiceCommands",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NominativeServiceCommands_Activities_ActivityCode",
|
||||
table: "NominativeServiceCommands",
|
||||
column: "ActivityCode",
|
||||
principalTable: "Activities",
|
||||
principalColumn: "Code",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NominativeServiceCommands_AspNetUsers_ClientId",
|
||||
table: "NominativeServiceCommands",
|
||||
column: "ClientId",
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NominativeServiceCommands_BrusherProfile_SelectedProfileUse~",
|
||||
table: "NominativeServiceCommands",
|
||||
column: "SelectedProfileUserId",
|
||||
principalTable: "BrusherProfile",
|
||||
principalColumn: "UserId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NominativeServiceCommands_GitRepositoryReference_GitId",
|
||||
table: "NominativeServiceCommands",
|
||||
column: "GitId",
|
||||
principalTable: "GitRepositoryReference",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NominativeServiceCommands_HairPrestation_PrestationId",
|
||||
table: "NominativeServiceCommands",
|
||||
column: "PrestationId",
|
||||
principalTable: "HairPrestation",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NominativeServiceCommands_Locations_HairMultiCutQuery_Locat~",
|
||||
table: "NominativeServiceCommands",
|
||||
column: "HairMultiCutQuery_LocationId",
|
||||
principalTable: "Locations",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NominativeServiceCommands_Locations_RdvQuery_LocationId",
|
||||
table: "NominativeServiceCommands",
|
||||
column: "RdvQuery_LocationId",
|
||||
principalTable: "Locations",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NominativeServiceCommands_PayPalPayment_PaymentId",
|
||||
table: "NominativeServiceCommands",
|
||||
column: "PaymentId",
|
||||
principalTable: "PayPalPayment",
|
||||
principalColumn: "CreationToken");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NominativeServiceCommands_Performers_PerformerId",
|
||||
table: "NominativeServiceCommands",
|
||||
column: "PerformerId",
|
||||
principalTable: "Performers",
|
||||
principalColumn: "PerformerId",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_ProjectBuildConfiguration_NominativeServiceCommands_Project~",
|
||||
table: "ProjectBuildConfiguration",
|
||||
column: "ProjectId",
|
||||
principalTable: "NominativeServiceCommands",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Estimates_NominativeServiceCommands_CommandId",
|
||||
table: "Estimates");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_HairPrestationCollectionItem_NominativeServiceCommands_Quer~",
|
||||
table: "HairPrestationCollectionItem");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NominativeServiceCommands_Activities_ActivityCode",
|
||||
table: "NominativeServiceCommands");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NominativeServiceCommands_AspNetUsers_ClientId",
|
||||
table: "NominativeServiceCommands");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NominativeServiceCommands_BrusherProfile_SelectedProfileUse~",
|
||||
table: "NominativeServiceCommands");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NominativeServiceCommands_GitRepositoryReference_GitId",
|
||||
table: "NominativeServiceCommands");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NominativeServiceCommands_HairPrestation_PrestationId",
|
||||
table: "NominativeServiceCommands");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NominativeServiceCommands_Locations_HairMultiCutQuery_Locat~",
|
||||
table: "NominativeServiceCommands");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NominativeServiceCommands_Locations_LocationId",
|
||||
table: "NominativeServiceCommands");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NominativeServiceCommands_Locations_RdvQuery_LocationId",
|
||||
table: "NominativeServiceCommands");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NominativeServiceCommands_PayPalPayment_PaymentId",
|
||||
table: "NominativeServiceCommands");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NominativeServiceCommands_Performers_PerformerId",
|
||||
table: "NominativeServiceCommands");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_ProjectBuildConfiguration_NominativeServiceCommands_Project~",
|
||||
table: "ProjectBuildConfiguration");
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_NominativeServiceCommands",
|
||||
table: "NominativeServiceCommands");
|
||||
|
||||
migrationBuilder.RenameTable(
|
||||
name: "NominativeServiceCommands",
|
||||
newName: "NominativeServiceCommand");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_NominativeServiceCommands_SelectedProfileUserId",
|
||||
table: "NominativeServiceCommand",
|
||||
newName: "IX_NominativeServiceCommand_SelectedProfileUserId");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_NominativeServiceCommands_RdvQuery_LocationId",
|
||||
table: "NominativeServiceCommand",
|
||||
newName: "IX_NominativeServiceCommand_RdvQuery_LocationId");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_NominativeServiceCommands_PrestationId",
|
||||
table: "NominativeServiceCommand",
|
||||
newName: "IX_NominativeServiceCommand_PrestationId");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_NominativeServiceCommands_PerformerId",
|
||||
table: "NominativeServiceCommand",
|
||||
newName: "IX_NominativeServiceCommand_PerformerId");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_NominativeServiceCommands_PaymentId",
|
||||
table: "NominativeServiceCommand",
|
||||
newName: "IX_NominativeServiceCommand_PaymentId");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_NominativeServiceCommands_HairMultiCutQuery_LocationId",
|
||||
table: "NominativeServiceCommand",
|
||||
newName: "IX_NominativeServiceCommand_HairMultiCutQuery_LocationId");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_NominativeServiceCommands_GitId",
|
||||
table: "NominativeServiceCommand",
|
||||
newName: "IX_NominativeServiceCommand_GitId");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_NominativeServiceCommands_ClientId",
|
||||
table: "NominativeServiceCommand",
|
||||
newName: "IX_NominativeServiceCommand_ClientId");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_NominativeServiceCommands_ActivityCode",
|
||||
table: "NominativeServiceCommand",
|
||||
newName: "IX_NominativeServiceCommand_ActivityCode");
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_NominativeServiceCommand",
|
||||
table: "NominativeServiceCommand",
|
||||
column: "Id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Estimates_NominativeServiceCommand_CommandId",
|
||||
table: "Estimates",
|
||||
column: "CommandId",
|
||||
principalTable: "NominativeServiceCommand",
|
||||
principalColumn: "Id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_HairPrestationCollectionItem_NominativeServiceCommand_Query~",
|
||||
table: "HairPrestationCollectionItem",
|
||||
column: "QueryId",
|
||||
principalTable: "NominativeServiceCommand",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NominativeServiceCommand_Activities_ActivityCode",
|
||||
table: "NominativeServiceCommand",
|
||||
column: "ActivityCode",
|
||||
principalTable: "Activities",
|
||||
principalColumn: "Code",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NominativeServiceCommand_AspNetUsers_ClientId",
|
||||
table: "NominativeServiceCommand",
|
||||
column: "ClientId",
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NominativeServiceCommand_BrusherProfile_SelectedProfileUser~",
|
||||
table: "NominativeServiceCommand",
|
||||
column: "SelectedProfileUserId",
|
||||
principalTable: "BrusherProfile",
|
||||
principalColumn: "UserId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NominativeServiceCommand_GitRepositoryReference_GitId",
|
||||
table: "NominativeServiceCommand",
|
||||
column: "GitId",
|
||||
principalTable: "GitRepositoryReference",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NominativeServiceCommand_HairPrestation_PrestationId",
|
||||
table: "NominativeServiceCommand",
|
||||
column: "PrestationId",
|
||||
principalTable: "HairPrestation",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NominativeServiceCommand_Locations_HairMultiCutQuery_Locati~",
|
||||
table: "NominativeServiceCommand",
|
||||
column: "HairMultiCutQuery_LocationId",
|
||||
principalTable: "Locations",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NominativeServiceCommand_Locations_RdvQuery_LocationId",
|
||||
table: "NominativeServiceCommand",
|
||||
column: "RdvQuery_LocationId",
|
||||
principalTable: "Locations",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NominativeServiceCommand_PayPalPayment_PaymentId",
|
||||
table: "NominativeServiceCommand",
|
||||
column: "PaymentId",
|
||||
principalTable: "PayPalPayment",
|
||||
principalColumn: "CreationToken");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NominativeServiceCommand_Performers_PerformerId",
|
||||
table: "NominativeServiceCommand",
|
||||
column: "PerformerId",
|
||||
principalTable: "Performers",
|
||||
principalColumn: "PerformerId",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_ProjectBuildConfiguration_NominativeServiceCommand_ProjectId",
|
||||
table: "ProjectBuildConfiguration",
|
||||
column: "ProjectId",
|
||||
principalTable: "NominativeServiceCommand",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Yavsc.Models;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Yavsc.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20260913220000_AddHairCutQueryLocationId")]
|
||||
public partial class AddHairCutQueryLocationId : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<long>(
|
||||
name: "LocationId",
|
||||
table: "NominativeServiceCommands",
|
||||
type: "bigint",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_NominativeServiceCommands_LocationId",
|
||||
table: "NominativeServiceCommands",
|
||||
column: "LocationId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NominativeServiceCommands_Locations_LocationId",
|
||||
table: "NominativeServiceCommands",
|
||||
column: "LocationId",
|
||||
principalTable: "Locations",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NominativeServiceCommands_Locations_LocationId",
|
||||
table: "NominativeServiceCommands");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_NominativeServiceCommands_LocationId",
|
||||
table: "NominativeServiceCommands");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "LocationId",
|
||||
table: "NominativeServiceCommands");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1495,7 +1495,7 @@ namespace Yavsc.Migrations
|
|||
|
||||
b.HasIndex("PerformerId");
|
||||
|
||||
b.ToTable("NominativeServiceCommand");
|
||||
b.ToTable("NominativeServiceCommands");
|
||||
|
||||
b.HasDiscriminator<string>("Discriminator").HasValue("NominativeServiceCommand");
|
||||
|
||||
|
|
@ -3336,7 +3336,7 @@ namespace Yavsc.Migrations
|
|||
|
||||
b.HasIndex("LocationId");
|
||||
|
||||
b.ToTable("NominativeServiceCommand", t =>
|
||||
b.ToTable("NominativeServiceCommands", t =>
|
||||
{
|
||||
t.Property("EventDate")
|
||||
.HasColumnName("HairMultiCutQuery_EventDate");
|
||||
|
|
@ -3367,7 +3367,7 @@ namespace Yavsc.Migrations
|
|||
|
||||
b.HasIndex("LocationId");
|
||||
|
||||
b.ToTable("NominativeServiceCommand", t =>
|
||||
b.ToTable("NominativeServiceCommands", t =>
|
||||
{
|
||||
t.Property("EventDate")
|
||||
.HasColumnName("RdvQuery_EventDate");
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"Slogan": "Yavsc!",
|
||||
"StyleSheet": "/css/default.css",
|
||||
"Authority": "https://[Your domaine name]",
|
||||
"Audience": ["blogs"],
|
||||
"Audience": ["blogs", "api"],
|
||||
"ExternalUrl": "https://[Your domaine name]",
|
||||
"ApiUrl": "https://[Your API domaine name]",
|
||||
"CorsAllowedOrigins": [
|
||||
|
|
|
|||
|
|
@ -507,5 +507,7 @@ namespace Yavsc.Models
|
|||
public DbSet<RegexAlertPattern> RegexAlertPatterns { get; set; }
|
||||
|
||||
public DbSet<ModerationLog> ModerationLogs { get; set; }
|
||||
|
||||
public DbSet<NominativeServiceCommand> NominativeServiceCommands { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue