Skip to content

Conversation

@MH321Productions
Copy link
Contributor

Readiness checklist

  • I added/updated unit tests.
  • I added/updated integration tests.
  • I ensured that the PR title is good enough for the changelog.
  • I labeled the PR.

@MH321Productions MH321Productions self-assigned this Aug 22, 2025
@MH321Productions MH321Productions added the enhancement New feature or request label Aug 22, 2025
Copy link
Member

@tnotheis tnotheis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed in our call, there are 3 bigger topics:

I think there should be tests for this. At least the following:

  1. The check finds a simple address
  2. The check finds an address concatenated with something else

The test should be a unit test. This means that it should NOT run the CLI command. Instead, there should be a class responsible for the check, which is called by the CheckCommand, as well as by the test.


I just had a crazy idea. :) Wouldn't it be awesome if we could run the logic of the check command from within the ActualDeletion job after an identity was deleted? This way we would be notified if there is undeleted data.
But this involves some optimizations in your code. Because currently you read the whole file content (=> the whole database export) into memory. In a production database this would lead to a memory overflow. This means that you would have to refactor your code so that it reads line by line.


You cannot use the export command of the Admin CLI, as the generated files only contain a subset of all data.

docker compose -f ./.ci/compose.test.yml -f ./.ci/compose.test.${{matrix.database.type}}.yml wait admin-cli
- name: Create identities, relationships etc. and initiate deletion processes
run: dotnet run --no-build --no-restore --project ./Applications/IdentityDeletionVerifier/src/IdentityDeletionVerifier/IdentityDeletionVerifier.csproj init --consumerBaseUrl http://localhost:5000 --adminBaseUrl http://localhost:5173
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
run: dotnet run --no-build --no-restore --project ./Applications/IdentityDeletionVerifier/src/IdentityDeletionVerifier/IdentityDeletionVerifier.csproj init --consumerBaseUrl http://localhost:5000 --adminBaseUrl http://localhost:5173
run: dotnet run --no-build --no-restore --project ./Applications/IdentityDeletionVerifier/src/IdentityDeletionVerifier/IdentityDeletionVerifier.csproj init --consumerApiBaseUrl http://localhost:5000 --adminApiBaseUrl http://localhost:5173

using System.Text;
using Backbone.IdentityDeletionVerifier.Commands;

Console.OutputEncoding = Encoding.UTF8;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity: why do we need this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Spectre.Console to be able to write emojis and better spinners

public static readonly string PATH_TO_IDENTITIES_FILE = Path.Combine(PATH_TO_TEMP_DIR, IDENTITIES_FILENAME);

[GeneratedRegex(@"export-\d{8}_\d{6}\.zip$")]
private static partial Regex MyRegex();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weird name

return -1;
}

var a = await GetIdentityToCheck();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weird name

Comment on lines 370 to 371
Database__Provider: Postgres
Database__ConnectionString: "Server=postgres;Database=enmeshed;User Id=devices;Password=Passw0rd;Port=5432"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please stay with the typical config hierarchy, so that

  1. It's consistent
  2. I don't have to provide a separate config during deployment

In this case, this means:

Suggested change
Database__Provider: Postgres
Database__ConnectionString: "Server=postgres;Database=enmeshed;User Id=devices;Password=Passw0rd;Port=5432"
Infrastructure__SqlDatabase__Provider: Postgres
Infrastructure__SqlDatabase__ConnectionString: "Server=postgres;Database=enmeshed;User Id=devices;Password=Passw0rd;Port=5432"

Comment on lines 17 to 21
if (!DirectoryExists())
{
AnsiConsole.MarkupLineInterpolated($"[red bold]The temp directory[/][grey bold]{FilePaths.PATH_TO_TEMP_DIR} [/][red bold]doesn't exist.[/]");
return -1;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IdentitiesFileExists already checks implicitly for the existence of the directory

Comment on lines 47 to 50
private bool DirectoryExists() => Directory.Exists(FilePaths.PATH_TO_TEMP_DIR);
private bool IdentitiesFileExists() => File.Exists(FilePaths.PATH_TO_IDENTITIES_FILE);
private bool ExportFileExists() => Directory.EnumerateFiles(FilePaths.PATH_TO_TEMP_DIR).Any(FilePaths.EXPORT_FILE_PATTERN.IsMatch);
private string GetLatestExportFile() => Directory.EnumerateFiles(FilePaths.PATH_TO_TEMP_DIR).Where(e => FilePaths.EXPORT_FILE_PATTERN.IsMatch(e)).Max()!;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest a (static?) class AppDirectory (I'm not quite happy with the name, maybe you find a better one), which encapsulates the regular expressions and constants for the file paths and has the following methods:

  • Exists() (only if you want to keep the check for the existence of the directoy)
  • IdentitiesFileExists()
  • ExportFileExists()
  • GetLatestExportFile()

return -1;
}

var a = await GetIdentityToCheck();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the name of the method either. How about DoesIdentityFileHaveContent?

Comment on lines 104 to 106
var count = line
.Split(',')
.Count(s => string.Equals(s, identityToCheck, StringComparison.OrdinalIgnoreCase));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a problem with this solution: if the address is concatenated with something else, it doesn't match. I'd suggest:

Suggested change
var count = line
.Split(',')
.Count(s => string.Equals(s, identityToCheck, StringComparison.OrdinalIgnoreCase));
var count = Regex.Matches(line, identityToCheck).Count


if (!IdentitiesFileExists())
{
AnsiConsole.MarkupLine("[red bold]The deleted identities file doesn't exist. Run the Init command first.[/]");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first part of the error message sounds incorrect if you read it without any special knowledge. Because OF COURSE the identities file doesn't exist if it was deleted. 😉

MH321Productions and others added 28 commits September 17, 2025 12:55
@tnotheis tnotheis added the wip Work in Progress label Oct 6, 2025
@tnotheis tnotheis marked this pull request as draft October 6, 2025 07:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request wip Work in Progress

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants