### Installation Rules Source: https://github.com/userver-framework/realmedium_sample/blob/develop/CMakeLists.txt Defines installation rules for the main executable and configuration files. It handles custom installation prefixes if the PREFIX environment variable is set. ```cmake # Install include(GNUInstallDirs) if(DEFINED ENV{PREFIX}) message(STATUS "Set install prefix: $ENV{PREFIX}") file(TO_CMAKE_PATH "$ENV{PREFIX}" PREFIX_PATH) set(CMAKE_INSTALL_PREFIX ${PREFIX_PATH}) endif() file(GLOB CONFIGS_FILES ${CMAKE_CURRENT_SOURCE_DIR}/configs/*.yaml ${CMAKE_CURRENT_SOURCE_DIR}/configs/*.json) install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${PROJECT_NAME}) install(FILES ${CONFIGS_FILES} DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/${PROJECT_NAME} COMPONENT ${PROJECT_NAME}) ``` -------------------------------- ### Unit Test Setup Source: https://github.com/userver-framework/realmedium_sample/blob/develop/CMakeLists.txt Configures and links the unit test executable against the project's object library and userver's testing utilities. It also adds Google Tests. ```cmake # Unit Tests add_executable(${PROJECT_NAME}_unittest ${UNIT_TEST_SOURCES}) target_link_libraries(${PROJECT_NAME}_unittest PRIVATE ${PROJECT_NAME}_objs userver::utest) add_google_tests(${PROJECT_NAME}_unittest) ``` -------------------------------- ### Get All Tags Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Retrieves a comprehensive list of all tags that are currently in use across all articles on the platform. This endpoint does not require authentication. ```APIDOC ## GET /api/tags ### Description Returns a list of all available tags used in articles on the platform. This endpoint is publicly accessible. ### Method GET ### Endpoint `/api/tags` ### Parameters None ### Request Example ```bash curl -X GET http://localhost:8080/api/tags ``` ### Response #### Success Response (200 OK) - **tags** (array) - An array of strings, where each string is a unique tag. #### Response Example ```json { "tags": [ "cpp", "userver", "backend", "async", "coroutines", "performance", "postgresql", "microservices" ] } ``` ``` -------------------------------- ### Get Single Article (API) Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Retrieves a specific article by its slug identifier. Includes the author's profile and favorite status. Requires optional authentication. Handles responses for found and not found articles. ```bash # Get article by slug (optionally authenticated) curl -X GET http://localhost:8080/api/articles/getting-started-with-userver-framework \ -H "Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." # Error response for non-existent article (404 Not Found) { "errors": { "article": ["not found"] } } ``` -------------------------------- ### Get Article Comments (Bash) Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Retrieves all comments for a given article. The response includes author profiles and their following status. Can be optionally authenticated. ```bash # Get comments for article (optionally authenticated) curl -X GET http://localhost:8080/api/articles/getting-started-with-userver-framework/comments \ -H "Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ``` -------------------------------- ### Get Current User Profile API Request Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Illustrates how to retrieve the profile information of the currently authenticated user using their JWT token. It shows the GET request with the Authorization header and the expected successful response. It also covers the error response for missing or invalid tokens. ```bash # Get current user profile (authenticated) curl -X GET http://localhost:8080/api/user \ -H "Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." # Response (200 OK) { "user": { "email": "john@example.com", "username": "johndoe", "bio": "Software developer and tech writer", "image": "https://example.com/avatar.jpg", "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } } # Error response for missing/invalid token (401 Unauthorized) { "errors": { "message": "Empty 'Authorization' header" } } ``` -------------------------------- ### GET /api/articles/{slug} Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Retrieve a specific article by its slug identifier, including author profile and favorite status. ```APIDOC ## Get Single Article Retrieve a specific article by its slug identifier including author profile and favorite status. ### Method GET ### Endpoint /api/articles/{slug} ### Parameters #### Path Parameters - **slug** (string) - Required - The unique slug identifier of the article to retrieve. ### Request Example ```bash curl -X GET http://localhost:8080/api/articles/getting-started-with-userver-framework \ -H "Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ``` ### Response #### Success Response (200 OK) - **article** (object) - The requested article object. - **slug** (string) - Unique identifier for the article. - **title** (string) - The title of the article. - **description** (string) - A short description of the article. - **body** (string) - The full content of the article. - **tags** (array of strings) - Tags associated with the article. - **createdAt** (string) - The date and time the article was created (ISO 8601 format). - **updatedAt** (string) - The date and time the article was last updated (ISO 8601 format). - **favorited** (boolean) - Whether the current user has favorited this article. - **favoritesCount** (integer) - The total number of users who have favorited this article. - **author** (object) - The author of the article. - **username** (string) - The author's username. - **bio** (string) - The author's biography. - **image** (string) - The URL of the author's profile image. - **following** (boolean) - Whether the current user is following this author. #### Response Example ```json { "article": { "slug": "getting-started-with-userver-framework", "title": "Getting Started with userver Framework", "description": "Learn how to build high-performance C++ backends", "body": "The userver framework is a powerful tool for building asynchronous C++ applications...", "tags": ["cpp", "userver", "backend"], "createdAt": "2025-12-29T10:30:00Z", "updatedAt": "2025-12-29T10:30:00Z", "favorited": true, "favoritesCount": 5, "author": { "username": "johndoe", "bio": "Software developer and tech writer", "image": "https://example.com/avatar.jpg", "following": false } } } ``` #### Error Response (404 Not Found) - **errors** (object) - Contains error details. - **article** (array of strings) - "not found" if the article does not exist. #### Error Response Example ```json { "errors": { "article": ["not found"] } } ``` ``` -------------------------------- ### Get Articles List (API) Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Retrieves a list of recent articles from the API. Supports filtering by tag, author, or favorited user, and pagination using limit and offset parameters. Requires optional authentication. ```bash # Get recent articles (optionally authenticated) curl -X GET "http://localhost:8080/api/articles?tag=cpp&limit=10&offset=0" \ -H "Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." # Filter by author curl -X GET "http://localhost:8080/api/articles?author=johndoe&limit=20" # Filter by favorited user curl -X GET "http://localhost:8080/api/articles?favorited=janedoe&limit=20" ``` -------------------------------- ### Get Article Comments Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Retrieves all comments for a specific article, including author profiles and following status. This endpoint can be optionally authenticated. ```APIDOC ## GET /api/articles/{slug}/comments ### Description Retrieve all comments for a specific article including author profiles and following status. This endpoint can be optionally authenticated. ### Method GET ### Endpoint /api/articles/{slug}/comments #### Path Parameters - **slug** (string) - Required - The slug of the article whose comments are to be retrieved. ### Request Example ```bash curl -X GET http://localhost:8080/api/articles/getting-started-with-userver-framework/comments \ -H "Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ``` ### Response #### Success Response (200 OK) - **comments** (array) - List of comment objects. - **id** (integer) - Unique identifier for the comment. - **createdAt** (string) - ISO 8601 format timestamp of creation. - **updatedAt** (string) - ISO 8601 format timestamp of last update. - **body** (string) - The content of the comment. - **author** (object) - Author details. - **username** (string) - Author's username. - **bio** (string) - Author's biography. - **image** (string) - URL to the author's profile image. - **following** (boolean) - Whether the current user follows the author. #### Response Example ```json { "comments": [ { "id": 1, "createdAt": "2025-12-29T15:30:00Z", "updatedAt": "2025-12-29T15:30:00Z", "body": "Great article! Very informative and well-written.", "author": { "username": "janedoe", "bio": "C++ expert and conference speaker", "image": "https://example.com/jane-avatar.jpg", "following": false } } ] } ``` ``` -------------------------------- ### GET /api/articles Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Retrieve a list of recent articles with optional filtering by tag, author, or favorited user. Supports pagination with limit and offset parameters. ```APIDOC ## Get Articles Retrieve a list of recent articles with optional filtering by tag, author, or favorited user. Supports pagination with limit and offset parameters. ### Method GET ### Endpoint /api/articles ### Parameters #### Query Parameters - **tag** (string) - Optional - Filter articles by a specific tag. - **author** (string) - Optional - Filter articles by a specific author's username. - **favorited** (string) - Optional - Filter articles by a user who has favorited them. - **limit** (integer) - Optional - The maximum number of articles to return (default: 20). - **offset** (integer) - Optional - The number of articles to skip for pagination (default: 0). ### Request Example ```bash curl -X GET "http://localhost:8080/api/articles?tag=cpp&limit=10&offset=0" \ -H "Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ``` ### Response #### Success Response (200 OK) - **articles** (array) - An array of article objects. - **slug** (string) - Unique identifier for the article. - **title** (string) - The title of the article. - **description** (string) - A short description of the article. - **body** (string) - The full content of the article. - **tags** (array of strings) - Tags associated with the article. - **createdAt** (string) - The date and time the article was created (ISO 8601 format). - **updatedAt** (string) - The date and time the article was last updated (ISO 8601 format). - **favorited** (boolean) - Whether the current user has favorited this article. - **favoritesCount** (integer) - The total number of users who have favorited this article. - **author** (object) - The author of the article. - **username** (string) - The author's username. - **bio** (string) - The author's biography. - **image** (string) - The URL of the author's profile image. - **following** (boolean) - Whether the current user is following this author. - **articlesCount** (integer) - The total number of articles returned in this response. #### Response Example ```json { "articles": [ { "slug": "getting-started-with-userver-framework", "title": "Getting Started with userver Framework", "description": "Learn how to build high-performance C++ backends", "body": "The userver framework is a powerful tool...", "tags": ["cpp", "userver", "backend"], "createdAt": "2025-12-29T10:30:00Z", "updatedAt": "2025-12-29T10:30:00Z", "favorited": false, "favoritesCount": 5, "author": { "username": "johndoe", "bio": "Software developer and tech writer", "image": "https://example.com/avatar.jpg", "following": false } } ], "articlesCount": 1 } ``` ``` -------------------------------- ### Update User Profile API Request Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Demonstrates how to update the authenticated user's profile details. The example shows a PUT request with updated user information and the expected successful response. It allows modification of email, bio, and profile image. ```bash # Update user profile (authenticated) curl -X PUT http://localhost:8080/api/user \ -H "Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \ -H "Content-Type: application/json" \ -d '{ "user": { "email": "john.doe@example.com", "bio": "Experienced C++ developer passionate about high-performance systems", "image": "https://example.com/new-avatar.jpg" } }' # Response (200 OK) { "user": { "email": "john.doe@example.com", "username": "johndoe", "bio": "Experienced C++ developer passionate about high-performance systems", "image": "https://example.com/new-avatar.jpg", "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } } ``` -------------------------------- ### Get Article Feed Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Retrieves a personalized feed of articles based on followed users, sorted by creation date. Supports pagination with limit and offset. ```APIDOC ## GET /api/articles/feed ### Description Retrieve a personalized feed of articles from users you follow, sorted by creation date. Supports pagination. ### Method GET ### Endpoint /api/articles/feed #### Query Parameters - **limit** (integer) - Optional - Maximum number of articles to return. - **offset** (integer) - Optional - Number of articles to skip before returning. ### Request Example ```bash curl -X GET "http://localhost:8080/api/articles/feed?limit=20&offset=0" -H "Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ``` ### Response #### Success Response (200 OK) - **articles** (array) - List of article objects. - **slug** (string) - Unique identifier for the article. - **title** (string) - Title of the article. - **description** (string) - Short description of the article. - **body** (string) - Full content of the article. - **tags** (array of strings) - Tags associated with the article. - **createdAt** (string) - ISO 8601 format timestamp of creation. - **updatedAt** (string) - ISO 8601 format timestamp of last update. - **favorited** (boolean) - Whether the current user has favorited the article. - **favoritesCount** (integer) - Total number of favorites for the article. - **author** (object) - Author details. - **username** (string) - Author's username. - **bio** (string) - Author's biography. - **image** (string) - URL to the author's profile image. - **following** (boolean) - Whether the current user follows the author. - **articlesCount** (integer) - Total number of articles in the feed. #### Response Example ```json { "articles": [ { "slug": "async-patterns-in-cpp", "title": "Async Patterns in Modern C++", "description": "Exploring coroutines and async/await", "body": "Modern C++ provides powerful async capabilities...", "tags": ["cpp", "async", "coroutines"], "createdAt": "2025-12-29T14:20:00Z", "updatedAt": "2025-12-29T14:20:00Z", "favorited": false, "favoritesCount": 12, "author": { "username": "janedoe", "bio": "C++ expert and conference speaker", "image": "https://example.com/jane-avatar.jpg", "following": true } } ], "articlesCount": 1 } ``` ``` -------------------------------- ### Get All Tags (REST API) Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Retrieves a list of all tags used across articles on the platform. This endpoint does not require authentication and is useful for filtering or categorizing content. It returns a JSON array of tag strings. ```bash # Get all tags (no authentication required) curl -X GET http://localhost:8080/api/tags ``` -------------------------------- ### Get Article Feed (Bash) Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Retrieves a personalized feed of articles from users the authenticated user follows. The feed is sorted by creation date and supports pagination via limit and offset parameters. Requires an Authorization token. ```bash # Get personalized feed (authenticated) curl -X GET "http://localhost:8080/api/articles/feed?limit=20&offset=0" \ -H "Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ``` -------------------------------- ### Get User Profile Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Retrieves the public profile of a user, including their username, bio, image, and following status relative to the authenticated user. ```APIDOC ## GET /api/profiles/:username ### Description Fetches a user's public profile information. The `following` status indicates if the authenticated user follows the requested user. ### Method GET ### Endpoint `/api/profiles/:username` ### Parameters #### Path Parameters - **username** (string) - Required - The username of the profile to retrieve. #### Query Parameters None #### Request Body None ### Request Example ```bash curl -X GET http://localhost:8080/api/profiles/johndoe \ -H "Authorization: Token YOUR_AUTH_TOKEN" ``` ### Response #### Success Response (200 OK) - **profile** (object) - Contains the user's profile details. - **username** (string) - The user's unique username. - **bio** (string) - A short biography of the user. - **image** (string) - URL of the user's profile picture. - **following** (boolean) - True if the authenticated user follows this user, false otherwise. #### Response Example ```json { "profile": { "username": "johndoe", "bio": "Software developer and tech writer", "image": "https://example.com/avatar.jpg", "following": false } } ``` #### Error Response (404 Not Found) - **errors.username** (array) - An array containing an error message if the user is not found. #### Error Response Example ```json { "errors": { "username": ["There is no user with this nickname."] } } ``` ``` -------------------------------- ### Get Current User Profile API Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Retrieves the profile information of the currently authenticated user. Requires a valid JWT token in the Authorization header. ```APIDOC ## GET /api/user ### Description Retrieve the authenticated user's profile information using the JWT token. ### Method GET ### Endpoint /api/user ### Parameters #### Headers - **Authorization** (string) - Required - JWT token in the format `Token YOUR_TOKEN` ### Request Example ```bash curl -X GET http://localhost:8080/api/user \ -H "Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ``` ### Response #### Success Response (200 OK) - **user** (object) - Authenticated user details - **email** (string) - User's email - **username** (string) - User's username - **bio** (string) - User's biography - **image** (string) - User's profile image URL - **token** (string) - JWT authentication token #### Response Example ```json { "user": { "email": "john@example.com", "username": "johndoe", "bio": "Software developer and tech writer", "image": "https://example.com/avatar.jpg", "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } } ``` #### Error Response (401 Unauthorized) - **errors** (object) - Contains authentication error details - **message** (string) - Error message, e.g., "Empty 'Authorization' header" #### Error Response Example ```json { "errors": { "message": "Empty 'Authorization' header" } } ``` ``` -------------------------------- ### Get User Profile by Username (REST API) Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Retrieves a user's public profile information, including their bio, image, and following status relative to the authenticated user. This endpoint can be accessed with or without authentication. It returns profile details or an error if the user is not found. ```bash # Get user profile (optionally authenticated) curl -X GET http://localhost:8080/api/profiles/johndoe \ -H "Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ``` -------------------------------- ### Project Build and Deployment Commands Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Provides commands for cloning the repository, building the service in release or debug modes, running tests, and managing Docker Compose environments. Includes a command for code formatting. ```bash # Clone repository with submodules git clone --recurse-submodules https://github.com/userver-framework/realmedium_sample.git cd realmedium_sample # Docker Compose development workflow make docker-start-service-release # Build and start service make docker-test-release # Run tests make docker-clean-data # Clean up containers and data # Local development workflow make build-release # Build release binary make test-release # Run all tests make service-start-release # Start service locally # Development with debugging make build-debug # Build with sanitizers and assertions make test-debug # Run tests in debug mode make service-start-debug # Start with debug symbols # Code formatting make format # Auto-format C++ and Python sources ``` -------------------------------- ### SQL Library Generation Source: https://github.com/userver-framework/realmedium_sample/blob/develop/CMakeLists.txt Generates a SQL library for the project using userver_add_sql_library. It takes SQL files as input and places the generated code in a specified output directory with a given namespace. ```cmake userver_add_sql_library( ${PROJECT_NAME}_sql NAMESPACE real_medium OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR} SQL_FILES src/db/*.sql ) target_link_libraries(${PROJECT_NAME}_objs PUBLIC ${PROJECT_NAME}_sql) ``` -------------------------------- ### Functional Test Suite Configuration Source: https://github.com/userver-framework/realmedium_sample/blob/develop/CMakeLists.txt Sets up the functional test suite by specifying requirements and linking the SQL library. ```cmake # Functional Tests userver_testsuite_add_simple( REQUIREMENTS ${CMAKE_CURRENT_SOURCE_DIR}/tests/requirements.txt SQL_LIBRARY ${PROJECT_NAME}_sql ) ``` -------------------------------- ### Create Article API Request Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Shows how to create a new article using the API. This POST request includes the article's title, description, body, and optional tags. The system automatically generates a slug from the title. Authentication is required. ```bash # Create article (authenticated) curl -X POST http://localhost:8080/api/articles \ -H "Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \ -H "Content-Type: application/json" \ -d '{ "article": { "title": "Getting Started with userver Framework", "description": "Learn how to build high-performance C++ backends", "body": "The userver framework is a powerful tool for building asynchronous C++ applications...", "tags": ["cpp", "userver", "backend"] } }' ``` -------------------------------- ### Userver Dependency Management Source: https://github.com/userver-framework/realmedium_sample/blob/develop/CMakeLists.txt Configures userver dependency, falling back to a local subdirectory if not found system-wide. It enables specific userver features and sets up the environment. ```cmake cmake_minimum_required(VERSION 3.12) project(realmedium_sample CXX) # Adding userver dependency find_package(userver COMPONENTS core postgresql chaotic QUIET) if(NOT userver_FOUND) # Fallback to subdirectory usage # Enable userver libraries that are needed in this project set(USERVER_FEATURE_POSTGRESQL ON CACHE BOOL "" FORCE) # Compatibility mode: some systems don't support these features set(USERVER_FEATURE_CRYPTOPP_BLAKE2 OFF CACHE BOOL "" FORCE) if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/third_party/userver) message(STATUS "Using userver framework from third_party/userver") add_subdirectory(third_party/userver) else() message(FATAL_ERROR "Either install the userver or provide a path to it") endif() endif() userver_setup_environment() ``` -------------------------------- ### Cpp-JWT and Source File Configuration Source: https://github.com/userver-framework/realmedium_sample/blob/develop/CMakeLists.txt Integrates the cpp-jwt library and collects source files for the project. It distinguishes between regular sources and unit test sources. ```cmake set(CPP_JWT_BUILD_TESTS OFF) set(CPP_JWT_BUILD_EXAMPLES OFF) add_subdirectory(third_party/cpp-jwt) # Common sources file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.[hc]pp) file(GLOB_RECURSE UNIT_TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*_test.cpp) list(REMOVE_ITEM SOURCES ${UNIT_TEST_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp) add_library(${PROJECT_NAME}_objs OBJECT ${SOURCES}) include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) target_link_libraries(${PROJECT_NAME}_objs PUBLIC userver::postgresql) ``` -------------------------------- ### Create Article API Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Allows an authenticated user to create a new article. The article can include a title, description, body, and tags. The API generates a slug from the title. ```APIDOC ## POST /api/articles ### Description Create a new article with title, description, body, and optional tags. The system automatically generates a URL-friendly slug from the title. ### Method POST ### Endpoint /api/articles ### Parameters #### Headers - **Authorization** (string) - Required - JWT token in the format `Token YOUR_TOKEN` - **Content-Type** (string) - Required - `application/json` #### Request Body - **article** (object) - Required - Article details - **title** (string) - Required - The title of the article - **description** (string) - Required - A brief description of the article - **body** (string) - Required - The main content of the article - **tags** (array of strings) - Optional - Tags associated with the article ### Request Example ```json { "article": { "title": "Getting Started with userver Framework", "description": "Learn how to build high-performance C++ backends", "body": "The userver framework is a powerful tool for building asynchronous C++ applications...", "tags": ["cpp", "userver", "backend"] } } ``` ``` -------------------------------- ### ICU and Final Linking Source: https://github.com/userver-framework/realmedium_sample/blob/develop/CMakeLists.txt Links against the ICU library components (uc and i18n) and links the main object library with cpp-jwt. ```cmake find_package(ICU COMPONENTS uc i18n REQUIRED) target_link_libraries(${PROJECT_NAME}_objs PUBLIC ICU::uc ICU::i18n) # The Service add_executable(${PROJECT_NAME} src/main.cpp) target_link_libraries(${PROJECT_NAME} PRIVATE ${PROJECT_NAME}_objs) target_link_libraries(${PROJECT_NAME}_objs PUBLIC cpp-jwt) ``` -------------------------------- ### User Registration API Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Allows for the registration of new user accounts. It takes user credentials, hashes the password, and returns user information along with an authentication token upon successful registration. ```APIDOC ## POST /api/users ### Description Register a new user account with email, username, and password. The system automatically generates a random salt and hashes the password using SHA-256 before storing it in the database. ### Method POST ### Endpoint /api/users ### Parameters #### Request Body - **user** (object) - Required - User registration details - **email** (string) - Required - User's email address - **username** (string) - Required - User's desired username - **password** (string) - Required - User's password ### Request Example ```json { "user": { "email": "john@example.com", "username": "johndoe", "password": "securepassword123" } } ``` ### Response #### Success Response (200 OK) - **user** (object) - Registered user details - **email** (string) - User's email - **username** (string) - User's username - **bio** (string) - User's biography (null if not set) - **image** (string) - User's profile image URL (null if not set) - **token** (string) - JWT authentication token #### Response Example ```json { "user": { "email": "john@example.com", "username": "johndoe", "bio": null, "image": null, "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } } ``` #### Error Response (422 Unprocessable Entity) - **errors** (object) - Contains validation errors - **username** (array) - Error message indicating username already exists #### Error Response Example ```json { "errors": { "username": ["already exists"] } } ``` ``` -------------------------------- ### Configure PostgreSQL Cache for Articles in C++ Source: https://context7.com/userver-framework/realmedium_sample/llms.txt This C++ class configures a PostgreSQL-backed cache for article data, optimizing read performance. It defines settings for incremental and full update delays, chunk size, and manages multiple indexes (by ID, slug, follower) for efficient data retrieval and filtering. ```cpp // src/cache/articles_cache.hpp // PostgreCache configuration for articles class ArticlesCache final : public PostgreCache { static constexpr std::string_view kName = "articles-cache"; // Cache update settings static constexpr auto kUpdDelay = std::chrono::seconds{10}; // Incremental static constexpr auto kFullUpdDelay = std::chrono::minutes{1}; // Full update static constexpr size_t kChunkSize = 100; // Articles per chunk // Multiple indexes for efficient lookups unordered_map by_id_; unordered_map by_slug_; multimap by_follower_; // For feed vector recent_articles_; // Sorted by creation time // Efficient article filtering vector getRecent(const ArticleFilterDTO& filter) { vector result; for (auto* article : recent_articles_) { if (filter.tag && !article->tags.contains(*filter.tag)) continue; if (filter.author && article->authorInfo.username != *filter.author) continue; if (filter.favorited && !article->articleFavoritedByUsernames.contains(*filter.favorited)) continue; result.push_back(article); if (filter.limit && result.size() >= *filter.limit) break; } return result; } }; ``` -------------------------------- ### User Registration API Request Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Demonstrates how to register a new user account via the RESTful API. It includes the request payload with user credentials and expected success/error responses. The API hashes passwords using SHA-256. ```bash # Register a new user curl -X POST http://localhost:8080/api/users \ -H "Content-Type: application/json" \ -d '{ "user": { "email": "john@example.com", "username": "johndoe", "password": "securepassword123" } }' # Response (200 OK) { "user": { "email": "john@example.com", "username": "johndoe", "bio": null, "image": null, "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } } # Error response for duplicate username (422 Unprocessable Entity) { "errors": { "username": ["already exists"] } } ``` -------------------------------- ### Chaotic Schema Generation Source: https://github.com/userver-framework/realmedium_sample/blob/develop/CMakeLists.txt Generates serializers and handlers from YAML schema files using the userver_target_generate_chaotic macro. It specifies input schemas and output directories. ```cmake file(GLOB_RECURSE SCHEMAS ${CMAKE_CURRENT_SOURCE_DIR}/docs/*.yaml) userver_target_generate_chaotic(${PROJECT_NAME}-chgen LAYOUT "/components/schemas/([^/]*)/=real_medium::handlers::{0}" GENERATE_SERIALIZERS OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/src SCHEMAS ${SCHEMAS} RELATIVE_TO ${CMAKE_CURRENT_SOURCE_DIR} ) target_link_libraries(${PROJECT_NAME}_objs PUBLIC ${PROJECT_NAME}-chgen) ``` -------------------------------- ### PUT /api/articles/{slug} Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Update an existing article's title, description, body, or tags. Only the article author can perform updates. ```APIDOC ## Update Article Update an existing article's title, description, body, or tags. Only the article author can perform updates. ### Method PUT ### Endpoint /api/articles/{slug} ### Parameters #### Path Parameters - **slug** (string) - Required - The unique slug identifier of the article to update. #### Request Body - **article** (object) - Required - The article object containing fields to update. - **title** (string) - Optional - The new title for the article. - **description** (string) - Optional - The new description for the article. - **body** (string) - Optional - The new body content for the article. - **tags** (array of strings) - Optional - The new list of tags for the article. ### Request Example ```bash curl -X PUT http://localhost:8080/api/articles/getting-started-with-userver-framework \ -H "Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \ -H "Content-Type: application/json" \ -d '{ "article": { "title": "Advanced userver Framework Techniques", "body": "Updated content with advanced techniques...", "tags": ["cpp", "userver", "backend", "advanced"] } }' ``` ### Response #### Success Response (200 OK) - **article** (object) - The updated article object. - **slug** (string) - Unique identifier for the article. - **title** (string) - The title of the article. - **description** (string) - A short description of the article. - **body** (string) - The full content of the article. - **tags** (array of strings) - Tags associated with the article. - **createdAt** (string) - The date and time the article was created (ISO 8601 format). - **updatedAt** (string) - The date and time the article was last updated (ISO 8601 format). - **favorited** (boolean) - Whether the current user has favorited this article. - **favoritesCount** (integer) - The total number of users who have favorited this article. - **author** (object) - The author of the article. - **username** (string) - The author's username. - **bio** (string) - The author's biography. - **image** (string) - The URL of the author's profile image. - **following** (boolean) - Whether the current user is following this author. #### Response Example ```json { "article": { "slug": "getting-started-with-userver-framework", "title": "Advanced userver Framework Techniques", "description": "Learn how to build high-performance C++ backends", "body": "Updated content with advanced techniques...", "tags": ["cpp", "userver", "backend", "advanced"], "createdAt": "2025-12-29T10:30:00Z", "updatedAt": "2025-12-29T12:45:00Z", "favorited": false, "favoritesCount": 5, "author": { "username": "johndoe", "bio": "Software developer and tech writer", "image": "https://example.com/avatar.jpg", "following": false } } } ``` #### Error Response (403 Forbidden) - **errors** (object) - Contains error details. - **message** (string) - "Forbidden" if the user is not the author of the article. #### Error Response Example ```json { "errors": { "message": "Forbidden" } } ``` ``` -------------------------------- ### PostgreSQL Database Schema Creation Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Defines the core tables for users, articles, comments, favorites, and followers, along with custom composite types for profile and tagged article data. This schema supports complex relationships and efficient data retrieval. ```sql -- Core tables CREATE TABLE real_medium.users( user_id text PRIMARY KEY DEFAULT uuid_generate_v4(), username varchar(255) NOT NULL, email varchar(255) NOT NULL, bio text, image varchar(255), password_hash varchar(255) NOT NULL, salt varchar(255) NOT NULL, CONSTRAINT uniq_username UNIQUE (username), CONSTRAINT uniq_email UNIQUE (email) ); CREATE TABLE real_medium.articles( article_id text PRIMARY KEY DEFAULT uuid_generate_v4(), title varchar(255) NOT NULL, slug varchar(255) NOT NULL, body text NOT NULL, description text NOT NULL, created_at timestamptz NOT NULL DEFAULT NOW(), updated_at timestamptz NOT NULL DEFAULT NOW(), favorites_count bigint DEFAULT 0, user_id text NOT NULL, CONSTRAINT fk_article_author FOREIGN KEY (user_id) REFERENCES real_medium.users(user_id), CONSTRAINT uniq_slug UNIQUE (slug) ); CREATE TABLE real_medium.comments( comment_id bigserial PRIMARY KEY, created_at timestamptz NOT NULL DEFAULT NOW(), updated_at timestamptz NOT NULL DEFAULT NOW(), body varchar(16384) NOT NULL, user_id text NOT NULL, article_id text NOT NULL, CONSTRAINT fk_article FOREIGN KEY (article_id) REFERENCES real_medium.articles(article_id) ON DELETE CASCADE, CONSTRAINT fk_author FOREIGN KEY (user_id) REFERENCES real_medium.users(user_id) ON DELETE CASCADE ); CREATE TABLE real_medium.favorites( article_id text NOT NULL, user_id text NOT NULL, CONSTRAINT pk_favorites PRIMARY KEY (user_id, article_id), CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES real_medium.users(user_id) ON DELETE CASCADE, CONSTRAINT fk_article FOREIGN KEY (article_id) REFERENCES real_medium.articles(article_id) ON DELETE CASCADE ); CREATE TABLE real_medium.followers( followed_user_id text NOT NULL, follower_user_id text NOT NULL, CONSTRAINT pk_followers PRIMARY KEY (follower_user_id, followed_user_id), CONSTRAINT fk_follower FOREIGN KEY (follower_user_id) REFERENCES real_medium.users(user_id), CONSTRAINT fk_followed FOREIGN KEY (followed_user_id) REFERENCES real_medium.users(user_id) ); -- Custom composite types for efficient data retrieval CREATE TYPE real_medium.profile AS ( username varchar(255), bio text, image varchar(255), following boolean ); CREATE TYPE real_medium.tagged_article_with_author_profile AS ( article_id text, title varchar(255), slug varchar(255), body text, description text, created_at timestamptz, updated_at timestamptz, tags varchar(255)[], favorited boolean, favorites_count bigint, author_profile real_medium.profile ); ``` -------------------------------- ### User Login API Request Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Shows the process of authenticating a user via the API. It includes the request payload with user email and password, and the expected successful response containing a JWT token. Error handling for invalid credentials is also demonstrated. ```bash # Login user curl -X POST http://localhost:8080/api/users/login \ -H "Content-Type: application/json" \ -d '{ "user": { "email": "john@example.com", "password": "securepassword123" } }' # Response (200 OK) { "user": { "email": "john@example.com", "username": "johndoe", "bio": "Software developer and tech writer", "image": "https://example.com/avatar.jpg", "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } } # Error response for invalid credentials (404 Not Found) { "errors": { "email or password": ["is invalid"] } } ``` -------------------------------- ### Update Article (API) Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Updates an existing article's title, description, body, or tags. This operation can only be performed by the article's author and requires authentication. It returns the updated article or an error if unauthorized or the article is not found. ```bash # Update article (authenticated, author only) curl -X PUT http://localhost:8080/api/articles/getting-started-with-userver-framework \ -H "Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \ -H "Content-Type: application/json" \ -d '{ "article": { "title": "Advanced userver Framework Techniques", "body": "Updated content with advanced techniques...", "tags": ["cpp", "userver", "backend", "advanced"] } }' # Error response for non-author (403 Forbidden) { "errors": { "message": "Forbidden" } } ``` -------------------------------- ### Follow User Source: https://context7.com/userver-framework/realmedium_sample/llms.txt Allows an authenticated user to follow another user. Once followed, the target user's articles will appear in the authenticated user's feed. ```APIDOC ## POST /api/profiles/:username/follow ### Description Enables an authenticated user to follow another user. This updates the `following` status in the target user's profile to true for the follower. ### Method POST ### Endpoint `/api/profiles/:username/follow` ### Parameters #### Path Parameters - **username** (string) - Required - The username of the user to follow. #### Query Parameters None #### Request Body None ### Request Example ```bash curl -X POST http://localhost:8080/api/profiles/johndoe/follow \ -H "Authorization: Token YOUR_AUTH_TOKEN" ``` ### Response #### Success Response (200 OK) - **profile** (object) - The updated profile of the followed user. - **username** (string) - The user's unique username. - **bio** (string) - A short biography of the user. - **image** (string) - URL of the user's profile picture. - **following** (boolean) - True, as the user is now being followed. #### Response Example ```json { "profile": { "username": "johndoe", "bio": "Software developer and tech writer", "image": "https://example.com/avatar.jpg", "following": true } } ``` #### Error Response (400 Bad Request) - **errors.message** (string) - Indicates that the user is already being followed. #### Error Response Example ```json { "errors": { "message": "Already followed" } } ``` ```