@@ -7,7 +7,6 @@ import 'package:flutter_news_app_api_server_full_source_code/src/helpers/respons
77import 'package:flutter_news_app_api_server_full_source_code/src/middlewares/ownership_check_middleware.dart' ;
88import 'package:flutter_news_app_api_server_full_source_code/src/rbac/permission_service.dart' ;
99import 'package:flutter_news_app_api_server_full_source_code/src/registry/model_registry.dart' ;
10- import 'package:flutter_news_app_api_server_full_source_code/src/services/dashboard_summary_service.dart' ;
1110import 'package:flutter_news_app_api_server_full_source_code/src/services/user_preference_limit_service.dart' ;
1211import 'package:logging/logging.dart' ;
1312
@@ -31,38 +30,20 @@ Future<Response> onRequest(RequestContext context, String id) async {
3130
3231// --- GET Handler ---
3332/// Handles GET requests: Retrieves a single item by its ID.
33+ ///
34+ /// This handler can safely assume that the requested item has already been
35+ /// fetched, validated, and provided in the context by the upstream
36+ /// `dataFetchMiddleware` . Its primary role is to construct the success
37+ /// response.
3438Future <Response > _handleGet (RequestContext context, String id) async {
3539 final modelName = context.read <String >();
36- final modelConfig = context.read <ModelConfig <dynamic >>();
37- final authenticatedUser = context.read <User >();
38- final permissionService = context.read <PermissionService >();
39-
4040 _logger.info (
4141 'Handling GET request for model "$modelName ", id "$id ".' ,
4242 );
4343
44- dynamic item;
45- final fetchedItem = context.read <FetchedItem <dynamic >?>();
46-
47- if (fetchedItem != null ) {
48- _logger.finer ('Item was pre-fetched by middleware.' );
49- item = fetchedItem.data;
50- } else {
51- _logger.finer ('Item not pre-fetched, calling _readItem helper.' );
52- final userIdForRepoCall = _getUserIdForRepoCall (
53- modelConfig: modelConfig,
54- permissionService: permissionService,
55- authenticatedUser: authenticatedUser,
56- );
57- item = await _readItem (context, modelName, id, userIdForRepoCall);
58- }
59-
60- _logger.finer ('Item fetch completed. Result: ${item == null ? "null" : "found" }.' );
61-
62- // This check is now crucial for preventing the NoSuchMethodError on null.
63- if (item == null ) {
64- throw NotFoundException ('Item with id "$id " not found.' );
65- }
44+ // The item is guaranteed to be present by the dataFetchMiddleware.
45+ final item = context.read <FetchedItem <dynamic >>().data;
46+ _logger.finer ('Item was pre-fetched by middleware. Preparing response.' );
6647
6748 return ResponseHelper .success (
6849 context: context,
@@ -192,83 +173,6 @@ String? _getUserIdForRepoCall({
192173 : null ;
193174}
194175
195- /// Encapsulates the logic for reading a single item by its type.
196- Future <dynamic > _readItem (
197- RequestContext context,
198- String modelName,
199- String id,
200- String ? userId,
201- ) async {
202- _logger.finer (
203- 'Executing _readItem for model "$modelName ", id "$id ", userId: $userId .' ,
204- );
205- try {
206- switch (modelName) {
207- case 'headline' :
208- return await context.read <DataRepository <Headline >>().read (
209- id: id,
210- userId: userId,
211- );
212- case 'topic' :
213- return await context
214- .read <DataRepository <Topic >>()
215- .read (id: id, userId: userId);
216- case 'source' :
217- return await context.read <DataRepository <Source >>().read (
218- id: id,
219- userId: userId,
220- );
221- case 'country' :
222- return await context.read <DataRepository <Country >>().read (
223- id: id,
224- userId: userId,
225- );
226- case 'language' :
227- return await context.read <DataRepository <Language >>().read (
228- id: id,
229- userId: userId,
230- );
231- case 'user' :
232- return await context
233- .read <DataRepository <User >>()
234- .read (id: id, userId: userId);
235- case 'user_app_settings' :
236- return await context.read <DataRepository <UserAppSettings >>().read (
237- id: id,
238- userId: userId,
239- );
240- case 'user_content_preferences' :
241- return await context.read <DataRepository <UserContentPreferences >>().read (
242- id: id,
243- userId: userId,
244- );
245- case 'remote_config' :
246- return await context.read <DataRepository <RemoteConfig >>().read (
247- id: id,
248- userId: userId,
249- );
250- case 'dashboard_summary' :
251- return await context.read <DashboardSummaryService >().getSummary ();
252- default :
253- _logger.warning ('Unsupported model type "$modelName " for read operation.' );
254- throw OperationFailedException (
255- 'Unsupported model type "$modelName " for read operation.' ,
256- );
257- }
258- } catch (e, s) {
259- _logger.severe (
260- 'Unhandled exception in _readItem for model "$modelName ", id "$id ".' ,
261- e,
262- s,
263- );
264- // Re-throw as a standard exception type that the main error handler
265- // can process into a 500 error, while preserving the original cause.
266- throw OperationFailedException (
267- 'An internal error occurred while reading the item: $e ' ,
268- );
269- }
270- }
271-
272176/// Encapsulates the logic for updating an item by its type.
273177Future <dynamic > _updateItem (
274178 RequestContext context,
0 commit comments