Skip to content

Mirror ModerationCase entities to SQL. - #9717

Merged
isoos merged 4 commits into
dart-lang:mainfrom
isoos:moderation-case
Oct 19, 2026
Merged

isoos merged 4 commits into
dart-lang:mainfrom
isoos:moderation-case

Conversation

@isoos

@isoos isoos commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator

@isoos
isoos requested review from jonasfj and sigurdm October 16, 2026 15:32

@sigurdm sigurdm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM!

Now that 000021_moderation_case.sql is in this PR and rebased on #9720, we could also uncomment 'moderation-cases-chk-resolved' and 'moderation-cases-fk-appealed' in app/lib/admin/actions/migrate_dry_run.dart (and drop - Also includes the commit from #9714 from the PR description).

Comment thread app/lib/admin/backend.dart Outdated
Comment on lines +940 to +952
for (var i = 0; i < entries.length; i++) {
final e = entries[i];
await db.moderationActionLogs
.upsertValue(
caseId: mc.caseId,
logId: Ulid(millis: e.timestamp.millisecondsSinceEpoch).toUuid(),
createdAt: e.timestamp,
subject: e.subject,
action: e.moderationAction.name,
note: e.note,
)
.execute();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ulid(millis: ...) uses the default UlidFactory() where monotonic is false, so each call draws 80 fresh random bits. If two action log entries share the same millisecond (e.g. under a fixed clock in tests, or if two iterations of the loop in moderation_case_sql_test.dart execute within the same millisecond), there is a 50% chance their logIds sort in the opposite order of entries, causing _isModerationCaseInSql to return false and expectModerationCasesInSqlMatchDatastore() to flake.

Could we use a local monotonic UlidFactory here (and drop the unused loop index i)?

Suggested change
for (var i = 0; i < entries.length; i++) {
final e = entries[i];
await db.moderationActionLogs
.upsertValue(
caseId: mc.caseId,
logId: Ulid(millis: e.timestamp.millisecondsSinceEpoch).toUuid(),
createdAt: e.timestamp,
subject: e.subject,
action: e.moderationAction.name,
note: e.note,
)
.execute();
}
final ulidFactory = UlidFactory(
monotonic: true,
monotonicBufferBits: 1,
incrementMillisOnOverflow: true,
);
for (final e in entries) {
await db.moderationActionLogs
.insertValue(
caseId: mc.caseId,
logId: ulidFactory
.next(millis: e.timestamp.millisecondsSinceEpoch)
.toUuid(),
createdAt: e.timestamp,
subject: e.subject,
action: e.moderationAction.name,
note: e.note,
)
.execute();
}

Comment on lines +78 to +79
final mc = await adminBackend.lookupModerationCase(caseId);
await adminBackend.mirrorModerationCaseToSqlById(caseId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: since mc was just looked up on line 78 (and similarly returned from the transaction in moderation_case_resolve.dart:131), we can pass mc! directly to mirrorModerationCaseToSql(mc) to avoid a second Datastore lookup:

Suggested change
final mc = await adminBackend.lookupModerationCase(caseId);
await adminBackend.mirrorModerationCaseToSqlById(caseId);
final mc = (await adminBackend.lookupModerationCase(caseId))!;
await adminBackend.mirrorModerationCaseToSql(mc);

@isoos
isoos merged commit 759229b into dart-lang:main Oct 19, 2026
37 checks passed
@isoos
isoos deleted the moderation-case branch October 19, 2026 13:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants