BLOG-104 Implement CRUD functionality for Posts #108

Merged
squid merged 5 commits from BLOG-104_post_create_and_update_routes into main 2025-08-02 14:35:27 +08:00
Owner

Description

This pull request introduces the core functionality for creating and updating posts, completing the backend CRUD operations for the post feature. It includes new API endpoints, database schema changes, and corresponding updates across the entire application stack from the database layer to the frontend.

Backend API

  • Added new authenticated endpoints:
    • POST /post: To create a new post.
    • PUT /post/{id}: To update an existing post.
  • Implemented the full vertical slice for these operations, including:
    • CreatePostUseCase and UpdatePostUseCase.
    • Repository and DB service methods for creating, updating, and associating posts with labels.
    • Transactional database operations to ensure data integrity when creating/updating posts and their associated labels.

Database

  • Added a new migration to include an "order" column in the post_label table.
  • This column preserves the user-defined order of labels for each post.
  • Queries have been updated to fetch and sort labels based on this new column.

API Schema & Documentation

  • Enhanced utoipa OpenAPI documentation with more specific formats for data types:
    • #[schema(format = Uri)] for URLs like preview_image_url.
    • #[schema(format = Email)] for user emails.
    • #[schema(format = DateTime)] for timestamps.
  • Standardized the published_time field to use the RFC3339 string format instead of a numeric timestamp, improving API clarity and interoperability.

Frontend

  • Updated the PostInfoResponseDto in the frontend to correctly parse the new DateTime (ISO string) format for published_time.

Refactoring

  • Renamed get_full_post to a more descriptive get_post_by_id across the post feature module for better code clarity.

Package Changes

utoipa = { version = "5.4.0", features = [
    "actix_extras",
    "non_strict_integers",
    "url",
] }

Screenshots

No response

Reference

Resolves #104

Checklist

  • A milestone is set
  • The related issuse has been linked to this branch
### Description This pull request introduces the core functionality for creating and updating posts, completing the backend CRUD operations for the `post` feature. It includes new API endpoints, database schema changes, and corresponding updates across the entire application stack from the database layer to the frontend. #### Backend API - **Added new authenticated endpoints:** - `POST /post`: To create a new post. - `PUT /post/{id}`: To update an existing post. - Implemented the full vertical slice for these operations, including: - `CreatePostUseCase` and `UpdatePostUseCase`. - Repository and DB service methods for creating, updating, and associating posts with labels. - Transactional database operations to ensure data integrity when creating/updating posts and their associated labels. #### Database - Added a new migration to include an `"order"` column in the `post_label` table. - This column preserves the user-defined order of labels for each post. - Queries have been updated to fetch and sort labels based on this new column. #### API Schema & Documentation - Enhanced `utoipa` OpenAPI documentation with more specific formats for data types: - `#[schema(format = Uri)]` for URLs like `preview_image_url`. - `#[schema(format = Email)]` for user emails. - `#[schema(format = DateTime)]` for timestamps. - Standardized the `published_time` field to use the RFC3339 string format instead of a numeric timestamp, improving API clarity and interoperability. #### Frontend - Updated the `PostInfoResponseDto` in the frontend to correctly parse the new `DateTime` (ISO string) format for `published_time`. #### Refactoring - Renamed `get_full_post` to a more descriptive `get_post_by_id` across the post feature module for better code clarity. ### Package Changes ```toml utoipa = { version = "5.4.0", features = [ "actix_extras", "non_strict_integers", "url", ] } ``` ### Screenshots _No response_ ### Reference Resolves #104 ### Checklist - [x] A milestone is set - [x] The related issuse has been linked to this branch
squid added this to the 0.3 milestone 2025-08-02 14:32:46 +08:00
squid added 5 commits 2025-08-02 14:32:46 +08:00
Collaborator

/improve

/improve
Collaborator

PR Code Suggestions

CategorySuggestion                                                                                                                                    Impact
Possible issue
Align API schema with data type

The published_time field is marked as required in the OpenAPI schema, but its Rust
type Option indicates it's optional. This creates an inconsistency in the API
contract. To resolve this, either remove #[schema(required)] if the field can be
omitted, or change the type to String if it must always be provided by the client.

backend/feature/post/src/adapter/delivery/create_post_request_dto.rs [17-18]

-#[schema(required, format = DateTime)]
+#[schema(format = DateTime)]
 pub published_time: Option<String>,
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies an inconsistency where the published_time field is marked as required in the OpenAPI schema but is an Option<String> in Rust. This can lead to misleading API documentation and incorrect client expectations.

Medium
## PR Code Suggestions ✨ <!-- --> <table><thead><tr><td><strong>Category</strong></td><td align=left><strong>Suggestion&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </strong></td><td align=center><strong>Impact</strong></td></tr><tbody><tr><td rowspan=1>Possible issue</td> <td> <details><summary>Align API schema with data type</summary> ___ **The <code>published_time</code> field is marked as <code>required</code> in the OpenAPI schema, but its Rust <br>type <code>Option<String></code> indicates it's optional. This creates an inconsistency in the API <br>contract. To resolve this, either remove <code>#[schema(required)]</code> if the field can be <br>omitted, or change the type to <code>String</code> if it must always be provided by the client.** [backend/feature/post/src/adapter/delivery/create_post_request_dto.rs [17-18]](https://git.squidspirit.com/squid/blog/src/branch/BLOG-104_post_create_and_update_routes/backend/feature/post/src/adapter/delivery/create_post_request_dto.rs#L17-L18) ```diff -#[schema(required, format = DateTime)] +#[schema(format = DateTime)] pub published_time: Option<String>, ``` <details><summary>Suggestion importance[1-10]: 8</summary> __ Why: The suggestion correctly identifies an inconsistency where the `published_time` field is marked as `required` in the OpenAPI schema but is an `Option<String>` in Rust. This can lead to misleading API documentation and incorrect client expectations. </details></details></td><td align=center>Medium </td></tr></tr></tbody></table>
squid changed title from BLOG-104_post_create_and_update_routes to BLOG-104 Implement CRUD functionality for Posts 2025-08-02 14:33:01 +08:00
Author
Owner

The published_time field is marked as required in the OpenAPI schema, but its Rust
type Option indicates it's optional. This creates an inconsistency in the API
contract. To resolve this, either remove #[schema(required)] if the field can be
omitted, or change the type to String if it must always be provided by the client.

backend/feature/post/src/adapter/delivery/create_post_request_dto.rs [17-18]

-#[schema(required, format = DateTime)]
+#[schema(format = DateTime)]
 pub published_time: Option<String>,

A null published_time represents as unpublished, which should be explicit.

> **The <code>published_time</code> field is marked as <code>required</code> in the OpenAPI schema, but its Rust <br>type <code>Option<String></code> indicates it's optional. This creates an inconsistency in the API <br>contract. To resolve this, either remove <code>#[schema(required)]</code> if the field can be <br>omitted, or change the type to <code>String</code> if it must always be provided by the client.** > > [backend/feature/post/src/adapter/delivery/create_post_request_dto.rs [17-18]](https://git.squidspirit.com/squid/blog/src/branch/BLOG-104_post_create_and_update_routes/backend/feature/post/src/adapter/delivery/create_post_request_dto.rs#L17-L18) > > ```diff > -#[schema(required, format = DateTime)] > +#[schema(format = DateTime)] > pub published_time: Option<String>, > ``` A `null` published_time represents as *unpublished*, which should be explicit.
squid merged commit a5f66616c4 into main 2025-08-02 14:35:27 +08:00
squid deleted branch BLOG-104_post_create_and_update_routes 2025-08-02 14:35:28 +08:00
Sign in to join this conversation.
No description provided.