Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Integrate local ad polymorphic collection into teh data route #55

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
9 commits
Select commit Hold shift + click to select a range
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
11 changes: 11 additions & 0 deletions lib/src/config/app_dependencies.dart
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class AppDependencies {
late final DataRepository<UserContentPreferences>
userContentPreferencesRepository;
late final DataRepository<RemoteConfig> remoteConfigRepository;
late final DataRepository<LocalAd> localAdRepository;
late final EmailRepository emailRepository;

// Services
Expand Down Expand Up @@ -201,6 +202,16 @@ class AppDependencies {

emailRepository = EmailRepository(emailClient: emailClient);

final localAdClient = DataMongodb<LocalAd>(
connectionManager: _mongoDbConnectionManager,
modelName: 'local_ads',
fromJson: LocalAd.fromJson,
toJson: LocalAd.toJson,
searchableFields: ['title'],
logger: Logger('DataMongodb<LocalAd>'),
);
localAdRepository = DataRepository(dataClient: localAdClient);

// 5. Initialize Services
tokenBlacklistService = MongoDbTokenBlacklistService(
connectionManager: _mongoDbConnectionManager,
Expand Down
6 changes: 6 additions & 0 deletions lib/src/rbac/permissions.dart
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ abstract class Permissions {
static const String userPreferenceBypassLimits =
'user_preference.bypass_limits';

// Local Ad Permissions
static const String localAdCreate = 'local_ad.create';
static const String localAdRead = 'local_ad.read';
static const String localAdUpdate = 'local_ad.update';
static const String localAdDelete = 'local_ad.delete';

// General System Permissions
static const String rateLimitingBypass = 'rate_limiting.bypass';
}
6 changes: 6 additions & 0 deletions lib/src/rbac/role_permissions.dart
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ final Set<String> _appGuestUserPermissions = {
Permissions.userContentPreferencesReadOwned,
Permissions.userContentPreferencesUpdateOwned,
Permissions.remoteConfigRead,
Permissions.localAdRead,
// Allows a user to update their own User object. This is essential for
// features like updating the `feedActionStatus` (e.g., when a user
// dismisses an in-feed prompt, etc). The endpoint handler ensures only
Expand Down Expand Up @@ -72,6 +73,11 @@ final Set<String> _dashboardAdminPermissions = {
Permissions.remoteConfigUpdate,
Permissions.remoteConfigDelete,
Permissions.userPreferenceBypassLimits,
// Added localAd CRUD permissions for admins
Permissions.localAdCreate,
Permissions.localAdRead,
Permissions.localAdUpdate,
Permissions.localAdDelete,
};

/// Defines the mapping between user roles (both app and dashboard) and the
Expand Down
14 changes: 14 additions & 0 deletions lib/src/registry/data_operation_registry.dart
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ class DataOperationRegistry {
.read(id: id, userId: null),
'remote_config': (c, id) =>
c.read<DataRepository<RemoteConfig>>().read(id: id, userId: null),
'local_ad': (c, id) =>
c.read<DataRepository<LocalAd>>().read(id: id, userId: null),
'dashboard_summary': (c, id) =>
c.read<DashboardSummaryService>().getSummary(),
});
Expand Down Expand Up @@ -159,6 +161,9 @@ class DataOperationRegistry {
sort: s,
pagination: p,
),
'local_ad': (c, uid, f, s, p) => c
.read<DataRepository<LocalAd>>()
.readAll(userId: uid, filter: f, sort: s, pagination: p),
});

// --- Register Item Creators ---
Expand Down Expand Up @@ -186,6 +191,10 @@ class DataOperationRegistry {
'remote_config': (c, item, uid) => c
.read<DataRepository<RemoteConfig>>()
.create(item: item as RemoteConfig, userId: uid),
'local_ad': (c, item, uid) => c.read<DataRepository<LocalAd>>().create(
item: item as LocalAd,
userId: uid,
),
});

// --- Register Item Updaters ---
Expand Down Expand Up @@ -228,6 +237,9 @@ class DataOperationRegistry {
'remote_config': (c, id, item, uid) => c
.read<DataRepository<RemoteConfig>>()
.update(id: id, item: item as RemoteConfig, userId: uid),
'local_ad': (c, id, item, uid) => c
.read<DataRepository<LocalAd>>()
.update(id: id, item: item as LocalAd, userId: uid),
});

// --- Register Item Deleters ---
Expand All @@ -251,6 +263,8 @@ class DataOperationRegistry {
.delete(id: id, userId: uid),
'remote_config': (c, id, uid) =>
c.read<DataRepository<RemoteConfig>>().delete(id: id, userId: uid),
'local_ad': (c, id, uid) =>
c.read<DataRepository<LocalAd>>().delete(id: id, userId: uid),
});
}
}
25 changes: 25 additions & 0 deletions lib/src/registry/model_registry.dart
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,31 @@ final modelRegistry = <String, ModelConfig<dynamic>>{
type: RequiredPermissionType.unsupported,
),
),
'local_ad': ModelConfig<LocalAd>(
fromJson: LocalAd.fromJson,
getId: (ad) => (ad as dynamic).id as String, // Corrected to access id
getOwnerId: null, // LocalAd is a global resource, not user-owned
getCollectionPermission: const ModelActionPermission(
type: RequiredPermissionType.specificPermission,
permission: Permissions.localAdRead,
),
getItemPermission: const ModelActionPermission(
type: RequiredPermissionType.specificPermission,
permission: Permissions.localAdRead,
),
postPermission: const ModelActionPermission(
type: RequiredPermissionType.adminOnly,
permission: Permissions.localAdCreate,
),
putPermission: const ModelActionPermission(
type: RequiredPermissionType.adminOnly,
permission: Permissions.localAdUpdate,
),
deletePermission: const ModelActionPermission(
type: RequiredPermissionType.adminOnly,
permission: Permissions.localAdDelete,
),
),
};

/// Type alias for the ModelRegistry map for easier provider usage.
Expand Down
14 changes: 14 additions & 0 deletions lib/src/services/database_seeding_service.dart
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ class DatabaseSeedingService {
getId: (item) => item.id,
toJson: (item) => item.toJson(),
);
await _seedCollection<LocalAd>(
collectionName: 'local_ads',
fixtureData: localAdsFixturesData,
getId: (item) => (item as dynamic).id as String,
// ignore: unnecessary_lambdas
toJson: (item) => LocalAd.toJson(item),
);

_log.info('Database seeding process completed.');
}
Expand Down Expand Up @@ -131,6 +138,13 @@ class DatabaseSeedingService {
.collection('countries')
.createIndex(keys: {'name': 1}, name: 'countries_name_index');

/// Index for searching local ads by adType.
/// This index supports efficient queries and filtering on the 'adType' field
/// of local ad documents.
await _db
.collection('local_ads')
.createIndex(keys: {'adType': 1}, name: 'local_ads_adType_index');

// --- TTL and Unique Indexes via runCommand ---
// The following indexes are created using the generic `runCommand` because
// they require specific options not exposed by the simpler `createIndex`
Expand Down
5 changes: 5 additions & 0 deletions routes/_middleware.dart
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ Handler middleware(Handler handler) {
(_) => deps.remoteConfigRepository,
),
)
.use(
provider<DataRepository<LocalAd>>(
(_) => deps.localAdRepository,
),
)
.use(provider<EmailRepository>((_) => deps.emailRepository))
.use(
provider<TokenBlacklistService>(
Expand Down
Loading

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /