Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 20 additions & 0 deletions lib/src/registry/data_operation_registry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,26 @@ class DataOperationRegistry {
);
}

// Business Logic Check: Ensure a user can only have one engagement
// per headline to prevent duplicate reactions or comments.
final engagementRepository = context.read<DataRepository<Engagement>>();
final existingEngagements = await engagementRepository.readAll(
filter: {
'userId': authenticatedUser.id,
'entityId': engagementToCreate.entityId,
'entityType': engagementToCreate.entityType.name,
},
);

if (existingEngagements.items.isNotEmpty) {
_log.warning(
'User ${authenticatedUser.id} attempted to create a second engagement for entity ${engagementToCreate.entityId}.',
);
throw const ConflictException(
'An engagement for this item already exists.',
);
}

// Limit Check: Delegate to the centralized service.
await userActionLimitService.checkEngagementCreationLimit(
user: authenticatedUser,
Expand Down
44 changes: 29 additions & 15 deletions lib/src/services/default_user_action_limit_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -265,24 +265,35 @@ class DefaultUserActionLimitService implements UserActionLimitService {
);
}

// Count all engagements in the last 24 hours for the reaction limit.
final twentyFourHoursAgo = DateTime.now().subtract(
const Duration(hours: 24),
);
final reactionCount = await _engagementRepository.count(
filter: {
'userId': user.id,
'createdAt': {r'$gte': twentyFourHoursAgo.toIso8601String()},
},
);
// --- 1. Check Reaction Limit (only if a reaction is present) ---
if (engagement.reaction != null) {
final reactionsLimit = limits.reactionsPerDay[user.appRole];
if (reactionsLimit == null) {
throw StateError(
'Reactions per day limit not configured for role: ${user.appRole}',
);
}

if (reactionCount >= reactionsLimit) {
_log.warning(
'User ${user.id} exceeded reactions per day limit: $reactionsLimit.',
// Count engagements with reactions in the last 24 hours.
final twentyFourHoursAgo = DateTime.now().subtract(
const Duration(hours: 24),
);
throw const ForbiddenException(
'You have reached your daily limit for reactions.',
final reactionCount = await _engagementRepository.count(
filter: {
'userId': user.id,
'reaction': {r'$exists': true, r'$ne': null},
'createdAt': {r'$gte': twentyFourHoursAgo.toIso8601String()},
},
);

if (reactionCount >= reactionsLimit) {
_log.warning(
'User ${user.id} exceeded reactions per day limit: $reactionsLimit.',
);
throw const ForbiddenException(
'You have reached your daily limit for reactions.',
);
}
}

// --- 2. Check Comment Limit (only if a comment is present) ---
Expand All @@ -295,6 +306,9 @@ class DefaultUserActionLimitService implements UserActionLimitService {
}

// Count engagements with comments in the last 24 hours.
final twentyFourHoursAgo = DateTime.now().subtract(
const Duration(hours: 24),
);
final commentCount = await _engagementRepository.count(
filter: {
'userId': user.id,
Expand Down
4 changes: 2 additions & 2 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,8 @@ packages:
dependency: "direct main"
description:
path: "."
ref: "8bae6eb17369b76f72961870a22ee13d3073fa61"
resolved-ref: "8bae6eb17369b76f72961870a22ee13d3073fa61"
ref: e66e076572bd326e50e9d5286ef5059ff658ed65
resolved-ref: e66e076572bd326e50e9d5286ef5059ff658ed65
url: "https://github.com/flutter-news-app-full-source-code/core.git"
source: git
version: "1.3.1"
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ dependency_overrides:
core:
git:
url: https://github.com/flutter-news-app-full-source-code/core.git
ref: 8bae6eb17369b76f72961870a22ee13d3073fa61
ref: e66e076572bd326e50e9d5286ef5059ff658ed65
data_mongodb:
git:
url: https://github.com/flutter-news-app-full-source-code/data-mongodb.git
Expand Down
Loading