Skip to content

Commit 5f16d60

Browse files
authored
Merge pull request #107 from flutter-news-app-full-source-code/feat/enforce-user-content-business-logic
Feat/enforce user content business logic
2 parents ed24227 + b28f8d3 commit 5f16d60

File tree

4 files changed

+52
-18
lines changed

4 files changed

+52
-18
lines changed

lib/src/registry/data_operation_registry.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,26 @@ class DataOperationRegistry {
318318
);
319319
}
320320

321+
// Business Logic Check: Ensure a user can only have one engagement
322+
// per headline to prevent duplicate reactions or comments.
323+
final engagementRepository = context.read<DataRepository<Engagement>>();
324+
final existingEngagements = await engagementRepository.readAll(
325+
filter: {
326+
'userId': authenticatedUser.id,
327+
'entityId': engagementToCreate.entityId,
328+
'entityType': engagementToCreate.entityType.name,
329+
},
330+
);
331+
332+
if (existingEngagements.items.isNotEmpty) {
333+
_log.warning(
334+
'User ${authenticatedUser.id} attempted to create a second engagement for entity ${engagementToCreate.entityId}.',
335+
);
336+
throw const ConflictException(
337+
'An engagement for this item already exists.',
338+
);
339+
}
340+
321341
// Limit Check: Delegate to the centralized service.
322342
await userActionLimitService.checkEngagementCreationLimit(
323343
user: authenticatedUser,

lib/src/services/default_user_action_limit_service.dart

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -265,24 +265,35 @@ class DefaultUserActionLimitService implements UserActionLimitService {
265265
);
266266
}
267267

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

279-
if (reactionCount >= reactionsLimit) {
280-
_log.warning(
281-
'User ${user.id} exceeded reactions per day limit: $reactionsLimit.',
277+
// Count engagements with reactions in the last 24 hours.
278+
final twentyFourHoursAgo = DateTime.now().subtract(
279+
const Duration(hours: 24),
282280
);
283-
throw const ForbiddenException(
284-
'You have reached your daily limit for reactions.',
281+
final reactionCount = await _engagementRepository.count(
282+
filter: {
283+
'userId': user.id,
284+
'reaction': {r'$exists': true, r'$ne': null},
285+
'createdAt': {r'$gte': twentyFourHoursAgo.toIso8601String()},
286+
},
285287
);
288+
289+
if (reactionCount >= reactionsLimit) {
290+
_log.warning(
291+
'User ${user.id} exceeded reactions per day limit: $reactionsLimit.',
292+
);
293+
throw const ForbiddenException(
294+
'You have reached your daily limit for reactions.',
295+
);
296+
}
286297
}
287298

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

297308
// Count engagements with comments in the last 24 hours.
309+
final twentyFourHoursAgo = DateTime.now().subtract(
310+
const Duration(hours: 24),
311+
);
298312
final commentCount = await _engagementRepository.count(
299313
filter: {
300314
'userId': user.id,

pubspec.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,8 @@ packages:
181181
dependency: "direct main"
182182
description:
183183
path: "."
184-
ref: "8bae6eb17369b76f72961870a22ee13d3073fa61"
185-
resolved-ref: "8bae6eb17369b76f72961870a22ee13d3073fa61"
184+
ref: e66e076572bd326e50e9d5286ef5059ff658ed65
185+
resolved-ref: e66e076572bd326e50e9d5286ef5059ff658ed65
186186
url: "https://github.com/flutter-news-app-full-source-code/core.git"
187187
source: git
188188
version: "1.3.1"

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ dependency_overrides:
6262
core:
6363
git:
6464
url: https://github.com/flutter-news-app-full-source-code/core.git
65-
ref: 8bae6eb17369b76f72961870a22ee13d3073fa61
65+
ref: e66e076572bd326e50e9d5286ef5059ff658ed65
6666
data_mongodb:
6767
git:
6868
url: https://github.com/flutter-news-app-full-source-code/data-mongodb.git

0 commit comments

Comments
 (0)