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
+
+
+