11import 'dart:io' ;
22
33import 'package:dart_frog/dart_frog.dart' ;
4+ import 'package:ht_api/src/helpers/response_helper.dart' ;
45import 'package:ht_api/src/rbac/permission_service.dart' ;
56import 'package:ht_api/src/registry/model_registry.dart' ;
67import 'package:ht_api/src/services/dashboard_summary_service.dart' ;
78import 'package:ht_api/src/services/user_preference_limit_service.dart' ; // Import UserPreferenceLimitService
89import 'package:ht_data_repository/ht_data_repository.dart' ;
910import 'package:ht_shared/ht_shared.dart' ;
1011
11- import '../../../../_middleware.dart' ; // Assuming RequestId is here
12-
1312/// Handles requests for the /api/v1/data/[id] endpoint.
1413/// Dispatches requests to specific handlers based on the HTTP method.
1514Future <Response > onRequest (RequestContext context, String id) async {
1615 // Read dependencies provided by middleware
1716 final modelName = context.read <String >();
1817 final modelConfig = context.read <ModelConfig <dynamic >>();
19- final requestId = context.read <RequestId >().id;
2018 // User is guaranteed non-null by requireAuthentication() middleware
2119 final authenticatedUser = context.read <User >();
2220 final permissionService = context
@@ -35,7 +33,6 @@ Future<Response> onRequest(RequestContext context, String id) async {
3533 modelConfig,
3634 authenticatedUser,
3735 permissionService, // Pass PermissionService
38- requestId,
3936 );
4037 case HttpMethod .put:
4138 return _handlePut (
@@ -46,7 +43,6 @@ Future<Response> onRequest(RequestContext context, String id) async {
4643 authenticatedUser,
4744 permissionService, // Pass PermissionService
4845 userPreferenceLimitService, // Pass the limit service
49- requestId,
5046 );
5147 case HttpMethod .delete:
5248 return _handleDelete (
@@ -56,7 +52,6 @@ Future<Response> onRequest(RequestContext context, String id) async {
5652 modelConfig,
5753 authenticatedUser,
5854 permissionService, // Pass PermissionService
59- requestId,
6055 );
6156 default :
6257 // Methods not allowed on the item endpoint
@@ -74,7 +69,6 @@ Future<Response> _handleGet(
7469 ModelConfig <dynamic > modelConfig,
7570 User authenticatedUser,
7671 PermissionService permissionService,
77- String requestId,
7872) async {
7973 // Authorization check is handled by authorizationMiddleware before this.
8074 // This handler only needs to perform the ownership check if required.
@@ -143,7 +137,7 @@ Future<Response> _handleGet(
143137 // Ensure getOwnerId is provided for models requiring ownership check
144138 if (modelConfig.getOwnerId == null ) {
145139 print (
146- '[ReqID: $ requestId ] Configuration Error: Model "$modelName " requires '
140+ 'Configuration Error: Model "$modelName " requires '
147141 'ownership check for GET item but getOwnerId is not provided.' ,
148142 );
149143 // Throw an exception to be caught by the errorHandler
@@ -162,25 +156,11 @@ Future<Response> _handleGet(
162156 }
163157 }
164158
165- // Create metadata including the request ID and current timestamp
166- final metadata = ResponseMetadata (
167- requestId: requestId,
168- timestamp: DateTime .now ().toUtc (), // Use UTC for consistency
169- );
170-
171- // Wrap the item in SuccessApiResponse with metadata
172- final successResponse = SuccessApiResponse <dynamic >(
159+ return ResponseHelper .success (
160+ context: context,
173161 data: item,
174- metadata : metadata, // Include the created metadata
162+ toJsonT : (data) => (data as dynamic ). toJson () as Map < String , dynamic >,
175163 );
176-
177- // Provide the correct toJsonT for the specific model type
178- final responseJson = successResponse.toJson (
179- (item) => (item as dynamic ).toJson (), // Assuming all models have toJson
180- );
181-
182- // Return 200 OK with the wrapped and serialized response
183- return Response .json (body: responseJson);
184164}
185165
186166// --- PUT Handler ---
@@ -195,7 +175,6 @@ Future<Response> _handlePut(
195175 PermissionService permissionService, // Receive PermissionService
196176 UserPreferenceLimitService
197177 userPreferenceLimitService, // Receive Limit Service
198- String requestId,
199178) async {
200179 // Authorization check is handled by authorizationMiddleware before this.
201180 // This handler only needs to perform the ownership check if required.
@@ -212,9 +191,8 @@ Future<Response> _handlePut(
212191 itemToUpdate = modelConfig.fromJson (requestBody);
213192 } on TypeError catch (e) {
214193 // Catch errors during deserialization (e.g., missing required fields)
215- // Include requestId in the server log
216194 print (
217- '[ReqID: $ requestId ] Deserialization TypeError in PUT /data/[id]: $e ' ,
195+ 'Deserialization TypeError in PUT /data/[id]: $e ' ,
218196 );
219197 // Throw BadRequestException to be caught by the errorHandler
220198 throw const BadRequestException (
@@ -235,8 +213,7 @@ Future<Response> _handlePut(
235213 } catch (e) {
236214 // Ignore if getId throws, means ID might not be in the body,
237215 // which is acceptable depending on the model/client.
238- // Log for debugging if needed.
239- print ('[ReqID: $requestId ] Warning: Could not get ID from PUT body: $e ' );
216+ print ('Warning: Could not get ID from PUT body: $e ' );
240217 }
241218
242219 // --- Handler-Level Limit Check (for UserContentPreferences PUT) ---
@@ -247,7 +224,7 @@ Future<Response> _handlePut(
247224 // Ensure the itemToUpdate is the correct type for the limit service
248225 if (itemToUpdate is ! UserContentPreferences ) {
249226 print (
250- '[ReqID: $ requestId ] Type Error: Expected UserContentPreferences '
227+ 'Type Error: Expected UserContentPreferences '
251228 'for limit check, but got ${itemToUpdate .runtimeType }.' ,
252229 );
253230 throw const OperationFailedException (
@@ -264,7 +241,7 @@ Future<Response> _handlePut(
264241 } catch (e) {
265242 // Catch unexpected errors from the limit service
266243 print (
267- '[ReqID: $ requestId ] Unexpected error during limit check for '
244+ 'Unexpected error during limit check for '
268245 'UserContentPreferences PUT: $e ' ,
269246 );
270247 throw const OperationFailedException (
@@ -381,7 +358,7 @@ Future<Response> _handlePut(
381358 // Ensure getOwnerId is provided for models requiring ownership check
382359 if (modelConfig.getOwnerId == null ) {
383360 print (
384- '[ReqID: $ requestId ] Configuration Error: Model "$modelName " requires '
361+ 'Configuration Error: Model "$modelName " requires '
385362 'ownership check for PUT but getOwnerId is not provided.' ,
386363 );
387364 // Throw an exception to be caught by the errorHandler
@@ -396,9 +373,8 @@ Future<Response> _handlePut(
396373 if (itemOwnerId != authenticatedUser.id) {
397374 // This scenario should ideally not happen if the repository correctly
398375 // enforced ownership during the update call when userId was passed.
399- // But as a defense-in-depth, we check here.
400376 print (
401- '[ReqID: $ requestId ] Ownership check failed AFTER PUT for item $id . '
377+ 'Ownership check failed AFTER PUT for item $id . '
402378 'Item owner: $itemOwnerId , User: ${authenticatedUser .id }' ,
403379 );
404380 // Throw ForbiddenException to be caught by the errorHandler
@@ -408,25 +384,11 @@ Future<Response> _handlePut(
408384 }
409385 }
410386
411- // Create metadata including the request ID and current timestamp
412- final metadata = ResponseMetadata (
413- requestId: requestId,
414- timestamp: DateTime .now ().toUtc (), // Use UTC for consistency
415- );
416-
417- // Wrap the updated item in SuccessApiResponse with metadata
418- final successResponse = SuccessApiResponse <dynamic >(
387+ return ResponseHelper .success (
388+ context: context,
419389 data: updatedItem,
420- metadata : metadata ,
390+ toJsonT : (data) => (data as dynamic ). toJson () as Map < String , dynamic > ,
421391 );
422-
423- // Provide the correct toJsonT for the specific model type
424- final responseJson = successResponse.toJson (
425- (item) => (item as dynamic ).toJson (), // Assuming all models have toJson
426- );
427-
428- // Return 200 OK with the wrapped and serialized response
429- return Response .json (body: responseJson);
430392}
431393
432394// --- DELETE Handler ---
@@ -438,7 +400,6 @@ Future<Response> _handleDelete(
438400 ModelConfig <dynamic > modelConfig,
439401 User authenticatedUser,
440402 PermissionService permissionService,
441- String requestId,
442403) async {
443404 // Authorization check is handled by authorizationMiddleware before this.
444405 // This handler only needs to perform the ownership check if required.
@@ -463,7 +424,7 @@ Future<Response> _handleDelete(
463424 // Ensure getOwnerId is provided for models requiring ownership check
464425 if (modelConfig.getOwnerId == null ) {
465426 print (
466- '[ReqID: $ requestId ] Configuration Error: Model "$modelName " requires '
427+ 'Configuration Error: Model "$modelName " requires '
467428 'ownership check for DELETE but getOwnerId is not provided.' ,
468429 );
469430 // Throw an exception to be caught by the errorHandler
@@ -503,7 +464,7 @@ Future<Response> _handleDelete(
503464 ); // userId should be null for AppConfig
504465 default :
505466 print (
506- '[ReqID: $ requestId ] Error: Unsupported model type "$modelName " reached _handleDelete ownership check.' ,
467+ 'Error: Unsupported model type "$modelName " reached _handleDelete ownership check.' ,
507468 );
508469 // Throw an exception to be caught by the errorHandler
509470 throw OperationFailedException (
@@ -571,9 +532,9 @@ Future<Response> _handleDelete(
571532 ); // userId should be null for AppConfig
572533 default :
573534 // This case should ideally be caught by the data/_middleware.dart,
574- // but added for safety. Consider logging this unexpected state.
535+ // but added for safety.
575536 print (
576- '[ReqID: $ requestId ] Error: Unsupported model type "$modelName " reached _handleDelete.' ,
537+ 'Error: Unsupported model type "$modelName " reached _handleDelete.' ,
577538 );
578539 // Throw an exception to be caught by the errorHandler
579540 throw OperationFailedException (
0 commit comments