Контракты
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Knot.Modules.Profiles.Domain;
|
||||
using Knot.Modules.Profiles.Contracts.Domain;
|
||||
using Knot.Shared.Kernel.Storage;
|
||||
|
||||
namespace Knot.Modules.Profiles.Infrastructure.Database;
|
||||
|
||||
public class AvatarStorageService : IAvatarStorageService
|
||||
internal class AvatarStorageService : IAvatarStorageService
|
||||
{
|
||||
private readonly IFileStorageService _fileStorage;
|
||||
|
||||
@@ -15,15 +15,24 @@ public class AvatarStorageService : IAvatarStorageService
|
||||
_fileStorage = fileStorage;
|
||||
}
|
||||
|
||||
public async Task<string> UploadAsync(Stream content, string fileName, string contentType, CancellationToken ct = default)
|
||||
public async Task<string> UploadAsync(Stream stream, string fileName, string contentType, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// IFileStorageService не принимает CancellationToken в UploadFileAsync
|
||||
return await _fileStorage.UploadFileAsync(content, fileName, contentType);
|
||||
return await _fileStorage.UploadFileAsync(stream, fileName, contentType);
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(string fileId, CancellationToken ct = default)
|
||||
public async Task DeleteAsync(string fileKey, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// IFileStorageService не принимает CancellationToken в DeleteFileAsync
|
||||
await _fileStorage.DeleteFileAsync(fileId);
|
||||
await _fileStorage.DeleteFileAsync(fileKey);
|
||||
}
|
||||
|
||||
public async Task<Stream?> GetAsync(string fileKey, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var (stream, _, _) = await _fileStorage.DownloadFileAsync(fileKey);
|
||||
return stream;
|
||||
}
|
||||
|
||||
public string GetFileUrl(string fileKey)
|
||||
{
|
||||
return $"/api/files/{fileKey}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Knot.Modules.Profiles.Contracts.Domain;
|
||||
using Knot.Modules.Profiles.Contracts.Application.DTOs;
|
||||
using Knot.Modules.Profiles.Domain;
|
||||
using Knot.Modules.Profiles.Infrastructure.Mappings;
|
||||
using Knot.Shared.Kernel;
|
||||
using ProfilesErrors = Knot.Modules.Profiles.Contracts.Application.DTOs.ProfilesErrors;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Driver;
|
||||
|
||||
namespace Knot.Modules.Profiles.Infrastructure.Database;
|
||||
|
||||
public class ProfileRepository : IProfileRepository
|
||||
internal class ProfileRepository : IProfileRepository
|
||||
{
|
||||
private readonly IMongoCollection<ProfileDocument> _profiles;
|
||||
|
||||
@@ -17,36 +23,69 @@ public class ProfileRepository : IProfileRepository
|
||||
_profiles = database.GetCollection<ProfileDocument>("profiles");
|
||||
}
|
||||
|
||||
public async Task<ProfileDocument?> GetByIdAsync(Guid id, CancellationToken ct = default)
|
||||
public async Task<UserProfileDto?> GetAsync(Guid userId, CancellationToken ct = default)
|
||||
{
|
||||
return await _profiles.Find(p => p.Id == id).FirstOrDefaultAsync(ct);
|
||||
var profile = await _profiles.Find(p => p.Id == userId).FirstOrDefaultAsync(ct);
|
||||
return profile?.ToDto();
|
||||
}
|
||||
|
||||
public async Task<ProfileDocument?> GetByUsernameAsync(string username, CancellationToken ct = default)
|
||||
public async Task<UserProfileDto?> GetByUsernameAsync(string username, CancellationToken ct = default)
|
||||
{
|
||||
return await _profiles.Find(p => p.Username == username).FirstOrDefaultAsync(ct);
|
||||
var profile = await _profiles.Find(p => p.Username == username).FirstOrDefaultAsync(ct);
|
||||
return profile?.ToDto();
|
||||
}
|
||||
|
||||
public async Task AddAsync(ProfileDocument profile, CancellationToken ct = default)
|
||||
public async Task<List<UserProfileDto>> GetAsync(IEnumerable<Guid> userIds, CancellationToken ct = default)
|
||||
{
|
||||
await _profiles.InsertOneAsync(profile, null, ct);
|
||||
var ids = userIds.ToList();
|
||||
var profiles = await _profiles.Find(p => ids.Contains(p.Id)).ToListAsync(ct);
|
||||
return profiles.Select(p => p.ToDto()).ToList();
|
||||
}
|
||||
|
||||
public async Task UpdateAsync(ProfileDocument profile, CancellationToken ct = default)
|
||||
{
|
||||
await _profiles.ReplaceOneAsync(p => p.Id == profile.Id, profile, new ReplaceOptions { IsUpsert = true }, ct);
|
||||
}
|
||||
|
||||
public async Task<List<ProfileDocument>> SearchAsync(string query, CancellationToken ct = default)
|
||||
public async Task<List<UserProfileDto>> SearchAsync(string query, int limit = 20, CancellationToken ct = default)
|
||||
{
|
||||
List<ProfileDocument> docs;
|
||||
if (string.IsNullOrWhiteSpace(query))
|
||||
return await _profiles.Find(_ => true).Limit(50).ToListAsync(ct);
|
||||
{
|
||||
docs = await _profiles.Find(_ => true).Limit(limit).ToListAsync(ct);
|
||||
}
|
||||
else
|
||||
{
|
||||
var filter = Builders<ProfileDocument>.Filter.Or(
|
||||
Builders<ProfileDocument>.Filter.Regex(p => p.Username, new BsonRegularExpression(query, "i")),
|
||||
Builders<ProfileDocument>.Filter.Regex(p => p.DisplayName, new BsonRegularExpression(query, "i"))
|
||||
);
|
||||
docs = await _profiles.Find(filter).Limit(limit).ToListAsync(ct);
|
||||
}
|
||||
return docs.Select(p => p.ToDto()).ToList();
|
||||
}
|
||||
|
||||
var filter = Builders<ProfileDocument>.Filter.Or(
|
||||
Builders<ProfileDocument>.Filter.Regex(p => p.Username, new BsonRegularExpression(query, "i")),
|
||||
Builders<ProfileDocument>.Filter.Regex(p => p.DisplayName, new BsonRegularExpression(query, "i"))
|
||||
);
|
||||
public async Task<Result<UserProfileDto>> CreateAsync(UserProfileDto dto, CancellationToken ct = default)
|
||||
{
|
||||
var profile = ProfileDocument.Create(dto.UserId, dto.Username ?? string.Empty, dto.DisplayName ?? string.Empty, dto.About);
|
||||
|
||||
return await _profiles.Find(filter).Limit(50).ToListAsync(ct);
|
||||
await _profiles.InsertOneAsync(profile, null, ct);
|
||||
return Result.Success(profile.ToDto());
|
||||
}
|
||||
|
||||
public async Task<Result<UserProfileDto>> UpdateAsync(UserProfileDto dto, CancellationToken ct = default)
|
||||
{
|
||||
var profile = await _profiles.Find(p => p.Id == dto.UserId).FirstOrDefaultAsync(ct);
|
||||
if (profile is null)
|
||||
return Result.Failure<UserProfileDto>(ProfilesErrors.ProfileNotFound);
|
||||
|
||||
profile.UpdateProfile(
|
||||
dto.DisplayName ?? profile.DisplayName,
|
||||
dto.About ?? profile.Bio,
|
||||
null);
|
||||
|
||||
await _profiles.ReplaceOneAsync(p => p.Id == dto.UserId, profile, new ReplaceOptions { IsUpsert = true }, ct);
|
||||
return Result.Success(profile.ToDto());
|
||||
}
|
||||
|
||||
public async Task<Result> DeleteAsync(Guid userId, CancellationToken ct = default)
|
||||
{
|
||||
var result = await _profiles.DeleteOneAsync(p => p.Id == userId, ct);
|
||||
return result.DeletedCount > 0 ? Result.Success() : Result.Failure(ProfilesErrors.ProfileNotFound);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
using System.Threading;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Knot.Modules.Profiles.Domain;
|
||||
using Knot.Modules.Profiles.Contracts.Domain;
|
||||
using Knot.Shared.Kernel;
|
||||
|
||||
namespace Knot.Modules.Profiles.Infrastructure.Database;
|
||||
|
||||
public class ProfilesUnitOfWork : IProfilesUnitOfWork
|
||||
internal class ProfilesUnitOfWork : IProfilesUnitOfWork
|
||||
{
|
||||
public Task SaveChangesAsync(CancellationToken ct = default) => Task.CompletedTask;
|
||||
public IProfileRepository ProfileRepository { get; }
|
||||
|
||||
public ProfilesUnitOfWork(IProfileRepository profileRepository)
|
||||
{
|
||||
ProfileRepository = profileRepository;
|
||||
}
|
||||
|
||||
public Task<int> SaveChangesAsync(CancellationToken ct = default) => Task.FromResult(1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user