import 'dart:convert'; import 'dart:io'; import 'package:shelf/shelf.dart'; import '../db.dart'; import '../firebase_auth.dart'; Handler profileHandler({ required ProfileDb db, required FirebaseAuthVerifier auth, }) { return (Request request) async { if (request.method == 'OPTIONS') { return Response.ok('', headers: _corsHeaders); } final String? firebaseUid = await auth.verifyBearerToken( request.headers['Authorization'] ?? request.headers['authorization'], ); if (firebaseUid == null) { return _jsonResponse(401, {'error': 'Unauthorized'}); } if (request.requestedUri.path != '/v1/me/profile') { return _jsonResponse(404, {'error': 'Not found'}); } try { if (request.method == 'GET') { final Map? profile = await db.getProfile(firebaseUid); if (profile == null) { return _jsonResponse(404, {'error': 'Not found'}); } return _jsonResponse(200, profile); } if (request.method == 'PUT') { final String body = await request.readAsString(); final Map json = jsonDecode(body) as Map; final int revision = (json['revision'] as num?)?.toInt() ?? 1; try { final Map saved = await db.upsertProfile( firebaseUid: firebaseUid, body: json, clientRevision: revision, ); return _jsonResponse(200, saved); } on StaleRevisionException catch (e) { return _jsonResponse(409, { 'error': 'Conflict', 'profile': e.serverProfile, }); } } return _jsonResponse(405, {'error': 'Method not allowed'}); } catch (e, st) { stderr.writeln('Profile handler error: $e\n$st'); return _jsonResponse(500, {'error': 'Internal error'}); } }; } Map get _corsHeaders => { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, PUT, OPTIONS', 'Access-Control-Allow-Headers': 'Authorization, Content-Type', }; Response _jsonResponse(int status, Map body) { return Response( status, body: jsonEncode(body), headers: { ..._corsHeaders, 'Content-Type': 'application/json', }, ); }