diff --git a/Directory.Build.props b/Directory.Build.props index 0751e1d..0f29b4c 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - 0.1.31 + 0.1.29 diff --git a/Femto.Api/Controllers/Posts/Dto/AddPostCommentRequest.cs b/Femto.Api/Controllers/Posts/Dto/AddPostCommentRequest.cs deleted file mode 100644 index 7546af0..0000000 --- a/Femto.Api/Controllers/Posts/Dto/AddPostCommentRequest.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace Femto.Api.Controllers.Posts.Dto; - -public record AddPostCommentRequest(Guid AuthorId, string Content); \ No newline at end of file diff --git a/Femto.Api/Controllers/Posts/Dto/GetPublicPostsSearchParams.cs b/Femto.Api/Controllers/Posts/Dto/GetPublicPostsSearchParams.cs index 3705456..e5155f6 100644 --- a/Femto.Api/Controllers/Posts/Dto/GetPublicPostsSearchParams.cs +++ b/Femto.Api/Controllers/Posts/Dto/GetPublicPostsSearchParams.cs @@ -3,4 +3,4 @@ using JetBrains.Annotations; namespace Femto.Api.Controllers.Posts.Dto; [PublicAPI] -public record GetPublicPostsSearchParams(Guid? After, int? Amount, Guid? AuthorId, string? Author); \ No newline at end of file +public record GetPublicPostsSearchParams(Guid? From, int? Amount, Guid? AuthorId, string? Author); \ No newline at end of file diff --git a/Femto.Api/Controllers/Posts/Dto/PostCommentDto.cs b/Femto.Api/Controllers/Posts/Dto/PostCommentDto.cs deleted file mode 100644 index 04e180a..0000000 --- a/Femto.Api/Controllers/Posts/Dto/PostCommentDto.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace Femto.Api.Controllers.Posts.Dto; - -public record PostCommentDto(string Author, string Content, DateTimeOffset PostedOn); \ No newline at end of file diff --git a/Femto.Api/Controllers/Posts/Dto/PostDto.cs b/Femto.Api/Controllers/Posts/Dto/PostDto.cs index c9af7c6..2e6e827 100644 --- a/Femto.Api/Controllers/Posts/Dto/PostDto.cs +++ b/Femto.Api/Controllers/Posts/Dto/PostDto.cs @@ -10,8 +10,7 @@ public record PostDto( IEnumerable Media, IEnumerable Reactions, DateTimeOffset CreatedAt, - IEnumerable PossibleReactions, - IEnumerable Comments + IEnumerable PossibleReactions ) { public static PostDto FromModel(Modules.Blog.Application.Queries.GetPosts.Dto.PostDto post) => @@ -22,7 +21,6 @@ public record PostDto( post.Media.Select(m => new PostMediaDto(m.Url, m.Width, m.Height)), post.Reactions.Select(r => new PostReactionDto(r.Emoji, r.AuthorName, r.ReactedOn)), post.CreatedAt, - post.PossibleReactions, - post.Comments.Select(c => new PostCommentDto(c.Author, c.Content, c.PostedOn)) + post.PossibleReactions ); -} \ No newline at end of file +} diff --git a/Femto.Api/Controllers/Posts/PostsController.cs b/Femto.Api/Controllers/Posts/PostsController.cs index ed882f7..aa59a2f 100644 --- a/Femto.Api/Controllers/Posts/PostsController.cs +++ b/Femto.Api/Controllers/Posts/PostsController.cs @@ -1,7 +1,6 @@ using Femto.Api.Controllers.Posts.Dto; using Femto.Common; using Femto.Modules.Blog.Application; -using Femto.Modules.Blog.Application.Commands.AddPostComment; using Femto.Modules.Blog.Application.Commands.AddPostReaction; using Femto.Modules.Blog.Application.Commands.ClearPostReaction; using Femto.Modules.Blog.Application.Commands.CreatePost; @@ -14,7 +13,7 @@ namespace Femto.Api.Controllers.Posts; [ApiController] [Route("posts")] -public class PostsController(IBlogModule blogModule, ICurrentUserContext currentUserContext, IAuthorizationService auth) +public class PostsController(IBlogModule blogModule, ICurrentUserContext currentUserContext) : ControllerBase { [HttpGet] @@ -26,7 +25,7 @@ public class PostsController(IBlogModule blogModule, ICurrentUserContext current var res = await blogModule.Query( new GetPostsQuery(currentUserContext.CurrentUser?.Id) { - After = searchParams.After, + After = searchParams.From, Amount = searchParams.Amount ?? 20, AuthorId = searchParams.AuthorId, Author = searchParams.Author, @@ -132,23 +131,4 @@ public class PostsController(IBlogModule blogModule, ICurrentUserContext current return this.Ok(); } - - [HttpPost("{postId}/comments")] - [Authorize] - public async Task AddPostComment( - Guid postId, - [FromBody] AddPostCommentRequest request, - CancellationToken cancellationToken - ) - { - if (currentUserContext.CurrentUser?.Id != request.AuthorId) - return this.BadRequest(); - - await blogModule.Command( - new AddPostCommentCommand(postId, request.AuthorId, request.Content), - cancellationToken - ); - - return this.Ok(); - } } diff --git a/Femto.Database/Migrations/20250810172242_AddCommentToPost.sql b/Femto.Database/Migrations/20250810172242_AddCommentToPost.sql deleted file mode 100644 index 44e0086..0000000 --- a/Femto.Database/Migrations/20250810172242_AddCommentToPost.sql +++ /dev/null @@ -1,11 +0,0 @@ --- Migration: AddCommentToPost --- Created at: 10/08/2025 17:22:42 - -CREATE TABLE blog.post_comment -( - id uuid PRIMARY KEY, - post_id uuid REFERENCES blog.post(id), - author_id uuid REFERENCES blog.author(id), - content TEXT NOT NULL, - created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() -) \ No newline at end of file diff --git a/Femto.Database/Seed/TestDataSeeder.cs b/Femto.Database/Seed/TestDataSeeder.cs index 2c8efcc..433f73c 100644 --- a/Femto.Database/Seed/TestDataSeeder.cs +++ b/Femto.Database/Seed/TestDataSeeder.cs @@ -43,7 +43,6 @@ public static class TestDataSeeder ('019691a0-4dd3-7e89-909e-94a6fd19a05e', @id, '["🍆", "🧢", "🧑🏾‍🎓", "🥕", "🕗"]', 'Some unwitched marbles are thought of simply as currencies. A boundary sees a nepal as a chordal railway.') ; - INSERT INTO blog.post_media (id, post_id, url, ordering) VALUES @@ -64,12 +63,6 @@ public static class TestDataSeeder ('019691a0-4c3e-726f-b8f6-bcbaabe789ae', @id, '🕗') ; - INSERT INTO blog.post_comment - (id, post_id, author_id, content) - VALUES - ('9116da05-49eb-4053-9199-57f54f92e73a', '019691a0-48ed-7eba-b8d3-608e25e07d4b', @id, 'this is a comment!') - ; - INSERT INTO authn.user_identity (id, username, password_hash, password_salt) VALUES diff --git a/Femto.Modules.Blog.Data/Class1.cs b/Femto.Modules.Blog.Data/Class1.cs new file mode 100644 index 0000000..3be8b2a --- /dev/null +++ b/Femto.Modules.Blog.Data/Class1.cs @@ -0,0 +1,5 @@ +namespace Femto.Modules.Blog.Data; + +public class Class1 +{ +} \ No newline at end of file diff --git a/Femto.Modules.Blog.Data/Femto.Modules.Blog.Data.csproj b/Femto.Modules.Blog.Data/Femto.Modules.Blog.Data.csproj new file mode 100644 index 0000000..17b910f --- /dev/null +++ b/Femto.Modules.Blog.Data/Femto.Modules.Blog.Data.csproj @@ -0,0 +1,9 @@ + + + + net9.0 + enable + enable + + + diff --git a/Femto.Modules.Blog.Domain/Femto.Modules.Blog.Domain.csproj b/Femto.Modules.Blog.Domain/Femto.Modules.Blog.Domain.csproj new file mode 100644 index 0000000..6ae6742 --- /dev/null +++ b/Femto.Modules.Blog.Domain/Femto.Modules.Blog.Domain.csproj @@ -0,0 +1,24 @@ + + + + net9.0 + enable + enable + + + + + + + + + + + + + + ..\..\..\..\.nuget\packages\microsoft.entityframeworkcore\9.0.4\lib\net8.0\Microsoft.EntityFrameworkCore.dll + + + + diff --git a/Femto.Modules.Blog/Application/Commands/AddPostComment/AddPostCommentCommand.cs b/Femto.Modules.Blog/Application/Commands/AddPostComment/AddPostCommentCommand.cs deleted file mode 100644 index 445c59e..0000000 --- a/Femto.Modules.Blog/Application/Commands/AddPostComment/AddPostCommentCommand.cs +++ /dev/null @@ -1,5 +0,0 @@ -using Femto.Common.Domain; - -namespace Femto.Modules.Blog.Application.Commands.AddPostComment; - -public record AddPostCommentCommand(Guid PostId, Guid AuthorId, string Content) : ICommand; \ No newline at end of file diff --git a/Femto.Modules.Blog/Application/Commands/AddPostComment/AddPostCommentCommandHandler.cs b/Femto.Modules.Blog/Application/Commands/AddPostComment/AddPostCommentCommandHandler.cs deleted file mode 100644 index 6e52877..0000000 --- a/Femto.Modules.Blog/Application/Commands/AddPostComment/AddPostCommentCommandHandler.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Femto.Common.Domain; -using Microsoft.EntityFrameworkCore; - -namespace Femto.Modules.Blog.Application.Commands.AddPostComment; - -internal class AddPostCommentCommandHandler(BlogContext context) : ICommandHandler -{ - public async Task Handle(AddPostCommentCommand request, CancellationToken cancellationToken) - { - var post = await context.Posts.SingleOrDefaultAsync( - p => p.Id == request.PostId, - cancellationToken - ); - - if (post is null) - return; - - post.AddComment(request.AuthorId, request.Content); - } -} \ No newline at end of file diff --git a/Femto.Modules.Blog/Application/Commands/CreatePost/CreatePostCommandHandler.cs b/Femto.Modules.Blog/Application/Commands/CreatePost/CreatePostCommandHandler.cs index 25bab45..2d9c713 100644 --- a/Femto.Modules.Blog/Application/Commands/CreatePost/CreatePostCommandHandler.cs +++ b/Femto.Modules.Blog/Application/Commands/CreatePost/CreatePostCommandHandler.cs @@ -24,9 +24,11 @@ internal class CreatePostCommandHandler(BlogContext context) media.Width, media.Height )) - .ToList(), - request.IsPublic is true - ); + .ToList() + ) + { + IsPublic = request.IsPublic is true + }; await context.AddAsync(post, cancellationToken); @@ -37,8 +39,7 @@ internal class CreatePostCommandHandler(BlogContext context) post.PostedOn, new PostAuthorDto(post.AuthorId, request.CurrentUser.Username), [], - post.PossibleReactions, - [] + post.PossibleReactions ); } } diff --git a/Femto.Modules.Blog/Application/Configurations/PostConfiguration.cs b/Femto.Modules.Blog/Application/Configurations/PostConfiguration.cs index 630cbe2..b1defec 100644 --- a/Femto.Modules.Blog/Application/Configurations/PostConfiguration.cs +++ b/Femto.Modules.Blog/Application/Configurations/PostConfiguration.cs @@ -24,8 +24,6 @@ internal class PostConfiguration : IEntityTypeConfiguration } ); - table.OwnsMany(p => p.Comments).WithOwner(); - table.Property("PossibleReactionsJson").HasColumnName("possible_reactions"); table.Ignore(e => e.PossibleReactions); diff --git a/Femto.Modules.Blog/Application/Queries/GetPosts/Dto/PostCommentDto.cs b/Femto.Modules.Blog/Application/Queries/GetPosts/Dto/PostCommentDto.cs deleted file mode 100644 index 55ea5e8..0000000 --- a/Femto.Modules.Blog/Application/Queries/GetPosts/Dto/PostCommentDto.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace Femto.Modules.Blog.Application.Queries.GetPosts.Dto; - -public record PostCommentDto(string Author, string Content, DateTimeOffset PostedOn); \ No newline at end of file diff --git a/Femto.Modules.Blog/Application/Queries/GetPosts/Dto/PostDto.cs b/Femto.Modules.Blog/Application/Queries/GetPosts/Dto/PostDto.cs index 63efede..b8b6a3d 100644 --- a/Femto.Modules.Blog/Application/Queries/GetPosts/Dto/PostDto.cs +++ b/Femto.Modules.Blog/Application/Queries/GetPosts/Dto/PostDto.cs @@ -7,6 +7,5 @@ public record PostDto( DateTimeOffset CreatedAt, PostAuthorDto Author, IList Reactions, - IEnumerable PossibleReactions, - IList Comments -); \ No newline at end of file + IEnumerable PossibleReactions +); diff --git a/Femto.Modules.Blog/Application/Queries/GetPosts/GetPostsQueryHandler.cs b/Femto.Modules.Blog/Application/Queries/GetPosts/GetPostsQueryHandler.cs index c57627f..0af48ee 100644 --- a/Femto.Modules.Blog/Application/Queries/GetPosts/GetPostsQueryHandler.cs +++ b/Femto.Modules.Blog/Application/Queries/GetPosts/GetPostsQueryHandler.cs @@ -68,7 +68,7 @@ public class GetPostsQueryHandler(IDbConnectionFactory connectionFactory) """, new { postIds } ); - + var media = loadMediaResult.ToList(); var loadReactionsResult = await conn.QueryAsync( @@ -87,36 +87,16 @@ public class GetPostsQueryHandler(IDbConnectionFactory connectionFactory) var reactions = loadReactionsResult.ToList(); - var loadCommentsResult = await conn.QueryAsync( - """ - select - pc.id as CommentId, - pc.post_id as PostId, - pc.content as Content, - pc.created_at as PostedOn, - a.username as AuthorName - from blog.post_comment pc - join blog.author a on pc.author_id = a.id - where pc.post_id = ANY (@postIds) - """, - new { postIds } - ); - - var comments = loadCommentsResult.ToList(); - return new GetPostsQueryResult( posts .Select(p => new PostDto( p.PostId, p.Content, - media - .Where(m => m.PostId == p.PostId) - .Select(m => new PostMediaDto( - new Uri(m.MediaUrl), - m.MediaWidth, - m.MediaHeight - )) - .ToList(), + media.Where(m => m.PostId == p.PostId).Select(m => new PostMediaDto( + new Uri(m.MediaUrl), + m.MediaWidth, + m.MediaHeight + )).ToList(), p.PostedOn, new PostAuthorDto(p.AuthorId, p.Username), reactions @@ -125,11 +105,7 @@ public class GetPostsQueryHandler(IDbConnectionFactory connectionFactory) .ToList(), !string.IsNullOrEmpty(p.PossibleReactions) ? JsonSerializer.Deserialize>(p.PossibleReactions)! - : [], - comments - .Where(c => c.PostId == p.PostId) - .Select(c => new PostCommentDto(c.AuthorName, c.Content, c.PostedOn)) - .ToList() + : [] )) .ToList() ); @@ -161,13 +137,4 @@ public class GetPostsQueryHandler(IDbConnectionFactory connectionFactory) public string Emoji { get; init; } public DateTimeOffset CreatedAt { get; init; } } - - internal record LoadCommentRow - { - public Guid CommentId { get; init; } - public Guid PostId { get; init; } - public string Content { get; init; } - public DateTimeOffset PostedOn { get; init; } - public string AuthorName { get; init; } - } } diff --git a/Femto.Modules.Blog/Domain/Posts/Post.cs b/Femto.Modules.Blog/Domain/Posts/Post.cs index b5a9b2d..dc4d937 100644 --- a/Femto.Modules.Blog/Domain/Posts/Post.cs +++ b/Femto.Modules.Blog/Domain/Posts/Post.cs @@ -13,9 +13,7 @@ internal class Post : Entity public IList Media { get; private set; } public IList Reactions { get; private set; } = []; - - public IList Comments { get; private set; } = []; - public bool IsPublic { get; private set; } + public bool IsPublic { get; set; } public DateTimeOffset PostedOn { get; private set; } @@ -29,7 +27,7 @@ internal class Post : Entity private Post() { } - public Post(Guid authorId, string content, IList media, bool isPublic) + public Post(Guid authorId, string content, IList media) { this.Id = Guid.CreateVersion7(); this.AuthorId = authorId; @@ -37,7 +35,6 @@ internal class Post : Entity this.Media = media; this.PossibleReactions = AllEmoji.GetRandomEmoji(5); this.PostedOn = DateTimeOffset.UtcNow; - this.IsPublic = isPublic; this.AddDomainEvent(new PostCreated(this)); } @@ -59,14 +56,4 @@ internal class Post : Entity .Reactions.Where(r => r.AuthorId != reactorId || r.Emoji != emoji) .ToList(); } - - public void AddComment(Guid authorId, string content) - { - // XXX just ignore empty comments for now. we may want to upgrade this to an error - // but it is probably suitable to just consider it a no-op - if (string.IsNullOrWhiteSpace(content)) - return; - - this.Comments.Add(new PostComment(authorId, content)); - } } diff --git a/Femto.Modules.Blog/Domain/Posts/PostComment.cs b/Femto.Modules.Blog/Domain/Posts/PostComment.cs deleted file mode 100644 index 6f658a8..0000000 --- a/Femto.Modules.Blog/Domain/Posts/PostComment.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Femto.Modules.Blog.Domain.Posts; - -internal class PostComment -{ - public Guid Id { get; private set; } - public Guid AuthorId { get; private set; } - public DateTimeOffset CreatedAt { get; private set; } - public string Content { get; private set; } - - private PostComment() {} - - public PostComment(Guid authorId, string content) - { - this.Id = Guid.CreateVersion7(); - this.AuthorId = authorId; - this.Content = content; - this.CreatedAt = TimeProvider.System.GetUtcNow(); - } -} \ No newline at end of file diff --git a/Femto.Modules.Files/Domain/Files/File.cs b/Femto.Modules.Files/Domain/Files/File.cs new file mode 100644 index 0000000..9600ceb --- /dev/null +++ b/Femto.Modules.Files/Domain/Files/File.cs @@ -0,0 +1,8 @@ +namespace Femto.Modules.Files.Domain.Files; + +public class File +{ + Guid Id { get; set; } + + +} \ No newline at end of file diff --git a/Femto.Modules.Files/Femto.Modules.Files.csproj b/Femto.Modules.Files/Femto.Modules.Files.csproj new file mode 100644 index 0000000..17b910f --- /dev/null +++ b/Femto.Modules.Files/Femto.Modules.Files.csproj @@ -0,0 +1,9 @@ + + + + net9.0 + enable + enable + + +