diff --git a/docs/schema/V1/schema.verified.graphql b/docs/schema/V1/schema.verified.graphql index c8802fdfa..162790668 100644 --- a/docs/schema/V1/schema.verified.graphql +++ b/docs/schema/V1/schema.verified.graphql @@ -127,7 +127,7 @@ type GuiAction { type Localization { value: String! - cultureCode: String! + languageCode: String! } type Queries @authorize(policy: "enduser") { @@ -205,8 +205,8 @@ input SearchDialogInput { dueBefore: DateTime "Search string for free text search. Will attempt to fuzzily match in all free text fields in the aggregate" search: String - "Limit free text search to texts with this culture code, e.g. \"nb-NO\". Default: search all culture codes" - searchCultureCode: String + "Limit free text search to texts with this language code, e.g. 'no', 'en'. Culture codes will be normalized to neutral language codes (ISO 639). Default: search all culture codes" + searchLanguageCode: String } enum ActivityType { diff --git a/docs/schema/V1/swagger.verified.json b/docs/schema/V1/swagger.verified.json index 25b33e8e2..76baa9897 100644 --- a/docs/schema/V1/swagger.verified.json +++ b/docs/schema/V1/swagger.verified.json @@ -227,7 +227,7 @@ "Value": [ { "Value": "Some Title", - "CultureCode": "en-us" + "LanguageCode": "en" } ], "MediaType": null @@ -237,7 +237,7 @@ "Value": [ { "Value": "Some Summary", - "CultureCode": "en-us" + "LanguageCode": "en" } ], "MediaType": null @@ -257,7 +257,7 @@ "DisplayName": [ { "Value": "Some display name", - "CultureCode": "en-us" + "LanguageCode": "en" } ], "Urls": [ @@ -282,11 +282,11 @@ "Title": [ { "Value": "GUI action title", - "CultureCode": "en-us" + "LanguageCode": "en" }, { "Value": "GUI action-tittel", - "CultureCode": "nb-no" + "LanguageCode": "nb" } ], "Prompt": null @@ -323,11 +323,11 @@ "Description": [ { "Value": "Some description", - "CultureCode": "en-us" + "LanguageCode": "en" }, { "Value": "En beskrivelse", - "CultureCode": "nb-no" + "LanguageCode": "nb" } ] } @@ -786,9 +786,9 @@ } }, { - "name": "searchCultureCode", + "name": "searchLanguageCode", "in": "query", - "description": "Limit free text search to texts with this culture code, e.g. \\\"nb-NO\\\". Default: search all culture codes", + "description": "Limit free text search to texts with this language code, e.g. 'no', 'en'. Culture codes will be normalized to neutral language codes (ISO 639). Default: search all culture codes", "schema": { "type": "string", "nullable": true @@ -1503,9 +1503,9 @@ } }, { - "name": "searchCultureCode", + "name": "searchLanguageCode", "in": "query", - "description": "Limit free text search to texts with this culture code, e.g. \\\"nb-NO\\\". Default: search all culture codes", + "description": "Limit free text search to texts with this language code, e.g. 'no', 'en'. Culture codes will be normalized to neutral language codes (ISO 639). Default: search all culture codes", "schema": { "type": "string", "nullable": true @@ -2024,7 +2024,7 @@ "value": { "type": "string" }, - "cultureCode": { + "languageCode": { "type": "string" } } diff --git a/src/Digdir.Domain.Dialogporten.Application/Common/Expressions.cs b/src/Digdir.Domain.Dialogporten.Application/Common/Expressions.cs index ecf0d3026..fefec0974 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Common/Expressions.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Common/Expressions.cs @@ -12,10 +12,10 @@ internal static Expression> Or(Expression> expr1, return Expression.Lambda>(Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters); } - internal static Expression> LocalizedSearchExpression(string? search, string? cultureCode) + internal static Expression> LocalizedSearchExpression(string? search, string? languageCode) { return localization => - (cultureCode == null || localization.CultureCode == cultureCode) && + (languageCode == null || localization.LanguageCode == languageCode) && EF.Functions.ILike(localization.Value, $"%{search}%"); } } diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/Common/Localizations/LocalizationDto.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/Common/Localizations/LocalizationDto.cs index de594fe7f..a6934f8cd 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/Common/Localizations/LocalizationDto.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/Common/Localizations/LocalizationDto.cs @@ -4,12 +4,12 @@ namespace Digdir.Domain.Dialogporten.Application.Features.V1.Common.Localization public sealed class LocalizationDto { - private readonly string _cultureCode = null!; + private readonly string _languageCode = null!; public required string Value { get; init; } - public required string CultureCode + public required string LanguageCode { - get => _cultureCode; - init => _cultureCode = Localization.NormalizeCultureCode(value)!; + get => _languageCode; + init => _languageCode = Localization.NormalizeCultureCode(value)!; } } diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/Common/Localizations/LocalizationDtoValidator.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/Common/Localizations/LocalizationDtoValidator.cs index ba0368bc6..bfb269b89 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/Common/Localizations/LocalizationDtoValidator.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/Common/Localizations/LocalizationDtoValidator.cs @@ -4,30 +4,58 @@ namespace Digdir.Domain.Dialogporten.Application.Features.V1.Common.Localizations; +internal static class LocalizationValidatorContants +{ + public const int MaximumLength = 255; + + public const string NormalizationErrorMessage = + "Culture specific codes like 'en_GB' and 'en-US' are normalized to 'en' (ISO 639)."; + + public const string InvalidCultureCodeErrorMessageWithNorwegianHint = + InvalidCultureCodeErrorMessage + "Use 'nb' or 'nn' for Norwegian. "; + + public const string InvalidCultureCodeErrorMessage = + "'{PropertyName}' '{PropertyValue}' is not a valid language code. "; +} + internal sealed class LocalizationDtosValidator : AbstractValidator> { - public LocalizationDtosValidator(int maximumLength = 255) + public LocalizationDtosValidator(int maximumLength = LocalizationValidatorContants.MaximumLength) { RuleFor(x => x) - .UniqueBy(x => x.CultureCode) + .UniqueBy(x => x.LanguageCode) + .WithMessage(localizations => + { + var duplicates = localizations + .GroupBy(y => y.LanguageCode) + .Where(g => g.Count() > 1) + .Select(g => g.Key); + + return $"Can not contain duplicate items: [{string.Join(", ", duplicates)}]. " + + $"{LocalizationValidatorContants.NormalizationErrorMessage}"; + }) .ForEach(x => x.SetValidator(new LocalizationDtoValidator(maximumLength))); } } internal sealed class LocalizationDtoValidator : AbstractValidator { - public LocalizationDtoValidator(int maximumLength = 255) + public LocalizationDtoValidator(int maximumLength = LocalizationValidatorContants.MaximumLength) { - RuleFor(x => x).NotNull(); + RuleFor(x => x) + .NotNull(); RuleFor(x => x.Value) .NotEmpty() - .NotNull() .MaximumLength(maximumLength); - RuleFor(x => x.CultureCode) + RuleFor(x => x.LanguageCode) .NotEmpty() - .Must(x => x is null || Localization.IsValidCultureCode(x)) - .WithMessage("'{PropertyName}' must be a valid culture code."); + .Must(Localization.IsValidCultureCode) + .WithMessage(localization => + (localization.LanguageCode == "no" + ? LocalizationValidatorContants.InvalidCultureCodeErrorMessageWithNorwegianHint + : LocalizationValidatorContants.InvalidCultureCodeErrorMessage) + + LocalizationValidatorContants.NormalizationErrorMessage); } } diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/Common/Localizations/LocalizationSetConverter.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/Common/Localizations/LocalizationSetConverter.cs index 49bb2e8bc..eaa94393d 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/Common/Localizations/LocalizationSetConverter.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/Common/Localizations/LocalizationSetConverter.cs @@ -18,8 +18,8 @@ internal sealed class LocalizationSetConverter : ITypeConverte set ??= new TLocalizationSet(); set.Localizations.Merge( sources: concreteDtos, - destinationKeySelector: x => x.CultureCode, - sourceKeySelector: x => x.CultureCode, + destinationKeySelector: x => x.LanguageCode, + sourceKeySelector: x => x.LanguageCode, create: context.Mapper.Map>, update: context.Mapper.Update, delete: DeleteDelegate.NoOp, diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/Common/Localizations/MappingProfile.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/Common/Localizations/MappingProfile.cs index 49c177bec..0ae750e7b 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/Common/Localizations/MappingProfile.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/Common/Localizations/MappingProfile.cs @@ -11,7 +11,7 @@ public MappingProfile() CreateMap?>() .ConvertUsing(src => src == null ? null : src.Localizations - .Select(x => new LocalizationDto { CultureCode = x.CultureCode, Value = x.Value }) + .Select(x => new LocalizationDto { LanguageCode = x.LanguageCode, Value = x.Value }) .ToList()); // In diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/EndUser/Dialogs/Queries/Get/GetDialogQuery.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/EndUser/Dialogs/Queries/Get/GetDialogQuery.cs index f6380a37c..06c2b03c9 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/EndUser/Dialogs/Queries/Get/GetDialogQuery.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/EndUser/Dialogs/Queries/Get/GetDialogQuery.cs @@ -61,15 +61,15 @@ public async Task Handle(GetDialogQuery request, CancellationTo // layer behaviours in an expected manner. Therefore, we need to be a bit more verbose about it. var dialog = await _db.Dialogs .Include(x => x.Content.OrderBy(x => x.Id).ThenBy(x => x.CreatedAt)) - .ThenInclude(x => x.Value.Localizations.OrderBy(x => x.CreatedAt).ThenBy(x => x.CultureCode)) + .ThenInclude(x => x.Value.Localizations.OrderBy(x => x.CreatedAt).ThenBy(x => x.LanguageCode)) .Include(x => x.Attachments.OrderBy(x => x.CreatedAt).ThenBy(x => x.Id)) - .ThenInclude(x => x.DisplayName!.Localizations.OrderBy(x => x.CreatedAt).ThenBy(x => x.CultureCode)) + .ThenInclude(x => x.DisplayName!.Localizations.OrderBy(x => x.CreatedAt).ThenBy(x => x.LanguageCode)) .Include(x => x.Attachments.OrderBy(x => x.CreatedAt).ThenBy(x => x.Id)) .ThenInclude(x => x.Urls.OrderBy(x => x.CreatedAt).ThenBy(x => x.Id)) .Include(x => x.GuiActions.OrderBy(x => x.CreatedAt).ThenBy(x => x.Id)) - .ThenInclude(x => x.Title!.Localizations.OrderBy(x => x.CreatedAt).ThenBy(x => x.CultureCode)) + .ThenInclude(x => x.Title!.Localizations.OrderBy(x => x.CreatedAt).ThenBy(x => x.LanguageCode)) .Include(x => x.GuiActions.OrderBy(x => x.CreatedAt).ThenBy(x => x.Id)) - .ThenInclude(x => x!.Prompt!.Localizations.OrderBy(x => x.CreatedAt).ThenBy(x => x.CultureCode)) + .ThenInclude(x => x!.Prompt!.Localizations.OrderBy(x => x.CreatedAt).ThenBy(x => x.LanguageCode)) .Include(x => x.ApiActions.OrderBy(x => x.CreatedAt).ThenBy(x => x.Id)) .ThenInclude(x => x.Endpoints.OrderBy(x => x.CreatedAt).ThenBy(x => x.Id)) .Include(x => x.Activities).ThenInclude(x => x.Description!.Localizations) diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/EndUser/Dialogs/Queries/Search/SearchDialogQuery.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/EndUser/Dialogs/Queries/Search/SearchDialogQuery.cs index 72a0d7b0e..27e31e817 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/EndUser/Dialogs/Queries/Search/SearchDialogQuery.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/EndUser/Dialogs/Queries/Search/SearchDialogQuery.cs @@ -19,7 +19,7 @@ namespace Digdir.Domain.Dialogporten.Application.Features.V1.EndUser.Dialogs.Que public sealed class SearchDialogQuery : SortablePaginationParameter, IRequest { - private readonly string? _searchCultureCode; + private readonly string? _searchLanguageCode; /// /// Filter by one or more service owner codes @@ -87,12 +87,12 @@ public sealed class SearchDialogQuery : SortablePaginationParameter - /// Limit free text search to texts with this culture code, e.g. \"nb-NO\". Default: search all culture codes + /// Limit free text search to texts with this language code, e.g. 'no', 'en'. Culture codes will be normalized to neutral language codes (ISO 639). Default: search all culture codes /// - public string? SearchCultureCode + public string? SearchLanguageCode { - get => _searchCultureCode; - init => _searchCultureCode = Localization.NormalizeCultureCode(value); + get => _searchLanguageCode; + init => _searchLanguageCode = Localization.NormalizeCultureCode(value); } } @@ -138,7 +138,7 @@ public async Task Handle(SearchDialogQuery request, Cancella { var currentUserInfo = await _userRegistry.GetCurrentUserInformation(cancellationToken); - var searchExpression = Expressions.LocalizedSearchExpression(request.Search, request.SearchCultureCode); + var searchExpression = Expressions.LocalizedSearchExpression(request.Search, request.SearchLanguageCode); var authorizedResources = await _altinnAuthorization.GetAuthorizedResourcesForSearch( request.Party ?? [], request.ServiceResource ?? [], diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/EndUser/Dialogs/Queries/Search/SearchDialogQueryValidator.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/EndUser/Dialogs/Queries/Search/SearchDialogQueryValidator.cs index a260a749b..a93a6e803 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/EndUser/Dialogs/Queries/Search/SearchDialogQueryValidator.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/EndUser/Dialogs/Queries/Search/SearchDialogQueryValidator.cs @@ -1,6 +1,7 @@ using Digdir.Domain.Dialogporten.Application.Common.Extensions.Enumerables; using Digdir.Domain.Dialogporten.Application.Common.Extensions.FluentValidation; using Digdir.Domain.Dialogporten.Application.Common.Pagination; +using Digdir.Domain.Dialogporten.Application.Features.V1.Common.Localizations; using Digdir.Domain.Dialogporten.Domain.Localizations; using FluentValidation; @@ -15,9 +16,13 @@ public SearchDialogQueryValidator() .MinimumLength(3) .When(x => x.Search is not null); - RuleFor(x => x.SearchCultureCode) + RuleFor(x => x.SearchLanguageCode) .Must(x => x is null || Localization.IsValidCultureCode(x)) - .WithMessage("'{PropertyName}' must be a valid culture code."); + .WithMessage(searchQuery => + (searchQuery.SearchLanguageCode == "no" + ? LocalizationValidatorContants.InvalidCultureCodeErrorMessageWithNorwegianHint + : LocalizationValidatorContants.InvalidCultureCodeErrorMessage) + + LocalizationValidatorContants.NormalizationErrorMessage); RuleFor(x => x) .Must(x => !x.ServiceResource.IsNullOrEmpty() || !x.Party.IsNullOrEmpty()) diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Queries/Get/GetDialogQuery.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Queries/Get/GetDialogQuery.cs index 8bdee1f60..da6c67986 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Queries/Get/GetDialogQuery.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Queries/Get/GetDialogQuery.cs @@ -46,16 +46,16 @@ public async Task Handle(GetDialogQuery request, CancellationTo // layer behaviours in an expected manner. Therefore we need to be a bit more verbose about it. var dialog = await _db.Dialogs .Include(x => x.Content.OrderBy(x => x.Id).ThenBy(x => x.CreatedAt)) - .ThenInclude(x => x.Value.Localizations.OrderBy(x => x.CreatedAt).ThenBy(x => x.CultureCode)) + .ThenInclude(x => x.Value.Localizations.OrderBy(x => x.CreatedAt).ThenBy(x => x.LanguageCode)) .Include(x => x.SearchTags.OrderBy(x => x.CreatedAt).ThenBy(x => x.Id)) .Include(x => x.Attachments.OrderBy(x => x.CreatedAt).ThenBy(x => x.Id)) - .ThenInclude(x => x.DisplayName!.Localizations.OrderBy(x => x.CreatedAt).ThenBy(x => x.CultureCode)) + .ThenInclude(x => x.DisplayName!.Localizations.OrderBy(x => x.CreatedAt).ThenBy(x => x.LanguageCode)) .Include(x => x.Attachments.OrderBy(x => x.CreatedAt).ThenBy(x => x.Id)) .ThenInclude(x => x.Urls.OrderBy(x => x.CreatedAt).ThenBy(x => x.Id)) .Include(x => x.GuiActions.OrderBy(x => x.CreatedAt).ThenBy(x => x.Id)) - .ThenInclude(x => x.Title!.Localizations.OrderBy(x => x.CreatedAt).ThenBy(x => x.CultureCode)) + .ThenInclude(x => x.Title!.Localizations.OrderBy(x => x.CreatedAt).ThenBy(x => x.LanguageCode)) .Include(x => x.GuiActions.OrderBy(x => x.CreatedAt).ThenBy(x => x.Id)) - .ThenInclude(x => x!.Prompt!.Localizations.OrderBy(x => x.CreatedAt).ThenBy(x => x.CultureCode)) + .ThenInclude(x => x!.Prompt!.Localizations.OrderBy(x => x.CreatedAt).ThenBy(x => x.LanguageCode)) .Include(x => x.ApiActions.OrderBy(x => x.CreatedAt).ThenBy(x => x.Id)) .ThenInclude(x => x.Endpoints.OrderBy(x => x.CreatedAt).ThenBy(x => x.Id)) .Include(x => x.Activities).ThenInclude(x => x.Description!.Localizations) diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Queries/Search/SearchDialogQuery.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Queries/Search/SearchDialogQuery.cs index 1dfede113..14b7cec05 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Queries/Search/SearchDialogQuery.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Queries/Search/SearchDialogQuery.cs @@ -18,7 +18,7 @@ namespace Digdir.Domain.Dialogporten.Application.Features.V1.ServiceOwner.Dialog public sealed class SearchDialogQuery : SortablePaginationParameter, IRequest { - private string? _searchCultureCode; + private string? _searchLanguageCode; /// /// Filter by one or more service resources @@ -95,12 +95,12 @@ public sealed class SearchDialogQuery : SortablePaginationParameter - /// Limit free text search to texts with this culture code, e.g. \"nb-NO\". Default: search all culture codes + /// Limit free text search to texts with this language code, e.g. 'no', 'en'. Culture codes will be normalized to neutral language codes (ISO 639). Default: search all culture codes /// - public string? SearchCultureCode + public string? SearchLanguageCode { - get => _searchCultureCode; - init => _searchCultureCode = Localization.NormalizeCultureCode(value); + get => _searchLanguageCode; + init => _searchLanguageCode = Localization.NormalizeCultureCode(value); } } public sealed class SearchDialogQueryOrderDefinition : IOrderDefinition @@ -141,7 +141,7 @@ public SearchDialogQueryHandler( public async Task Handle(SearchDialogQuery request, CancellationToken cancellationToken) { var resourceIds = await _userResourceRegistry.GetCurrentUserResourceIds(cancellationToken); - var searchExpression = Expressions.LocalizedSearchExpression(request.Search, request.SearchCultureCode); + var searchExpression = Expressions.LocalizedSearchExpression(request.Search, request.SearchLanguageCode); var query = _db.Dialogs .WhereIf(!request.ServiceResource.IsNullOrEmpty(), diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Queries/Search/SearchDialogQueryValidator.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Queries/Search/SearchDialogQueryValidator.cs index da1c8e022..e566d5ed2 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Queries/Search/SearchDialogQueryValidator.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Queries/Search/SearchDialogQueryValidator.cs @@ -1,6 +1,7 @@ using Digdir.Domain.Dialogporten.Application.Common.Extensions.Enumerables; using Digdir.Domain.Dialogporten.Application.Common.Extensions.FluentValidation; using Digdir.Domain.Dialogporten.Application.Common.Pagination; +using Digdir.Domain.Dialogporten.Application.Features.V1.Common.Localizations; using Digdir.Domain.Dialogporten.Domain.Localizations; using Digdir.Domain.Dialogporten.Domain.Parties; using Digdir.Domain.Dialogporten.Domain.Parties.Abstractions; @@ -17,9 +18,13 @@ public SearchDialogQueryValidator() .MinimumLength(3) .When(x => x.Search is not null); - RuleFor(x => x.SearchCultureCode) + RuleFor(x => x.SearchLanguageCode) .Must(x => x is null || Localization.IsValidCultureCode(x)) - .WithMessage("'{PropertyName}' must be a valid culture code."); + .WithMessage(searchQuery => + (searchQuery.SearchLanguageCode == "no" + ? LocalizationValidatorContants.InvalidCultureCodeErrorMessageWithNorwegianHint + : LocalizationValidatorContants.InvalidCultureCodeErrorMessage) + + LocalizationValidatorContants.NormalizationErrorMessage); RuleFor(x => x) .Must(x => PartyIdentifier.TryParse(x.EndUserId, out var id) && id is NorwegianPersonIdentifier or SystemUserIdentifier) diff --git a/src/Digdir.Domain.Dialogporten.Domain/Common/Extensions/AggregateNodeExtensions.cs b/src/Digdir.Domain.Dialogporten.Domain/Common/Extensions/AggregateNodeExtensions.cs index c47493d68..bdfa5a2f9 100644 --- a/src/Digdir.Domain.Dialogporten.Domain/Common/Extensions/AggregateNodeExtensions.cs +++ b/src/Digdir.Domain.Dialogporten.Domain/Common/Extensions/AggregateNodeExtensions.cs @@ -48,7 +48,7 @@ private static ReadOnlyCollection ToPaths(this IEnumerable ToLocalizationPathStrings(this LocalizationSet localizationSet, string parentPath) => - localizationSet.Localizations.Select(x => $"{parentPath}/{x.CultureCode}"); + localizationSet.Localizations.Select(x => $"{parentPath}/{x.LanguageCode}"); private static string ToName(this object obj) => obj switch { diff --git a/src/Digdir.Domain.Dialogporten.Domain/Localizations/Localization.cs b/src/Digdir.Domain.Dialogporten.Domain/Localizations/Localization.cs index 366c7f86d..4ccf3f860 100644 --- a/src/Digdir.Domain.Dialogporten.Domain/Localizations/Localization.cs +++ b/src/Digdir.Domain.Dialogporten.Domain/Localizations/Localization.cs @@ -5,32 +5,63 @@ namespace Digdir.Domain.Dialogporten.Domain.Localizations; public class Localization : IJoinEntity { - private static readonly HashSet ValidCultureNames = CultureInfo - .GetCultures(CultureTypes.NeutralCultures | CultureTypes.SpecificCultures) - .Where(x => !string.IsNullOrWhiteSpace(x.Name)) - .Select(x => x.Name) - .ToHashSet(); + private static readonly Dictionary NeutralCultureByValidCultureCodes = + BuildNeutralCultureByValidCultureCodes(); - private string _cultureCode = null!; + private string _languageCode = null!; public DateTimeOffset CreatedAt { get; set; } public DateTimeOffset UpdatedAt { get; set; } public string Value { get; set; } = null!; - public string CultureCode + + public string LanguageCode { - get => _cultureCode; - set => _cultureCode = NormalizeCultureCode(value)!; + get => _languageCode; + set => _languageCode = NormalizeCultureCode(value)!; } // === Dependent relationships === public Guid LocalizationSetId { get; set; } public LocalizationSet LocalizationSet { get; set; } = null!; - public static string? NormalizeCultureCode(string? cultureCode) => - cultureCode?.Trim().Replace('_', '-').ToLowerInvariant(); + + public static string? NormalizeCultureCode(string? cultureCode) + { + cultureCode = cultureCode?.Trim().Replace('_', '-').ToLowerInvariant(); + return cultureCode is not null && NeutralCultureByValidCultureCodes.TryGetValue(cultureCode, out var neutralCulture) + ? neutralCulture.TwoLetterISOLanguageName + : cultureCode; + } public static bool IsValidCultureCode(string? cultureCode) => - !string.IsNullOrWhiteSpace(cultureCode) && - ValidCultureNames.Contains(cultureCode, StringComparer.InvariantCultureIgnoreCase); + cultureCode is not null + && NeutralCultureByValidCultureCodes.TryGetValue(cultureCode, out var neutralCulture) + && cultureCode == neutralCulture.TwoLetterISOLanguageName; + + private static Dictionary BuildNeutralCultureByValidCultureCodes() + { + var exclude = new[] { "no", "iv" }; + var cultureGroups = CultureInfo + .GetCultures(CultureTypes.NeutralCultures | CultureTypes.SpecificCultures) + .Where(x => !exclude.Contains(x.TwoLetterISOLanguageName)) + .GroupBy(x => x.TwoLetterISOLanguageName) + .ToList(); + + var neutralCultureByValidCultureCodes = new Dictionary(StringComparer.OrdinalIgnoreCase); + + foreach (var cultureGroup in cultureGroups) + { + var neutral = cultureGroup.First(x => x.CultureTypes.HasFlag(CultureTypes.NeutralCultures)); + neutralCultureByValidCultureCodes[neutral.TwoLetterISOLanguageName] = neutral; + neutralCultureByValidCultureCodes[neutral.ThreeLetterISOLanguageName] = neutral; + + foreach (var culture in cultureGroup.Except([neutral])) + { + neutralCultureByValidCultureCodes[culture.Name] = neutral; + } + } + + return neutralCultureByValidCultureCodes; + } } diff --git a/src/Digdir.Domain.Dialogporten.GraphQL/EndUser/Common/ObjectTypes.cs b/src/Digdir.Domain.Dialogporten.GraphQL/EndUser/Common/ObjectTypes.cs index 4a153af2f..f705ba09d 100644 --- a/src/Digdir.Domain.Dialogporten.GraphQL/EndUser/Common/ObjectTypes.cs +++ b/src/Digdir.Domain.Dialogporten.GraphQL/EndUser/Common/ObjectTypes.cs @@ -3,7 +3,7 @@ namespace Digdir.Domain.Dialogporten.GraphQL.EndUser.Common; public sealed class Localization { public string Value { get; set; } = null!; - public string CultureCode { get; set; } = null!; + public string LanguageCode { get; set; } = null!; } public enum ContentType diff --git a/src/Digdir.Domain.Dialogporten.GraphQL/EndUser/SearchDialogs/ObjectTypes.cs b/src/Digdir.Domain.Dialogporten.GraphQL/EndUser/SearchDialogs/ObjectTypes.cs index f33e19f07..e5a7e36aa 100644 --- a/src/Digdir.Domain.Dialogporten.GraphQL/EndUser/SearchDialogs/ObjectTypes.cs +++ b/src/Digdir.Domain.Dialogporten.GraphQL/EndUser/SearchDialogs/ObjectTypes.cs @@ -90,6 +90,6 @@ public sealed class SearchDialogInput [GraphQLDescription("Search string for free text search. Will attempt to fuzzily match in all free text fields in the aggregate")] public string? Search { get; init; } - [GraphQLDescription("Limit free text search to texts with this culture code, e.g. \"nb-NO\". Default: search all culture codes")] - public string? SearchCultureCode { get; init; } + [GraphQLDescription("Limit free text search to texts with this language code, e.g. 'no', 'en'. Culture codes will be normalized to neutral language codes (ISO 639). Default: search all culture codes")] + public string? SearchLanguageCode { get; init; } } diff --git a/src/Digdir.Domain.Dialogporten.Infrastructure/Persistence/Configurations/Localizations/LocalizationConfiguration.cs b/src/Digdir.Domain.Dialogporten.Infrastructure/Persistence/Configurations/Localizations/LocalizationConfiguration.cs index cae120455..b9511ca12 100644 --- a/src/Digdir.Domain.Dialogporten.Infrastructure/Persistence/Configurations/Localizations/LocalizationConfiguration.cs +++ b/src/Digdir.Domain.Dialogporten.Infrastructure/Persistence/Configurations/Localizations/LocalizationConfiguration.cs @@ -8,8 +8,8 @@ internal sealed class LocalizationConfiguration : IEntityTypeConfiguration builder) { - builder.HasKey(x => new { x.LocalizationSetId, x.CultureCode }); - builder.Property(x => x.CultureCode).HasMaxLength(15); + builder.HasKey(x => new { x.LocalizationSetId, CultureCode = x.LanguageCode }); + builder.Property(x => x.LanguageCode).HasMaxLength(15); // TODO: Can value have smaller max length? builder.Property(x => x.Value).HasMaxLength(4095); } diff --git a/src/Digdir.Domain.Dialogporten.Infrastructure/Persistence/Migrations/20240624142033_RenameCultureCodeToLanguageCode.Designer.cs b/src/Digdir.Domain.Dialogporten.Infrastructure/Persistence/Migrations/20240624142033_RenameCultureCodeToLanguageCode.Designer.cs new file mode 100644 index 000000000..6e46d9c10 --- /dev/null +++ b/src/Digdir.Domain.Dialogporten.Infrastructure/Persistence/Migrations/20240624142033_RenameCultureCodeToLanguageCode.Designer.cs @@ -0,0 +1,1326 @@ +// +using System; +using Digdir.Domain.Dialogporten.Infrastructure.Persistence; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Digdir.Domain.Dialogporten.Infrastructure.Persistence.Migrations +{ + [DbContext(typeof(DialogDbContext))] + [Migration("20240624142033_RenameCultureCodeToLanguageCode")] + partial class RenameCultureCodeToLanguageCode + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.6") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions.DialogApiAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasDefaultValueSql("gen_random_uuid()"); + + b.Property("Action") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("AuthorizationAttribute") + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("current_timestamp at time zone 'utc'"); + + b.Property("DialogId") + .HasColumnType("uuid"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("current_timestamp at time zone 'utc'"); + + b.HasKey("Id"); + + b.HasIndex("DialogId"); + + b.ToTable("DialogApiAction"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions.DialogApiActionEndpoint", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasDefaultValueSql("gen_random_uuid()"); + + b.Property("ActionId") + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("current_timestamp at time zone 'utc'"); + + b.Property("Deprecated") + .HasColumnType("boolean"); + + b.Property("DocumentationUrl") + .HasMaxLength(1023) + .HasColumnType("character varying(1023)"); + + b.Property("HttpMethodId") + .HasColumnType("integer"); + + b.Property("RequestSchema") + .HasMaxLength(1023) + .HasColumnType("character varying(1023)"); + + b.Property("ResponseSchema") + .HasMaxLength(1023) + .HasColumnType("character varying(1023)"); + + b.Property("SunsetAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("current_timestamp at time zone 'utc'"); + + b.Property("Url") + .IsRequired() + .HasMaxLength(1023) + .HasColumnType("character varying(1023)"); + + b.Property("Version") + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.HasKey("Id"); + + b.HasIndex("ActionId"); + + b.HasIndex("HttpMethodId"); + + b.ToTable("DialogApiActionEndpoint"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions.DialogGuiAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasDefaultValueSql("gen_random_uuid()"); + + b.Property("Action") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("AuthorizationAttribute") + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("current_timestamp at time zone 'utc'"); + + b.Property("DialogId") + .HasColumnType("uuid"); + + b.Property("HttpMethodId") + .HasColumnType("integer"); + + b.Property("IsDeleteDialogAction") + .HasColumnType("boolean"); + + b.Property("PriorityId") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("current_timestamp at time zone 'utc'"); + + b.Property("Url") + .IsRequired() + .HasMaxLength(1023) + .HasColumnType("character varying(1023)"); + + b.HasKey("Id"); + + b.HasIndex("DialogId"); + + b.HasIndex("HttpMethodId"); + + b.HasIndex("PriorityId"); + + b.ToTable("DialogGuiAction"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions.DialogGuiActionPriority", b => + { + b.Property("Id") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.HasKey("Id"); + + b.ToTable("DialogGuiActionPriority"); + + b.HasData( + new + { + Id = 1, + Name = "Primary" + }, + new + { + Id = 2, + Name = "Secondary" + }, + new + { + Id = 3, + Name = "Tertiary" + }); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Activities.DialogActivity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasDefaultValueSql("gen_random_uuid()"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("current_timestamp at time zone 'utc'"); + + b.Property("DialogId") + .HasColumnType("uuid"); + + b.Property("ExtendedType") + .HasMaxLength(1023) + .HasColumnType("character varying(1023)"); + + b.Property("PerformedBy") + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("RelatedActivityId") + .HasColumnType("uuid"); + + b.Property("TypeId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("DialogId"); + + b.HasIndex("RelatedActivityId"); + + b.HasIndex("TypeId"); + + b.ToTable("DialogActivity"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Activities.DialogActivityType", b => + { + b.Property("Id") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.HasKey("Id"); + + b.ToTable("DialogActivityType"); + + b.HasData( + new + { + Id = 1, + Name = "Submission" + }, + new + { + Id = 2, + Name = "Feedback" + }, + new + { + Id = 3, + Name = "Information" + }, + new + { + Id = 4, + Name = "Error" + }, + new + { + Id = 5, + Name = "Closed" + }, + new + { + Id = 7, + Name = "Forwarded" + }); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Attachments.DialogAttachment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasDefaultValueSql("gen_random_uuid()"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("current_timestamp at time zone 'utc'"); + + b.Property("DialogId") + .HasColumnType("uuid"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("current_timestamp at time zone 'utc'"); + + b.HasKey("Id"); + + b.HasIndex("DialogId"); + + b.ToTable("DialogAttachment"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Attachments.DialogAttachmentUrl", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasDefaultValueSql("gen_random_uuid()"); + + b.Property("ConsumerTypeId") + .HasColumnType("integer"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("current_timestamp at time zone 'utc'"); + + b.Property("DialogAttachmentId") + .HasColumnType("uuid"); + + b.Property("MediaType") + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("current_timestamp at time zone 'utc'"); + + b.Property("Url") + .IsRequired() + .HasMaxLength(1023) + .HasColumnType("character varying(1023)"); + + b.HasKey("Id"); + + b.HasIndex("ConsumerTypeId"); + + b.HasIndex("DialogAttachmentId"); + + b.ToTable("DialogAttachmentUrl"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Attachments.DialogAttachmentUrlConsumerType", b => + { + b.Property("Id") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.HasKey("Id"); + + b.ToTable("DialogAttachmentUrlConsumerType"); + + b.HasData( + new + { + Id = 1, + Name = "Gui" + }, + new + { + Id = 2, + Name = "Api" + }); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Content.DialogContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasDefaultValueSql("gen_random_uuid()"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("current_timestamp at time zone 'utc'"); + + b.Property("DialogId") + .HasColumnType("uuid"); + + b.Property("MediaType") + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("TypeId") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("current_timestamp at time zone 'utc'"); + + b.HasKey("Id"); + + b.HasIndex("TypeId"); + + b.HasIndex("DialogId", "TypeId") + .IsUnique(); + + b.ToTable("DialogContent"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Content.DialogContentType", b => + { + b.Property("Id") + .HasColumnType("integer"); + + b.Property("AllowedMediaTypes") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("MaxLength") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("OutputInList") + .HasColumnType("boolean"); + + b.Property("Required") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.ToTable("DialogContentType"); + + b.HasData( + new + { + Id = 1, + AllowedMediaTypes = new string[0], + MaxLength = 255, + Name = "Title", + OutputInList = true, + Required = true + }, + new + { + Id = 2, + AllowedMediaTypes = new string[0], + MaxLength = 255, + Name = "SenderName", + OutputInList = true, + Required = false + }, + new + { + Id = 3, + AllowedMediaTypes = new string[0], + MaxLength = 255, + Name = "Summary", + OutputInList = true, + Required = true + }, + new + { + Id = 4, + AllowedMediaTypes = new[] { "text/html", "text/plain", "text/markdown" }, + MaxLength = 1023, + Name = "AdditionalInfo", + OutputInList = false, + Required = false + }, + new + { + Id = 5, + AllowedMediaTypes = new string[0], + MaxLength = 20, + Name = "ExtendedStatus", + OutputInList = true, + Required = false + }, + new + { + Id = 6, + AllowedMediaTypes = new[] { "application/vnd.dialogporten.frontchannelembed+json;type=markdown" }, + MaxLength = 1023, + Name = "MainContentReference", + OutputInList = false, + Required = false + }); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasDefaultValueSql("gen_random_uuid()"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("current_timestamp at time zone 'utc'"); + + b.Property("Deleted") + .HasColumnType("boolean"); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DueAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ExtendedStatus") + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("ExternalReference") + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("Org") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .UseCollation("C"); + + b.Property("Party") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .UseCollation("C"); + + b.Property("Progress") + .HasColumnType("integer"); + + b.Property("Revision") + .IsConcurrencyToken() + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasDefaultValueSql("gen_random_uuid()"); + + b.Property("ServiceResource") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .UseCollation("C"); + + b.Property("ServiceResourceType") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("StatusId") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("current_timestamp at time zone 'utc'"); + + b.Property("VisibleFrom") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CreatedAt"); + + b.HasIndex("DueAt"); + + b.HasIndex("Org"); + + b.HasIndex("Party"); + + b.HasIndex("ServiceResource"); + + b.HasIndex("StatusId"); + + b.HasIndex("UpdatedAt"); + + b.ToTable("Dialog", (string)null); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogSearchTag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasDefaultValueSql("gen_random_uuid()"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("current_timestamp at time zone 'utc'"); + + b.Property("DialogId") + .HasColumnType("uuid"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(63) + .HasColumnType("character varying(63)"); + + b.HasKey("Id"); + + b.HasIndex("DialogId", "Value") + .IsUnique(); + + b.ToTable("DialogSearchTag"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogSeenLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasDefaultValueSql("gen_random_uuid()"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("current_timestamp at time zone 'utc'"); + + b.Property("DialogId") + .HasColumnType("uuid"); + + b.Property("EndUserId") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("EndUserName") + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("EndUserTypeId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("DialogId"); + + b.HasIndex("EndUserTypeId"); + + b.ToTable("DialogSeenLog"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogStatus", b => + { + b.Property("Id") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.HasKey("Id"); + + b.ToTable("DialogStatus"); + + b.HasData( + new + { + Id = 1, + Name = "New" + }, + new + { + Id = 2, + Name = "InProgress" + }, + new + { + Id = 3, + Name = "Waiting" + }, + new + { + Id = 4, + Name = "Signing" + }, + new + { + Id = 5, + Name = "Cancelled" + }, + new + { + Id = 6, + Name = "Completed" + }); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogUserType", b => + { + b.Property("Id") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.HasKey("Id"); + + b.ToTable("DialogUserType"); + + b.HasData( + new + { + Id = 0, + Name = "Unknown" + }, + new + { + Id = 1, + Name = "Person" + }, + new + { + Id = 2, + Name = "LegacySystemUser" + }, + new + { + Id = 3, + Name = "SystemUser" + }, + new + { + Id = 4, + Name = "ServiceOwner" + }, + new + { + Id = 5, + Name = "ServiceOwnerOnBehalfOfPerson" + }); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Http.HttpVerb", b => + { + b.Property("Id") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.HasKey("Id"); + + b.ToTable("HttpVerb"); + + b.HasData( + new + { + Id = 1, + Name = "GET" + }, + new + { + Id = 2, + Name = "POST" + }, + new + { + Id = 3, + Name = "PUT" + }, + new + { + Id = 4, + Name = "PATCH" + }, + new + { + Id = 5, + Name = "DELETE" + }, + new + { + Id = 6, + Name = "HEAD" + }, + new + { + Id = 7, + Name = "OPTIONS" + }, + new + { + Id = 8, + Name = "TRACE" + }, + new + { + Id = 9, + Name = "CONNECT" + }); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Localizations.Localization", b => + { + b.Property("LocalizationSetId") + .HasColumnType("uuid"); + + b.Property("LanguageCode") + .HasMaxLength(15) + .HasColumnType("character varying(15)"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("current_timestamp at time zone 'utc'"); + + b.Property("UpdatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("current_timestamp at time zone 'utc'"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(4095) + .HasColumnType("character varying(4095)"); + + b.HasKey("LocalizationSetId", "LanguageCode"); + + b.ToTable("Localization"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Localizations.LocalizationSet", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasDefaultValueSql("gen_random_uuid()"); + + b.Property("CreatedAt") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("current_timestamp at time zone 'utc'"); + + b.Property("Discriminator") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.HasKey("Id"); + + b.ToTable("LocalizationSet"); + + b.HasDiscriminator("Discriminator").HasValue("LocalizationSet"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Outboxes.OutboxMessage", b => + { + b.Property("EventId") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("EventPayload") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("EventType") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.HasKey("EventId"); + + b.ToTable("OutboxMessage"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Outboxes.OutboxMessageConsumer", b => + { + b.Property("EventId") + .HasColumnType("uuid"); + + b.Property("ConsumerName") + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.HasKey("EventId", "ConsumerName"); + + b.ToTable("OutboxMessageConsumer"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions.DialogGuiActionPrompt", b => + { + b.HasBaseType("Digdir.Domain.Dialogporten.Domain.Localizations.LocalizationSet"); + + b.Property("GuiActionId") + .HasColumnType("uuid"); + + b.HasIndex("GuiActionId") + .IsUnique(); + + b.ToTable("LocalizationSet", t => + { + t.Property("GuiActionId") + .HasColumnName("DialogGuiActionPrompt_GuiActionId"); + }); + + b.HasDiscriminator().HasValue("DialogGuiActionPrompt"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions.DialogGuiActionTitle", b => + { + b.HasBaseType("Digdir.Domain.Dialogporten.Domain.Localizations.LocalizationSet"); + + b.Property("GuiActionId") + .HasColumnType("uuid"); + + b.HasIndex("GuiActionId") + .IsUnique(); + + b.HasDiscriminator().HasValue("DialogGuiActionTitle"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Activities.DialogActivityDescription", b => + { + b.HasBaseType("Digdir.Domain.Dialogporten.Domain.Localizations.LocalizationSet"); + + b.Property("ActivityId") + .HasColumnType("uuid"); + + b.HasIndex("ActivityId") + .IsUnique(); + + b.HasDiscriminator().HasValue("DialogActivityDescription"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Attachments.AttachmentDisplayName", b => + { + b.HasBaseType("Digdir.Domain.Dialogporten.Domain.Localizations.LocalizationSet"); + + b.Property("AttachmentId") + .HasColumnType("uuid"); + + b.HasIndex("AttachmentId") + .IsUnique(); + + b.HasDiscriminator().HasValue("AttachmentDisplayName"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Content.DialogContentValue", b => + { + b.HasBaseType("Digdir.Domain.Dialogporten.Domain.Localizations.LocalizationSet"); + + b.Property("DialogContentId") + .HasColumnType("uuid"); + + b.HasIndex("DialogContentId") + .IsUnique(); + + b.HasDiscriminator().HasValue("DialogContentValue"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogSeenLogVia", b => + { + b.HasBaseType("Digdir.Domain.Dialogporten.Domain.Localizations.LocalizationSet"); + + b.Property("DialogSeenLogId") + .HasColumnType("uuid"); + + b.HasIndex("DialogSeenLogId") + .IsUnique(); + + b.HasDiscriminator().HasValue("DialogSeenLogVia"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions.DialogApiAction", b => + { + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogEntity", "Dialog") + .WithMany("ApiActions") + .HasForeignKey("DialogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Dialog"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions.DialogApiActionEndpoint", b => + { + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions.DialogApiAction", "Action") + .WithMany("Endpoints") + .HasForeignKey("ActionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Digdir.Domain.Dialogporten.Domain.Http.HttpVerb", "HttpMethod") + .WithMany() + .HasForeignKey("HttpMethodId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Action"); + + b.Navigation("HttpMethod"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions.DialogGuiAction", b => + { + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogEntity", "Dialog") + .WithMany("GuiActions") + .HasForeignKey("DialogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Digdir.Domain.Dialogporten.Domain.Http.HttpVerb", "HttpMethod") + .WithMany() + .HasForeignKey("HttpMethodId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions.DialogGuiActionPriority", "Priority") + .WithMany() + .HasForeignKey("PriorityId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Dialog"); + + b.Navigation("HttpMethod"); + + b.Navigation("Priority"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Activities.DialogActivity", b => + { + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogEntity", "Dialog") + .WithMany("Activities") + .HasForeignKey("DialogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Activities.DialogActivity", "RelatedActivity") + .WithMany("RelatedActivities") + .HasForeignKey("RelatedActivityId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Activities.DialogActivityType", "Type") + .WithMany() + .HasForeignKey("TypeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Dialog"); + + b.Navigation("RelatedActivity"); + + b.Navigation("Type"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Attachments.DialogAttachment", b => + { + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogEntity", "Dialog") + .WithMany("Attachments") + .HasForeignKey("DialogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Dialog"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Attachments.DialogAttachmentUrl", b => + { + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Attachments.DialogAttachmentUrlConsumerType", "ConsumerType") + .WithMany() + .HasForeignKey("ConsumerTypeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Attachments.DialogAttachment", "DialogAttachment") + .WithMany("Urls") + .HasForeignKey("DialogAttachmentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ConsumerType"); + + b.Navigation("DialogAttachment"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Content.DialogContent", b => + { + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogEntity", "Dialog") + .WithMany("Content") + .HasForeignKey("DialogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Content.DialogContentType", "Type") + .WithMany() + .HasForeignKey("TypeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Dialog"); + + b.Navigation("Type"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogEntity", b => + { + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogStatus", "Status") + .WithMany() + .HasForeignKey("StatusId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Status"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogSearchTag", b => + { + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogEntity", "Dialog") + .WithMany("SearchTags") + .HasForeignKey("DialogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Dialog"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogSeenLog", b => + { + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogEntity", "Dialog") + .WithMany("SeenLog") + .HasForeignKey("DialogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogUserType", "EndUserType") + .WithMany() + .HasForeignKey("EndUserTypeId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Dialog"); + + b.Navigation("EndUserType"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Localizations.Localization", b => + { + b.HasOne("Digdir.Domain.Dialogporten.Domain.Localizations.LocalizationSet", "LocalizationSet") + .WithMany("Localizations") + .HasForeignKey("LocalizationSetId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("LocalizationSet"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Outboxes.OutboxMessageConsumer", b => + { + b.HasOne("Digdir.Domain.Dialogporten.Domain.Outboxes.OutboxMessage", "OutboxMessage") + .WithMany("OutboxMessageConsumers") + .HasForeignKey("EventId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("OutboxMessage"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions.DialogGuiActionPrompt", b => + { + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions.DialogGuiAction", "GuiAction") + .WithOne("Prompt") + .HasForeignKey("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions.DialogGuiActionPrompt", "GuiActionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuiAction"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions.DialogGuiActionTitle", b => + { + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions.DialogGuiAction", "GuiAction") + .WithOne("Title") + .HasForeignKey("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions.DialogGuiActionTitle", "GuiActionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuiAction"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Activities.DialogActivityDescription", b => + { + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Activities.DialogActivity", "Activity") + .WithOne("Description") + .HasForeignKey("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Activities.DialogActivityDescription", "ActivityId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Activity"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Attachments.AttachmentDisplayName", b => + { + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Attachments.DialogAttachment", "Attachment") + .WithOne("DisplayName") + .HasForeignKey("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Attachments.AttachmentDisplayName", "AttachmentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Attachment"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Content.DialogContentValue", b => + { + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Content.DialogContent", "DialogContent") + .WithOne("Value") + .HasForeignKey("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Content.DialogContentValue", "DialogContentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DialogContent"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogSeenLogVia", b => + { + b.HasOne("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogSeenLog", "DialogSeenLog") + .WithOne("Via") + .HasForeignKey("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogSeenLogVia", "DialogSeenLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DialogSeenLog"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions.DialogApiAction", b => + { + b.Navigation("Endpoints"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions.DialogGuiAction", b => + { + b.Navigation("Prompt"); + + b.Navigation("Title"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Activities.DialogActivity", b => + { + b.Navigation("Description"); + + b.Navigation("RelatedActivities"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Attachments.DialogAttachment", b => + { + b.Navigation("DisplayName"); + + b.Navigation("Urls"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Content.DialogContent", b => + { + b.Navigation("Value") + .IsRequired(); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogEntity", b => + { + b.Navigation("Activities"); + + b.Navigation("ApiActions"); + + b.Navigation("Attachments"); + + b.Navigation("Content"); + + b.Navigation("GuiActions"); + + b.Navigation("SearchTags"); + + b.Navigation("SeenLog"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.DialogSeenLog", b => + { + b.Navigation("Via"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Localizations.LocalizationSet", b => + { + b.Navigation("Localizations"); + }); + + modelBuilder.Entity("Digdir.Domain.Dialogporten.Domain.Outboxes.OutboxMessage", b => + { + b.Navigation("OutboxMessageConsumers"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Digdir.Domain.Dialogporten.Infrastructure/Persistence/Migrations/20240624142033_RenameCultureCodeToLanguageCode.cs b/src/Digdir.Domain.Dialogporten.Infrastructure/Persistence/Migrations/20240624142033_RenameCultureCodeToLanguageCode.cs new file mode 100644 index 000000000..f62530c20 --- /dev/null +++ b/src/Digdir.Domain.Dialogporten.Infrastructure/Persistence/Migrations/20240624142033_RenameCultureCodeToLanguageCode.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Digdir.Domain.Dialogporten.Infrastructure.Persistence.Migrations +{ + /// + public partial class RenameCultureCodeToLanguageCode : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.RenameColumn( + name: "CultureCode", + table: "Localization", + newName: "LanguageCode"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.RenameColumn( + name: "LanguageCode", + table: "Localization", + newName: "CultureCode"); + } + } +} diff --git a/src/Digdir.Domain.Dialogporten.Infrastructure/Persistence/Migrations/DialogDbContextModelSnapshot.cs b/src/Digdir.Domain.Dialogporten.Infrastructure/Persistence/Migrations/DialogDbContextModelSnapshot.cs index f1900a6ef..897b5644f 100644 --- a/src/Digdir.Domain.Dialogporten.Infrastructure/Persistence/Migrations/DialogDbContextModelSnapshot.cs +++ b/src/Digdir.Domain.Dialogporten.Infrastructure/Persistence/Migrations/DialogDbContextModelSnapshot.cs @@ -825,7 +825,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("LocalizationSetId") .HasColumnType("uuid"); - b.Property("CultureCode") + b.Property("LanguageCode") .HasMaxLength(15) .HasColumnType("character varying(15)"); @@ -844,7 +844,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(4095) .HasColumnType("character varying(4095)"); - b.HasKey("LocalizationSetId", "CultureCode"); + b.HasKey("LocalizationSetId", "LanguageCode"); b.ToTable("Localization"); }); diff --git a/src/Digdir.Domain.Dialogporten.WebApi/Digdir.Domain.Dialogporten.WebApi.http b/src/Digdir.Domain.Dialogporten.WebApi/Digdir.Domain.Dialogporten.WebApi.http index 9e4acb888..13c8f2539 100644 --- a/src/Digdir.Domain.Dialogporten.WebApi/Digdir.Domain.Dialogporten.WebApi.http +++ b/src/Digdir.Domain.Dialogporten.WebApi/Digdir.Domain.Dialogporten.WebApi.http @@ -34,10 +34,10 @@ Content-Type: application/json "ServiceResource": "urn:altinn:resource:super-simple-service", "Status": "InProgress", "Content": [ - { "Type": "Title", "Value": [ { "CultureCode": "en-us", "Value": "Hello world!" } ]}, - { "Type": "Summary", "Value": [ { "CultureCode": "NB_NO", "Value": "Dette er en oppsummering." } ]}, - { "Type": "SenderName", "Value": [ { "CultureCode": "NB_NO", "Value": "Jeg er meg og jeg har sendt" } ]}, - { "Type": "AdditionalInfo", "Value": [ { "CultureCode": "NB_NO", "Value": "Dette er en paragref

" } ]} + { "Type": "Title", "Value": [ { "LanguageCode": "en-us", "Value": "Hello world!" } ]}, + { "Type": "Summary", "Value": [ { "LanguageCode": "NB_NO", "Value": "Dette er en oppsummering." } ]}, + { "Type": "SenderName", "Value": [ { "LanguageCode": "NB_NO", "Value": "Jeg er meg og jeg har sendt" } ]}, + { "Type": "AdditionalInfo", "Value": [ { "LanguageCode": "NB_NO", "Value": "Dette er en paragref

" } ]} ] } @@ -52,10 +52,10 @@ Content-Type: application/json "ServiceResource": "urn:altinn:resource:super-simple-service", "Status": "InProgress", "Content": [ - { "Type": "Title", "Value": [ { "CultureCode": "NB_NO", "Value": "Hei verden!" } ]}, - { "Type": "Summary", "Value": [ { "CultureCode": "NB_NO", "Value": "Dette er en oppsummering." } ]}, - { "Type": "SenderName", "Value": [ { "CultureCode": "NB_NO", "Value": "Jeg er meg og jeg har sendt" } ]}, - { "Type": "AdditionalInfo", "Value": [ { "CultureCode": "NB_NO", "Value": "Dette er en paragref

" } ]} + { "Type": "Title", "Value": [ { "LanguageCode": "NB_NO", "Value": "Hei verden!" } ]}, + { "Type": "Summary", "Value": [ { "LanguageCode": "NB_NO", "Value": "Dette er en oppsummering." } ]}, + { "Type": "SenderName", "Value": [ { "LanguageCode": "NB_NO", "Value": "Jeg er meg og jeg har sendt" } ]}, + { "Type": "AdditionalInfo", "Value": [ { "LanguageCode": "NB_NO", "Value": "Dette er en paragref

" } ]} ], "SearchTags": [ { "value": "tag1" }, @@ -69,8 +69,19 @@ PATCH {{baseAdress}}/api/v1/serviceowner/dialogs/{{dialogId}} Content-Type: application/json [ - { "op": "replace", "path": "/content/0/value/0", "value": { "CultureCode": "en_US", "Value": "Hello world!" } }, - { "op": "replace", "path": "/content/1/value/0/value", "value": "Ny oppsummering." } + { + "op": "replace", + "path": "/content/0/value/0", + "value": { + "LanguageCode": "en_US", + "Value": "Hello world!" + } + }, + { + "op": "replace", + "path": "/content/1/value/0/value", + "value": "Ny oppsummering." + } ] ### diff --git a/src/Digdir.Domain.Dialogporten.WebApi/Endpoints/V1/ServiceOwner/Dialogs/Update/UpdateDialogSwaggerConfig.cs b/src/Digdir.Domain.Dialogporten.WebApi/Endpoints/V1/ServiceOwner/Dialogs/Update/UpdateDialogSwaggerConfig.cs index 1015d517f..f1096c891 100644 --- a/src/Digdir.Domain.Dialogporten.WebApi/Endpoints/V1/ServiceOwner/Dialogs/Update/UpdateDialogSwaggerConfig.cs +++ b/src/Digdir.Domain.Dialogporten.WebApi/Endpoints/V1/ServiceOwner/Dialogs/Update/UpdateDialogSwaggerConfig.cs @@ -56,7 +56,7 @@ public static RouteHandlerBuilder SetDescription(RouteHandlerBuilder builder) => [ new LocalizationDto { - CultureCode = "en-us", + LanguageCode = "en-us", Value = "Some Title" } ] @@ -68,7 +68,7 @@ public static RouteHandlerBuilder SetDescription(RouteHandlerBuilder builder) => [ new LocalizationDto { - CultureCode = "en-us", + LanguageCode = "en-us", Value = "Some Summary" } ] @@ -87,7 +87,7 @@ public static RouteHandlerBuilder SetDescription(RouteHandlerBuilder builder) => [ new LocalizationDto { - CultureCode = "en-us", + LanguageCode = "en-us", Value = "Some display name" } ], @@ -114,12 +114,12 @@ public static RouteHandlerBuilder SetDescription(RouteHandlerBuilder builder) => [ new LocalizationDto { - CultureCode = "en-us", + LanguageCode = "en-us", Value = "GUI action title" }, new LocalizationDto { - CultureCode = "nb-no", + LanguageCode = "nb-no", Value = "GUI action-tittel" } ] @@ -157,12 +157,12 @@ public static RouteHandlerBuilder SetDescription(RouteHandlerBuilder builder) => [ new LocalizationDto { - CultureCode = "en-us", + LanguageCode = "en-us", Value = "Some description" }, new LocalizationDto { - CultureCode = "nb-no", + LanguageCode = "nb-no", Value = "En beskrivelse" } ] diff --git a/src/Digdir.Tool.Dialogporten.GenerateFakeData/DialogGenerator.cs b/src/Digdir.Tool.Dialogporten.GenerateFakeData/DialogGenerator.cs index e592836dc..e157a63c9 100644 --- a/src/Digdir.Tool.Dialogporten.GenerateFakeData/DialogGenerator.cs +++ b/src/Digdir.Tool.Dialogporten.GenerateFakeData/DialogGenerator.cs @@ -353,17 +353,17 @@ public static List GenerateFakeLocalizations(int wordCount) [ new() { - CultureCode = "nb_NO", + LanguageCode = "nb_NO", Value = r.Words(wordCount) }, new() { - CultureCode = "nn_NO", + LanguageCode = "nn_NO", Value = r.Words(wordCount) }, new() { - CultureCode = "en_US", + LanguageCode = "en_US", Value = r.Words(wordCount) } ];