mnemo_cards/mnemo_cards_backend/lib/user/user_repository.dart

182 lines
5.8 KiB
Dart
Raw Normal View History

2026-01-08 16:07:56 +00:00
import 'package:drift/drift.dart';
import 'package:drift_postgres/drift_postgres.dart';
import 'package:injectable/injectable.dart';
import 'package:mnemo_cards_backend/database/database.dart';
import 'package:mnemo_cards_backend/packs/card_pack_drift_extension.dart';
import 'package:mnemo_cards_common_backend/mnemo_cards_common_backend.dart';
import 'user_drift_extension.dart';
/// Repository для работы с пользователями
/// Работает с доменными моделями (UserModel), использует DAO для доступа к БД
@lazySingleton
class UserRepository {
final AppDatabase _db;
UserRepository(this._db);
/// Получить пользователя по ID
/// [includePacks] - загружать ли связанные паки пользователя
Future<UserModel?> getUserById(
String id, {
bool includePacks = false,
}) async {
final user = await _db.userDao.getUserById(id);
if (user == null) return null;
if (includePacks) {
final packs = await _db.userDao.getUserPacks(id);
return await user.toUserModel(packs);
}
return await user.toUserModel();
}
/// Получить пользователя по email
Future<UserModel?> getUserByEmail(String email) async {
final user = await _db.userDao.getUserByEmail(email);
if (user == null) return null;
return await user.toUserModel();
}
/// Получить пользователя по externalUserId
Future<UserModel?> getUserByExternalId(String externalId) async {
final user = await _db.userDao.getUserByExternalId(externalId);
if (user == null) return null;
return await user.toUserModel();
}
/// Получить пользователя с UserData
Future<UserModel?> getUserWithDataById(String id) async {
final userWithData = await _db.userDao.getUserWithDataById(id);
if (userWithData == null) return null;
final packs = await _db.userDao.getUserPacks(id);
final userModel = await userWithData.user.toUserModel(packs);
// TODO: загрузить UserDataModel если нужно
// userModel.userData = userWithData.userData?.toUserDataModel();
return userModel;
}
/// Создать пользователя
Future<String> createUser(UserModel userModel) async {
final userCompanion = userModel.toUsersCompanion();
return await _db.userDao.createUser(userCompanion);
}
/// Создать пользователя с UserData
Future<String> createUserWithData({
required UserModel userModel,
required UserDatasCompanion userData,
}) async {
final userCompanion = userModel.toUsersCompanion();
return await _db.userDao.createUserWithData(
user: userCompanion,
userData: userData,
);
}
/// Обновить пользователя
Future<void> updateUser(UserModel userModel) async {
if (userModel.id == null) {
throw ArgumentError('User ID is required');
}
await _db.userDao.updateUserPartial(
userModel.toUsersCompanion().copyWith(
updatedAt: Value(PgDateTime(DateTime.now())),
),
);
}
/// Обновить пользователя частично
Future<void> updateUserPartial(UsersCompanion updates) async {
await _db.userDao.updateUserPartial(updates);
}
/// Удалить пользователя (soft delete)
Future<void> softDeleteUser(String userId) async {
await _db.userDao.softDeleteUser(userId);
}
/// Получить всех пользователей (для админки)
Future<List<UserModel>> getAllUsers({
int? limit,
int? offset,
bool includeDeleted = false,
bool includePacks = false,
}) async {
final users = await _db.userDao.getAllUsers(
limit: limit,
offset: offset,
includeDeleted: includeDeleted,
);
if (includePacks) {
final userModels = <UserModel>[];
for (final user in users) {
final packs = await _db.userDao.getUserPacks(user.id);
final userModel = await user.toUserModel(packs);
userModels.add(userModel);
}
return userModels;
}
return await Future.wait(users.map((u) => u.toUserModel()));
}
/// Подсчитать пользователей
Future<int> countUsers({bool includeDeleted = false}) async {
return await _db.userDao.countUsers(includeDeleted: includeDeleted);
}
/// Получить паки пользователя
Future<List<CardPackModel>> getUserPacks(String userId) async {
final packs = await _db.userDao.getUserPacks(userId);
return await Future.wait(packs.map((p) => p.toModel()));
}
/// Проверить, есть ли у пользователя доступ к паку
Future<bool> hasPackAccess(String userId, String packId) async {
return await _db.userDao.hasPackAccess(userId, packId);
}
/// Дать пользователю доступ к паку
Future<void> grantPackAccess({
required String userId,
required String packId,
String grantType = 'purchase',
}) async {
await _db.userDao.grantPackAccess(
userId: userId,
packId: packId,
grantType: grantType,
);
}
/// Отозвать доступ к паку
Future<void> revokePackAccess(String userId, String packId) async {
await _db.userDao.revokePackAccess(userId, packId);
}
/// Получить UserData пользователя
Future<UserData?> getUserData(String userId) async {
return await _db.userDao.getUserData(userId);
}
/// Обновить UserData частично
Future<void> updateUserDataPartial(UserDatasCompanion updates) async {
await _db.userDao.updateUserDataPartial(updates);
}
/// Обновить время последнего визита
Future<void> updateLastOnline(String userId) async {
await _db.userDao.updateLastOnline(userId);
}
}