Dart Shelf API with modules: auth (JWT + PBKDF2), tasks (CRUD + dopamine scorer), streaks (forgiveness + freeze), rewards (variable reward engine), time perception, sync (offline-first push/pull), rooms (body doubling placeholder). Includes DB migration (001_initial_schema.sql) and Docker Compose. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
65 lines
1.8 KiB
Dart
65 lines
1.8 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:shelf/shelf.dart';
|
|
import 'package:shelf_router/shelf_router.dart';
|
|
|
|
import '../../middleware/error_handler.dart';
|
|
import '../../shared/api_response.dart';
|
|
import '../../shared/pagination.dart';
|
|
import 'reward_service.dart';
|
|
|
|
/// Reward module route definitions.
|
|
class RewardRoutes {
|
|
final RewardService _service;
|
|
|
|
RewardRoutes(this._service);
|
|
|
|
Router get router {
|
|
final router = Router();
|
|
|
|
router.post('/generate', _generate);
|
|
router.get('/history', _history);
|
|
|
|
return router;
|
|
}
|
|
|
|
// ── Handlers ────────────────────────────────────────────────────────
|
|
|
|
Future<Response> _generate(Request request) async {
|
|
final userId = request.context['userId'] as String;
|
|
final body =
|
|
jsonDecode(await request.readAsString()) as Map<String, dynamic>;
|
|
|
|
final taskId = body['task_id'] as String?;
|
|
final taskEnergyLevel = body['task_energy_level'] as int?;
|
|
|
|
if (taskId == null || taskEnergyLevel == null) {
|
|
throw ApiException.badRequest(
|
|
'Missing required fields: task_id, task_energy_level',
|
|
);
|
|
}
|
|
|
|
final reward = await _service.generateReward(
|
|
userId: userId,
|
|
taskId: taskId,
|
|
taskEnergyLevel: taskEnergyLevel,
|
|
currentStreak: (body['current_streak'] as int?) ?? 0,
|
|
);
|
|
|
|
return ApiResponse.created(reward, message: 'Reward generated!');
|
|
}
|
|
|
|
Future<Response> _history(Request request) async {
|
|
final userId = request.context['userId'] as String;
|
|
final paging = Pagination.fromRequest(request);
|
|
|
|
final rewards = await _service.getHistory(
|
|
userId,
|
|
limit: paging.perPage,
|
|
offset: paging.offset,
|
|
);
|
|
|
|
return ApiResponse.success(rewards);
|
|
}
|
|
}
|