feat: dynamic units table with localized names via GET /units

- Add units + unit_translations tables with FK constraints on products and ingredient_mappings
- Normalize products.unit from Russian strings (г, кг) to English codes (g, kg)
- Load units at startup (in-memory registry) and serve via GET /units (language-aware)
- Replace hardcoded _units lists and _mapUnit() functions in Flutter with unitsProvider FutureProvider
- Re-fetches automatically when language changes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
dbastrikin
2026-03-15 16:15:33 +02:00
parent e1fbe7b1a2
commit 55d01400b0
13 changed files with 259 additions and 86 deletions

View File

@@ -8,8 +8,8 @@ class LanguageRepository {
LanguageRepository(this._api);
Future<Map<String, String>> fetchLanguages() async {
final response = await _api.dio.get('/languages');
final List<dynamic> items = response.data['languages'] as List;
final data = await _api.get('/languages');
final List<dynamic> items = data['languages'] as List;
return {
for (final item in items)
item['code'] as String: item['native_name'] as String,

View File

@@ -0,0 +1,22 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../auth/auth_provider.dart';
import 'api_client.dart';
class UnitRepository {
final ApiClient _api;
UnitRepository(this._api);
Future<Map<String, String>> fetchUnits() async {
final data = await _api.get('/units');
final List<dynamic> items = data['units'] as List;
return {
for (final item in items)
item['code'] as String: item['name'] as String,
};
}
}
final unitRepositoryProvider = Provider<UnitRepository>(
(ref) => UnitRepository(ref.watch(apiClientProvider)),
);