docs: cpp,client,frontends (4 files)

This commit is contained in:
2025-12-26 06:10:51 +00:00
parent 62374a10f9
commit 5a39d253ee
4 changed files with 120 additions and 0 deletions

View File

@@ -50,6 +50,14 @@ Result<int> Client::batchDeleteUsers(const std::vector<std::string>& ids) {
return entities::user::batchDelete(getStore(), ids);
}
Result<std::vector<User>> Client::searchUsers(const std::string& query, int limit) {
return entities::user::search(getStore(), query, limit);
}
Result<int> Client::countUsers(const std::optional<UserRole>& role) {
return entities::user::count(getStore(), role);
}
Result<bool> Client::setCredential(const CreateCredentialInput& input) {
return entities::credential::set(getStore(), input);
}

View File

@@ -211,6 +211,75 @@ void test_credential_validation() {
std::cout << " ✓ Empty password hash rejected" << std::endl;
}
void test_user_search() {
std::cout << "Testing user search..." << std::endl;
dbal::ClientConfig config;
config.adapter = "sqlite";
config.database_url = ":memory:";
dbal::Client client(config);
dbal::CreateUserInput user1;
user1.username = "search_alpha";
user1.email = "alpha@example.com";
auto result1 = client.createUser(user1);
assert(result1.isOk());
dbal::CreateUserInput user2;
user2.username = "search_beta";
user2.email = "beta@examples.com";
auto result2 = client.createUser(user2);
assert(result2.isOk());
auto found = client.searchUsers("search", 10);
assert(found.isOk());
assert(found.value().size() >= 2);
std::cout << " ✓ Search matched multiple users" << std::endl;
auto caseInsensitive = client.searchUsers("SEARCH_BETA", 10);
assert(caseInsensitive.isOk());
assert(caseInsensitive.value().size() == 1);
assert(caseInsensitive.value()[0].username == "search_beta");
std::cout << " ✓ Search is case-insensitive" << std::endl;
auto limited = client.searchUsers("search", 1);
assert(limited.isOk());
assert(limited.value().size() == 1);
std::cout << " ✓ Search respects limit" << std::endl;
}
void test_user_count() {
std::cout << "Testing user count..." << std::endl;
dbal::ClientConfig config;
config.adapter = "sqlite";
config.database_url = ":memory:";
dbal::Client client(config);
dbal::CreateUserInput user;
user.username = "count_user";
user.email = "count@example.com";
auto result = client.createUser(user);
assert(result.isOk());
dbal::CreateUserInput admin;
admin.username = "count_admin";
admin.email = "count_admin@example.com";
admin.role = dbal::UserRole::Admin;
auto adminResult = client.createUser(admin);
assert(adminResult.isOk());
auto totalCount = client.countUsers();
assert(totalCount.isOk());
assert(totalCount.value() >= 2);
std::cout << " ✓ Total user count matches" << std::endl;
auto adminCount = client.countUsers(dbal::UserRole::Admin);
assert(adminCount.isOk());
assert(adminCount.value() >= 1);
std::cout << " ✓ Admin count matches" << std::endl;
}
void test_get_user() {
std::cout << "Testing get user..." << std::endl;

View File

@@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.27)
project(metabuilder_cli VERSION 0.1.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(${CMAKE_BINARY_DIR}/conan_toolchain.cmake OPTIONAL)
add_executable(metabuilder-cli
src/main.cpp
src/commands/command_dispatch.cpp
src/utils/http_client.cpp
)
find_package(cpr CONFIG REQUIRED)
target_link_libraries(metabuilder-cli PRIVATE cpr::cpr)
target_compile_features(metabuilder-cli PRIVATE cxx_std_20)
target_include_directories(metabuilder-cli PRIVATE src)
install(TARGETS metabuilder-cli
RUNTIME DESTINATION bin
)

View File

@@ -0,0 +1,19 @@
#pragma once
#include <cpr/cpr.h>
#include <string>
class HttpClient {
public:
explicit HttpClient(std::string base_url);
cpr::Response get(const std::string &path) const;
cpr::Response post(const std::string &path,
const std::string &body,
const std::string &content_type = "application/json") const;
[[nodiscard]] const std::string &base_url() const noexcept;
private:
std::string base_url_;
};