From f20db24d5a404648ed93986cfb5ddcce6cc632bf Mon Sep 17 00:00:00 2001 From: Istvan Soos Date: Thu, 4 Apr 2024 17:07:13 +0200 Subject: [PATCH 1/4] ModerationCase entity --- app/lib/admin/models.dart | 87 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 app/lib/admin/models.dart diff --git a/app/lib/admin/models.dart b/app/lib/admin/models.dart new file mode 100644 index 0000000000..227e1618a9 --- /dev/null +++ b/app/lib/admin/models.dart @@ -0,0 +1,87 @@ +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:clock/clock.dart'; +import 'package:pub_dev/shared/utils.dart'; + +import '../shared/datastore.dart' as db; + +/// Tracks the status of the moderation or appeal case. +@db.Kind(name: 'ModerationCase', idType: db.IdType.String) +class ModerationCase extends db.ExpandoModel { + /// Same as [id]. + /// A random UUID id. + String get caseId => id!; + + /// The `userId` of the reporter (may be null for non-authenticated reporter). + @db.StringProperty() + String? reporterUserId; + + /// The email of the reporter. + @db.StringProperty(required: true) + late String reporterEmail; + + /// The case was opened at this time. + @db.DateTimeProperty(required: true) + late DateTime opened; + + /// The case was resolved at this time (or null if it has not been resolved yet). + @db.DateTimeProperty() + DateTime? resolved; + + /// The source of the case, one of: + /// - `external-notification`, + /// - `internal-notification` (only used for reports from @google.com accounts), or, + /// - `automated-detection. (will not be used) + @db.StringProperty(required: true) + late String detectedBy; + + /// The kind of the case, one of: + /// - `notification`, or, + /// - `appeal` + @db.StringProperty(required: true) + late String kind; + + /// The package this notification or appeal concerns. + /// In the case of an appeal, reporter must be owner of said package. + @db.StringProperty() + String? subjectPackage; + + /// The publisher this notification or appeal concerns. + /// In the case of an appeal, reporter must be a member of said publisher. + @db.StringProperty() + String? subjectPublisher; + + /// The `caseId` of the appeal (or null). + @db.StringProperty() + String? appealedCaseId; + + /// One of: + /// - `no-action`, if this is a notification (kind = notification) and + /// we decided to take no action. + /// - `moderation-applied`, if this is a notification (kind = notification) and + /// we decided to apply content moderation. + /// - `no-action-upheld`, if this is an appeal (kind = appeal) of a notification + /// where we took no-action, and we decided to uphold that decision. + /// - `no-action-reverted`, if this is an appeal (kind = appeal) of a notification + /// where we took no-action, and we decided to revert that decision. + /// - `moderation-upheld`, if this is an appeal (kind = appeal) of a notification + /// where we applied content moderation, and we decided to uphold that decision. + /// - `moderation-reverted`, if this is an appeal (kind = appeal) of a notification + /// where we applied content moderation, and we decided to revert that decision. + @db.StringProperty() + String? resolution; + + ModerationCase(); + + ModerationCase.init({ + required this.reporterUserId, + required this.reporterEmail, + required this.detectedBy, + required this.kind, + }) { + id = createUuid(); + opened = clock.now().toUtc(); + } +} From 14c36f78ad701af69f1bff4fb09ee3b9ca8188f1 Mon Sep 17 00:00:00 2001 From: Istvan Soos Date: Fri, 5 Apr 2024 10:45:18 +0200 Subject: [PATCH 2/4] pending + required --- app/lib/admin/models.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/lib/admin/models.dart b/app/lib/admin/models.dart index 227e1618a9..bce6a56218 100644 --- a/app/lib/admin/models.dart +++ b/app/lib/admin/models.dart @@ -58,6 +58,7 @@ class ModerationCase extends db.ExpandoModel { String? appealedCaseId; /// One of: + /// - `pending`, if this is an appeal and we haven't decided anything yet. /// - `no-action`, if this is a notification (kind = notification) and /// we decided to take no action. /// - `moderation-applied`, if this is a notification (kind = notification) and @@ -70,7 +71,7 @@ class ModerationCase extends db.ExpandoModel { /// where we applied content moderation, and we decided to uphold that decision. /// - `moderation-reverted`, if this is an appeal (kind = appeal) of a notification /// where we applied content moderation, and we decided to revert that decision. - @db.StringProperty() + @db.StringProperty(required: true) String? resolution; ModerationCase(); From 09834aef3e9d14170140081eb7ec303a96b4be48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Istv=C3=A1n=20So=C3=B3s?= Date: Fri, 5 Apr 2024 13:55:59 +0200 Subject: [PATCH 3/4] Update app/lib/admin/models.dart Co-authored-by: Jonas Finnemann Jensen --- app/lib/admin/models.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/admin/models.dart b/app/lib/admin/models.dart index bce6a56218..21114df823 100644 --- a/app/lib/admin/models.dart +++ b/app/lib/admin/models.dart @@ -33,7 +33,7 @@ class ModerationCase extends db.ExpandoModel { /// The source of the case, one of: /// - `external-notification`, /// - `internal-notification` (only used for reports from @google.com accounts), or, - /// - `automated-detection. (will not be used) + /// - `automated-detection`. (will not be used) @db.StringProperty(required: true) late String detectedBy; From 113273eeb571227257df735e4dfcfca69f731c1d Mon Sep 17 00:00:00 2001 From: Istvan Soos Date: Fri, 5 Apr 2024 13:57:30 +0200 Subject: [PATCH 4/4] rename resolution to status --- app/lib/admin/models.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/lib/admin/models.dart b/app/lib/admin/models.dart index 21114df823..7a1f9ba999 100644 --- a/app/lib/admin/models.dart +++ b/app/lib/admin/models.dart @@ -72,7 +72,7 @@ class ModerationCase extends db.ExpandoModel { /// - `moderation-reverted`, if this is an appeal (kind = appeal) of a notification /// where we applied content moderation, and we decided to revert that decision. @db.StringProperty(required: true) - String? resolution; + String? status; ModerationCase(); @@ -81,6 +81,7 @@ class ModerationCase extends db.ExpandoModel { required this.reporterEmail, required this.detectedBy, required this.kind, + required this.status, }) { id = createUuid(); opened = clock.now().toUtc();