Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retrieve contact information for multiple users #209

Merged
merged 111 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
111 commits
Select commit Hold shift + click to select a range
9bed012
Correct name of container and solution folder
hggutvik Sep 25, 2024
5e8c12c
Fix comment typos
hggutvik Sep 25, 2024
d78a923
Use pattern matching for type check
hggutvik Sep 25, 2024
f7bcce5
Refactoring GetUserListByUuid to better fit it with the other methods
hggutvik Sep 25, 2024
502872c
Correct typo in comment
hggutvik Sep 26, 2024
9c1185e
Refactoring to arrow function for simplification
hggutvik Sep 26, 2024
148c693
Cleaning up namespace for Core's ServiceCollectionExtensions
hggutvik Sep 26, 2024
463287d
Add suffix "Service" to IUnitContactPoints
hggutvik Sep 27, 2024
9da782d
Correct namespace ..User.ContactPoints -> Unit.ContactPoints for IUni…
hggutvik Sep 27, 2024
6b32190
Simplify list initialization
hggutvik Sep 27, 2024
9ad68f5
Merge branch 'organize/clean-architecture' into featur/186-krr-db-schema
Ahmed-Ghanam Sep 30, 2024
42def52
Generate database models
Ahmed-Ghanam Sep 30, 2024
368af63
Move the database context class to its own folder
Ahmed-Ghanam Sep 30, 2024
3d0631d
Update the ContextClassName attribute
Ahmed-Ghanam Sep 30, 2024
4a9e081
Implemented an endpoint to retrieve user contact information efficien…
Ahmed-Ghanam Oct 2, 2024
d459308
Organize each component into its appropriate namespace
Ahmed-Ghanam Oct 2, 2024
6b9c2f3
Remove the unused dependencies and improve the service collection ext…
Ahmed-Ghanam Oct 2, 2024
da1535b
Implement a simple validation logic
Ahmed-Ghanam Oct 2, 2024
4be6d04
Specify the expected request and response content types
Ahmed-Ghanam Oct 3, 2024
50f9afd
Code refactoring to achieve a clean separation of concerns, enhance f…
Ahmed-Ghanam Oct 3, 2024
f518723
Code refactoring
Ahmed-Ghanam Oct 3, 2024
220239b
Keep the validation in the service layer and use the AutoMapper to mo…
Ahmed-Ghanam Oct 3, 2024
17ee5f4
Merge branch 'main' into feature/192-krr-endpoints
Ahmed-Ghanam Oct 3, 2024
393fa8b
Add a number of unit tests
Ahmed-Ghanam Oct 3, 2024
7cf18d6
Merge branch 'main' into feature/192-krr-endpoints
Ahmed-Ghanam Oct 3, 2024
635fe89
Improve the unit tests
Ahmed-Ghanam Oct 3, 2024
e4b42b1
Code refactoring
Ahmed-Ghanam Oct 4, 2024
98d7786
Add a validation rule to validate national security numbers
Ahmed-Ghanam Oct 4, 2024
5f0cc46
Rearrange core extensions
Ahmed-Ghanam Oct 4, 2024
b595849
Organize the matched SSN and the unmatched SSN in a respone object
Ahmed-Ghanam Oct 4, 2024
0dbe139
Implement validation layer and refactor existing code.
Ahmed-Ghanam Oct 4, 2024
31c2329
Implement a use case for controllers to access and retrieve users’ co…
Ahmed-Ghanam Oct 5, 2024
0399981
Add unit tests for string extension methods
Ahmed-Ghanam Oct 7, 2024
7b1838e
Code refactoring
Ahmed-Ghanam Oct 7, 2024
0280fdf
Remove old unit tests
Ahmed-Ghanam Oct 7, 2024
af75be9
Moved the file ServiceCollectionExtensions to Altinn.Profile.Integrat…
Ahmed-Ghanam Oct 7, 2024
e074f56
Fix typos
Ahmed-Ghanam Oct 7, 2024
02df646
Fix a conflict
Ahmed-Ghanam Oct 7, 2024
3beb232
Rewrite a number of unit tests
Ahmed-Ghanam Oct 7, 2024
2aeb39e
Improve a comment
Ahmed-Ghanam Oct 7, 2024
a260f47
Update the internal endpoint address
Ahmed-Ghanam Oct 7, 2024
62fd873
Shorten the error message
Ahmed-Ghanam Oct 7, 2024
2708b4f
Remove the parameter name argument.
Ahmed-Ghanam Oct 7, 2024
8ca0b59
Remove two unused variables
Ahmed-Ghanam Oct 7, 2024
201732e
Changed the Register name to Person
Ahmed-Ghanam Oct 7, 2024
22264d2
Add the default parameter value defined in the overridden method.
Ahmed-Ghanam Oct 7, 2024
6b3014f
Remove the nameof parameter
Ahmed-Ghanam Oct 7, 2024
6903998
Remove an unnecessary check for null
Ahmed-Ghanam Oct 7, 2024
2d755a4
Rename the service using the table name
Ahmed-Ghanam Oct 7, 2024
3aa73a6
Improve code smell
Ahmed-Ghanam Oct 7, 2024
3723e74
Code refactoring
Ahmed-Ghanam Oct 7, 2024
643d984
Implement two unit tests to validate the functionality of the user co…
Ahmed-Ghanam Oct 8, 2024
9a9a8b6
Fix merge conflicts
Ahmed-Ghanam Oct 8, 2024
b14fe81
Create a new Migration folder and attach the database creation script
Ahmed-Ghanam Oct 8, 2024
ec690a0
Merge branch 'main' into feature/192-krr-endpoints
Ahmed-Ghanam Oct 8, 2024
53dea15
Merge the feature branch that includes the Database schema file
Ahmed-Ghanam Oct 8, 2024
59cca99
Regenerate the data models
Ahmed-Ghanam Oct 8, 2024
0d8eb00
Fix merge conflicts
Ahmed-Ghanam Oct 8, 2024
e4c7c3e
Move the Person class to the entities folder
Ahmed-Ghanam Oct 8, 2024
e64c189
Change the table name from Register to Person
Ahmed-Ghanam Oct 8, 2024
2a7bcf9
Rename a number of classes
Ahmed-Ghanam Oct 8, 2024
16dc240
Rename some classes
Ahmed-Ghanam Oct 8, 2024
b224d14
Rename more classes
Ahmed-Ghanam Oct 8, 2024
0c5b8b2
Code refactoring
Ahmed-Ghanam Oct 8, 2024
2036783
Remove an unnecessary check for null
Ahmed-Ghanam Oct 8, 2024
ecb80aa
Remove an unnecessary check for null
Ahmed-Ghanam Oct 8, 2024
104b446
Add a simple unit test to test the public endpoint
Ahmed-Ghanam Oct 8, 2024
30f5cea
Add a number of unit tests to test the public endpoint
Ahmed-Ghanam Oct 8, 2024
6c23549
Inject a logger to record information whenever an exception occurs
Ahmed-Ghanam Oct 8, 2024
e1fd350
Rename the unit tests
Ahmed-Ghanam Oct 8, 2024
5713989
Check the error message
Ahmed-Ghanam Oct 8, 2024
d7970b6
Implement a single unit test to ensure that the controller does not b…
Ahmed-Ghanam Oct 8, 2024
38640d4
Implement unit tests to verify the functionality of the class respons…
Ahmed-Ghanam Oct 8, 2024
89ba7b9
Implement unit tests to test retrieval of contact details
Ahmed-Ghanam Oct 8, 2024
86babbd
Update the internal endpoint to produce the same result as the extern…
Ahmed-Ghanam Oct 8, 2024
3999344
Fix a typo
Ahmed-Ghanam Oct 8, 2024
5310621
Add three new unit tests
Ahmed-Ghanam Oct 8, 2024
3df44e6
Copy some unit tests from the external controller to the internal one
Ahmed-Ghanam Oct 8, 2024
a1c0938
Change the national identity number
Ahmed-Ghanam Oct 8, 2024
72e15e0
Try to avoid duplicates
Ahmed-Ghanam Oct 8, 2024
23411a1
Check model validity
Ahmed-Ghanam Oct 8, 2024
b3c9ff6
Implement two unit tests to verify the outcome when the data model is…
Ahmed-Ghanam Oct 9, 2024
92d2d99
Rename the unit tests
Ahmed-Ghanam Oct 9, 2024
c40cf77
Update the unit tests to check the returned values
Ahmed-Ghanam Oct 9, 2024
9d5bade
Increase the unit tests to cover valid and invalid national identity …
Ahmed-Ghanam Oct 9, 2024
a48bf37
Use different types
Ahmed-Ghanam Oct 9, 2024
3e11984
Fix an issue introduced in the previous commit
Ahmed-Ghanam Oct 9, 2024
d486bf3
Add the Reservation flag to the test data
Ahmed-Ghanam Oct 9, 2024
7e6f569
Renamed a file
Ahmed-Ghanam Oct 9, 2024
d607540
Add a unit test to test retrieving contact details
Ahmed-Ghanam Oct 9, 2024
4a96d15
Code refactoring
Ahmed-Ghanam Oct 9, 2024
de8f506
Code refactoring
Ahmed-Ghanam Oct 9, 2024
7a51015
Add a missing dot
Ahmed-Ghanam Oct 9, 2024
c29f65a
Rename a folder
Ahmed-Ghanam Oct 9, 2024
b596225
Code refactoring
Ahmed-Ghanam Oct 9, 2024
88b03e0
Cover more use cases
Ahmed-Ghanam Oct 9, 2024
2891cc7
Increase covered use cases
Ahmed-Ghanam Oct 9, 2024
f58eb64
Follow the same naming pattern
Ahmed-Ghanam Oct 9, 2024
4227cbf
Implement a number of simple unit test to test the mapping profile
Ahmed-Ghanam Oct 9, 2024
98813ff
Delete the DROP DATABASE IF EXISTS statement
Ahmed-Ghanam Oct 9, 2024
30dbaa8
Delete an index that could be used to search for person data by a sup…
Ahmed-Ghanam Oct 9, 2024
13de400
Add statements to grant two users, we have, access to the schema
Ahmed-Ghanam Oct 9, 2024
74979bb
Remove the database creation statement
Ahmed-Ghanam Oct 9, 2024
2250863
Regenerate the Person data model
Ahmed-Ghanam Oct 9, 2024
6dc787a
Merge branch 'featur/186-krr-db-schema' into feature/192-krr-endpoints
Ahmed-Ghanam Oct 9, 2024
5a6cfbc
Fix merge conflicts
Ahmed-Ghanam Oct 10, 2024
9262540
Fix merge conflicts
Ahmed-Ghanam Oct 10, 2024
c0e1b12
Fix merge conflcits
Ahmed-Ghanam Oct 10, 2024
7730a39
Fix merge conflicts
Ahmed-Ghanam Oct 14, 2024
71e5c7c
Move the data models to the integration project
Ahmed-Ghanam Oct 14, 2024
3398e40
Fix connection string
SandGrainOne Oct 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions src/Altinn.Profile.Core/Domain/IRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#nullable enable

namespace Altinn.Profile.Core.Domain;

/// <summary>
/// Defines generic methods for handling entities in a repository.
/// </summary>
/// <typeparam name="T">The type of the entity.</typeparam>
public interface IRepository<T>
where T : class
{
/// <summary>
/// Asynchronously retrieves all entities.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains a collection of entities.</returns>
Task<IEnumerable<T>> GetAllAsync();

/// <summary>
/// Asynchronously retrieves entities with optional filtering, sorting, and pagination.
/// </summary>
/// <param name="filter">Optional filter criteria.</param>
/// <param name="orderBy">Optional ordering criteria.</param>
/// <param name="skip">The number of entities to skip.</param>
/// <param name="take">The number of entities to take.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains a collection of filtered, sorted, and paginated entities.</returns>
Task<IEnumerable<T>> GetAsync(
Func<T, bool>? filter = null,
Func<IEnumerable<T>, IOrderedEnumerable<T>>? orderBy = null,
int? skip = null,
int? take = null);

/// <summary>
/// Asynchronously retrieves an entity by its identifier.
/// </summary>
/// <param name="id">The identifier of the entity.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains the entity that matches the identifier.</returns>
Task<T?> GetByIdAsync(string id);

/// <summary>
/// Asynchronously checks if an entity exists by its identifier.
/// </summary>
/// <param name="id">The identifier of the entity.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains a boolean indicating the existence of the entity.</returns>
Task<bool> ExistsAsync(string id);

/// <summary>
/// Asynchronously adds a new entity.
/// </summary>
/// <param name="entity">The entity to add.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains the added entity.</returns>
Task<T> AddAsync(T entity);

/// <summary>
/// Asynchronously adds multiple entities.
/// </summary>
/// <param name="entities">The entities to add.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
Task AddRangeAsync(IEnumerable<T> entities);

/// <summary>
/// Asynchronously updates an existing entity.
/// </summary>
/// <param name="entity">The entity to update.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
Task UpdateAsync(T entity);

/// <summary>
/// Asynchronously updates multiple entities.
/// </summary>
/// <param name="entities">The entities to update.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
Task UpdateRangeAsync(IEnumerable<T> entities);

/// <summary>
/// Asynchronously deletes an entity by its identifier.
/// </summary>
/// <param name="id">The identifier of the entity to delete.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
Task DeleteAsync(string id);

/// <summary>
/// Asynchronously deletes multiple entities by their identifiers.
/// </summary>
/// <param name="ids">The identifiers of the entities to delete.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
Task DeleteRangeAsync(IEnumerable<string> ids);

/// <summary>
/// Saves changes to the data source asynchronously.
/// </summary>
/// <returns>A task that represents the asynchronous save operation. The task result contains the number of state entries written to the data source.</returns>
Task<int> SaveChangesAsync();
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Altinn.Profile.Core;
namespace Altinn.Profile.Core.Extensions;

/// <summary>
/// Extension class for <see cref="IServiceCollection"/>
Expand Down
178 changes: 178 additions & 0 deletions src/Altinn.Profile.Core/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
using System.Collections.Concurrent;
using System.Globalization;
using System.Text.RegularExpressions;

namespace Altinn.Profile.Core.Extensions;

/// <summary>
/// Extension class for <see cref="string"/> to add more members.
/// </summary>
public static partial class StringExtensions
{
/// <summary>
/// Determines whether a given string consists of only digits.
/// </summary>
/// <param name="input">The string to check.</param>
/// <returns>
/// <c>true</c> if the given string consists of only digits; otherwise, <c>false</c>.
/// </returns>
/// <remarks>
/// This method checks if the provided string is not null or whitespace and matches the regex pattern for digits.
/// The regex pattern ensures that the string contains only numeric characters (0-9).
/// </remarks>
public static bool IsDigitsOnly(this string input)
{
if (string.IsNullOrWhiteSpace(input))
{
return false;
}

return DigitsOnlyRegex().IsMatch(input);
}

/// <summary>
/// Removes all whitespace characters from the given string.
/// </summary>
/// <param name="stringToClean">The string from which to remove whitespace characters.</param>
/// <returns>
/// A new string with all whitespace characters removed.
/// If the input is null, empty, or consists only of whitespace, the original input is returned.
/// </returns>
public static string? RemoveWhitespace(this string stringToClean)
{
if (string.IsNullOrWhiteSpace(stringToClean))
{
return stringToClean?.Trim();
}

return WhitespaceRegex().Replace(stringToClean, string.Empty);
}

/// <summary>
/// Determines whether a given string represents a valid format for a Norwegian Social Security Number (SSN).
/// </summary>
/// <param name="socialSecurityNumber">The Norwegian Social Security Number (SSN) to validate.</param>
/// <param name="controlDigits">Indicates whether to validate the control digits.</param>
/// <returns>
/// <c>true</c> if the given string represents a valid format for a Norwegian Social Security Number (SSN) and, if specified, the control digits are valid; otherwise, <c>false</c>.
/// </returns>
/// <remarks>
/// A valid Norwegian Social Security Number (SSN) is an 11-digit number where:
/// - The first six digits represent the date of birth in the format DDMMYY.
/// - The next three digits are an individual number where the first digit indicates the century of birth.
/// - The last two digits are control digits.
/// </remarks>
/// <exception cref="FormatException">Thrown when the individual number part of the SSN cannot be parsed into an integer.</exception>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the parsed date is outside the range of DateTime.</exception>
public static bool IsValidSocialSecurityNumber(this string socialSecurityNumber, bool controlDigits = true)
{
if (string.IsNullOrWhiteSpace(socialSecurityNumber) || socialSecurityNumber.Length != 11)
{
return false;
}

// Return the cached result if the given string has been checked once.
if (CachedSocialSecurityNumber.TryGetValue(socialSecurityNumber, out var cachedResult))
{
return cachedResult;
}

ReadOnlySpan<char> socialSecurityNumberSpan = socialSecurityNumber.AsSpan();

for (int i = 0; i < socialSecurityNumberSpan.Length; i++)
{
if (!char.IsDigit(socialSecurityNumberSpan[i]))
{
return false;
}
}

// Extract parts of the Social Security Number (SSN) using slicing.
ReadOnlySpan<char> datePart = socialSecurityNumberSpan[..6];
ReadOnlySpan<char> controlDigitsPart = socialSecurityNumberSpan[9..11];
ReadOnlySpan<char> individualNumberPart = socialSecurityNumberSpan[6..9];

// If parsing the individual number part fails, return false.
if (!int.TryParse(individualNumberPart, out _))
{
return false;
}

// Validate the date part.
if (!DateTime.TryParseExact(datePart.ToString(), "ddMMyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out _))
{
return false;
}

var isValidSocialSecurityNumber = !controlDigits || CalculateControlDigits(socialSecurityNumberSpan[..9].ToString()) == controlDigitsPart.ToString();

CachedSocialSecurityNumber.TryAdd(socialSecurityNumber, isValidSocialSecurityNumber);

return isValidSocialSecurityNumber;
}

/// <summary>
/// Calculates the control digits used to validate a Norwegian Social Security Number.
/// </summary>
/// <param name="firstNineDigits">The first nine digits of the Social Security Number.</param>
/// <returns>A <see cref="string"/> represents the two control digits.</returns>
private static string CalculateControlDigits(string firstNineDigits)
{
int[] weightsFirst = [3, 7, 6, 1, 8, 9, 4, 5, 2];

int[] weightsSecond = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];

int firstControlDigit = CalculateControlDigit(firstNineDigits, weightsFirst);

int secondControlDigit = CalculateControlDigit(firstNineDigits + firstControlDigit, weightsSecond);

return $"{firstControlDigit}{secondControlDigit}";
}

/// <summary>
/// Calculates a control digit using the specified weights.
/// </summary>
/// <param name="digits">The digits to use in the calculation.</param>
/// <param name="weights">The weights for each digit.</param>
/// <returns>An <see cref="int"/> represents the calculated control digit.</returns>
private static int CalculateControlDigit(string digits, int[] weights)
{
int sum = 0;

for (int i = 0; i < weights.Length; i++)
{
sum += (int)char.GetNumericValue(digits[i]) * weights[i];
}

int remainder = sum % 11;
return remainder == 0 ? 0 : 11 - remainder;
}

/// <summary>
/// Generates a compiled regular expression for matching all whitespace characters in a string.
/// </summary>
/// <returns>
/// A <see cref="Regex"/> object that can be used to match all whitespace characters in a string.
/// </returns>
[GeneratedRegex(@"\s+", RegexOptions.Compiled)]
private static partial Regex WhitespaceRegex();

/// <summary>
/// Generates a compiled regular expression for validating that a string consists of only digits.
/// </summary>
/// <returns>
/// A <see cref="Regex"/> object that can be used to validate that a string contains only digits.
/// </returns>
[GeneratedRegex(@"^\d+$", RegexOptions.Compiled)]
private static partial Regex DigitsOnlyRegex();

/// <summary>
/// A cache for storing the validation results of Norwegian Social Security Numbers (SSNs).
/// </summary>
/// <remarks>
/// This cache helps to avoid redundant validation checks for SSNs that have already been processed.
/// It maps the SSN as a string to a boolean indicating whether the SSN is valid (true) or not (false).
/// Utilizing this cache can significantly improve performance for applications that frequently validate the same SSNs.
/// </remarks>
private static ConcurrentDictionary<string, bool> CachedSocialSecurityNumber => new();
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class UserContactPointAvailability
public int UserId { get; set; }

/// <summary>
/// Gets or sets the national identityt number of the user
/// Gets or sets the national identity number of the user
/// </summary>
public string NationalIdentityNumber { get; set; } = string.Empty;

Expand All @@ -37,7 +37,7 @@ public class UserContactPointAvailability
public class UserContactPointAvailabilityList
{
/// <summary>
/// A list containing contact point availabiliy for users
/// A list containing contact point availability for users
/// </summary>
public List<UserContactPointAvailability> AvailabilityList { get; set; } = [];
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="8.0.8" />
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.8" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Altinn.Profile.Core\Altinn.Profile.Core.csproj" />
<InternalsVisibleTo Include="Altinn.Profile.Tests" />
</ItemGroup>

<ItemGroup Condition="'$(Configuration)'=='Debug'">
Expand Down
34 changes: 34 additions & 0 deletions src/Altinn.Profile.Integrations/Entities/IPersonContactDetails.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#nullable enable

namespace Altinn.Profile.Integrations.Entities;

/// <summary>
/// Represents a person's contact details.
/// </summary>
public interface IPersonContactDetails
{
/// <summary>
/// Gets the national identity number of the person.
/// </summary>
string NationalIdentityNumber { get; }

/// <summary>
/// Gets a value indicating whether the person opts out of being contacted.
/// </summary>
bool? IsReserved { get; }

/// <summary>
/// Gets the mobile phone number of the person.
/// </summary>
string? MobilePhoneNumber { get; }

/// <summary>
/// Gets the email address of the person.
/// </summary>
string? EmailAddress { get; }

/// <summary>
/// Gets the language code of the person, represented as an ISO 639-1 code.
/// </summary>
string? LanguageCode { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#nullable enable

using System.Collections.Immutable;

namespace Altinn.Profile.Integrations.Entities;

/// <summary>
/// Represents the result of a lookup operation for contact details.
/// </summary>
public interface IPersonContactDetailsLookupResult
{
/// <summary>
/// Gets a list of national identity numbers that could not be matched with any person contact details.
/// </summary>
/// <value>
/// An <see cref="ImmutableList{T}"/> of <see cref="string"/> containing the unmatched national identity numbers.
/// </value>
ImmutableList<string>? UnmatchedNationalIdentityNumbers { get; }

/// <summary>
/// Gets a list of person contact details that were successfully matched during the lookup.
/// </summary>
/// <value>
/// An <see cref="ImmutableList{T}"/> of <see cref="IPersonContactDetails"/> containing the matched person contact details.
/// </value>
ImmutableList<IPersonContactDetails>? MatchedPersonContactDetails { get; }
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
#nullable disable

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

using Microsoft.EntityFrameworkCore;

namespace Altinn.Profile.Models;
namespace Altinn.Profile.Integrations.Entities;

/// <summary>
/// Represents a mailbox supplier in the contact and reservation schema.
Expand Down
Loading
Loading