Skip to content

[Refactor]: Transitioning to a modular hexagonal core #212

@Gijsdeman

Description

@Gijsdeman

Overview of proposal

The current architecture of aurora-core functions as a almost monolithic entity, which limits extensibility and increases infrastructural coupling.

By moving to a modular hexagonal core we aim to refactor the repository into a plugin-based architecture (inspired by the Docusaurus setup) utilizing Hexagonal Architecture principles and Inversion of Control (IoC).

By decoupling the domain logic from infrastructural concerns (databases, authentication, hardware protocols), we will allow users to "hook" custom plugins into a central eventing system without modifying the core codebase.

Architectural Objectives

  • Decoupling: Separate the "Core" (domain logic) from "Adapters" (database, auth, etc.).
  • Inversion of Control: Utilize tsyringe for Dependency Injection to manage service lifecycles.
  • Workspace Orchestration: Move to a monorepo structure (preferably pnpm workspaces) to enforce strict dependency boundaries.
  • Plugin Ecosystem: Enable a system where @gewis/aurora-core is the orchestrator and all other features are interchangeable modules.

Implementation Strategy

The refactor will follow the Ports and Adapters pattern. The Core defines the Port (the interface), and external packages provide the Adapter (the implementation).

Note: This is a Strangler Fig refactor. We will maintain system stability by extracting modules piece-by-piece rather than a big bang rewrite.

Phase 1: structural foundations & extraction

Workspace initialization & core package migration

  • Initialize monorepo structure (e.g. packages/core, packages/plugins/*)
  • Migrate existing core logic into @gewis/aurora-core workspace
  • Establish a Common/Utilities package for shared types and interfaces to prevent circular dependencies.
  • Integrate tsyringe as the primary DI container within the core.
  • Testing Node: Establish a centralized testing configuration (Vitest) that works across all workspaces.
  • Testing Node: Implement unit tests for the DI Container to ensure the core is stable.

Database abstraction and extraction (storage port)

  • Define the IDatabaseDriver port (interface) within @gewis/aurora-core
  • Implement the first database adapter in a separate package: @gewis/aurora-db-sqlite
  • Refactor the core to request IDatabaseDriver via injection rather than static imports
  • Verify data persistence and transaction integrity across the new package boundary
  • Testing Node: Create a Contract Test Suite for IDatabaseDriver. Any new database plugin must pass these tests to ensure it satisfies the Core's requirements.
  • Testing Node: Implement integration tests for the @gewis/aurora-sqlite package using a test container or mock database.

Authentication abstraction and extraction (authentication port)

  • Define the IAuthService port in @gewis/aurora-core
  • Extract Logic to @gewis/aurora-auth-{method}
  • Implement Dependency Injection for Security Guards
  • Decouple User Persistence from Auth Logic (ensure usage of IDatabaseDriver)
  • Testing Node: Implement unit tests for the Auth logic in isolation within its workspace.
  • Testing Node: Perform "Plug-and-Play" verification: Ensure the Core can successfully authenticate a user when the Auth plugin is injected via tsyringe.

Phase 2

To be determined. With the initial setup of the hexagonal architecture we can start dissecting the core of Aurora and extract domain specific logic to separate ports. It is too early to see exactly what this might look like.

Metadata

Metadata

Assignees

No one assigned

    Labels

    For: CodeFor issues which specifically relates to the code, not its functionality.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions