Skip to content

refactor(daemon)!: verticalize architecture#164

Draft
LordTermor wants to merge 1 commit intoanydistro:masterfrom
LordTermor:refactor/vertical
Draft

refactor(daemon)!: verticalize architecture#164
LordTermor wants to merge 1 commit intoanydistro:masterfrom
LordTermor:refactor/vertical

Conversation

@LordTermor
Copy link
Collaborator

WIP

  • vertical slice instead of horizontal layers
  • not strict DDD, more DDD-like KISS YAGNI approach
  • reworked persistency layer (sql via sqlgen instead of lmdb)
  • reworked errors (new cpperr library)
  • more extensive usage of modern C++ ranges
  • xmake instead of cmake (keeping cmake for libs)
  • new API with more common backend features like pagination

@LordTermor LordTermor self-assigned this Nov 27, 2025
@LordTermor LordTermor requested a review from Copilot November 27, 2025 16:16
@LordTermor LordTermor added enhancement New feature or request Daemon Changes related to the backend Refactoring Readability code changes labels Nov 27, 2025
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the daemon architecture from horizontal layers to a vertical slice approach, modernizing the codebase with contemporary C++ features and replacing key infrastructure components. The changes move away from LMDB persistence to SQL via sqlgen, introduce a new error handling library (cpperr), and migrate from CMake to xmake for the main build while keeping CMake for libraries.

Key Changes:

  • Introduced a new percpptency library implementing DDD-like patterns with repositories, aggregates, and domain events
  • Added AsyncAPI specification for WebSocket real-time updates
  • Removed legacy horizontal layer code including LMDB persistence, utilities, presentation controllers, and test infrastructure
  • Enhanced Docker Compose configuration with user-specific settings and development mode support

Reviewed changes

Copilot reviewed 247 out of 357 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
vertical/api/asyncapi.yaml WebSocket API specification for package synchronization events
percpptency/* Complete DDD-inspired persistence library with repositories, aggregates, unit of work patterns, and SQLite adapter
docker-compose.yml Enhanced with user/UID/GID mapping and additional volume mounts
docker-compose.dev.yml New development-specific Docker Compose configuration
daemon/* (removed) Legacy horizontal architecture removed including utilities, presentation, persistence layers, tests, and Swagger documentation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

// Extract events first if this is an aggregate root
std::vector<std::unique_ptr<DomainEvent>> events;
if constexpr (std::is_base_of_v<AggregateRoot<TEntity>, TEntity>) {
events = entity.take_uncommitted_events();
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Type mismatch: take_uncommitted_events() returns std::vector<DomainEvent> (by value), but the code assigns it to std::vector<std::unique_ptr<DomainEvent>>. The same issue occurs on line 183 in the update method.

Suggested change
events = entity.take_uncommitted_events();
auto raw_events = entity.take_uncommitted_events();
events.reserve(raw_events.size());
for (auto& event : raw_events) {
events.push_back(std::make_unique<DomainEvent>(std::move(event)));
}

Copilot uses AI. Check for mistakes.
virtual ResultCount count() = 0;
virtual ResultVoid create(TEntity& entity) = 0;
virtual ResultVoid update(TEntity& entity) = 0;
virtual ResultBool delete_by_id(TId id) = 0;
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return type ResultBool is inconsistent with the other methods. Most CRUD delete operations return ResultVoid (indicating success/failure) rather than a boolean. Consider changing to ResultVoid for consistency unless the boolean has specific semantic meaning.

Suggested change
virtual ResultBool delete_by_id(TId id) = 0;
virtual ResultVoid delete_by_id(TId id) = 0;

Copilot uses AI. Check for mistakes.
Comment on lines +62 to +67
ResultVoid delete_by_id(std::string id) override {
auto it = std::remove_if(storage.begin(), storage.end(),
[&](auto const& e) { return e.m_data.id == id; });
if (it != storage.end()) {
storage.erase(it, storage.end());
return {};
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return type mismatch: The interface declares delete_by_id to return ResultBool, but the mock implementation returns ResultVoid. This violates the interface contract.

Suggested change
ResultVoid delete_by_id(std::string id) override {
auto it = std::remove_if(storage.begin(), storage.end(),
[&](auto const& e) { return e.m_data.id == id; });
if (it != storage.end()) {
storage.erase(it, storage.end());
return {};
ResultBool delete_by_id(std::string id) override {
auto it = std::remove_if(storage.begin(), storage.end(),
[&](auto const& e) { return e.m_data.id == id; });
if (it != storage.end()) {
storage.erase(it, storage.end());
return true;

Copilot uses AI. Check for mistakes.
WIP

- vertical slice instead of horizontal layers
- not strict DDD, more DDD-like KISS YAGNI approach
- reworked persistency layer (sql via sqlgen instead of lmdb)
- reworked errors (new cpperr library)
- more extensive usage of modern C++ ranges
- xmake instead of cmake (keeping cmake for libs)
- new API with more common backend features like pagination
@LordTermor LordTermor marked this pull request as draft November 27, 2025 16:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Daemon Changes related to the backend enhancement New feature or request Refactoring Readability code changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants