<!doctype html><html lang=en class=no-js> <head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta name=description content="Documentation for Hexagonal"><meta name=author content="Anya Core Team"><link href=https://docs.anya.org/hexagonal/ rel=canonical><link rel=icon href=../assets/images/favicon.png><meta name=generator content="mkdocs-1.6.1, mkdocs-material-9.6.14"><title>Hexagonal - Anya Core</title><link rel=stylesheet href=../assets/stylesheets/main.342714a4.min.css><link rel=stylesheet href=../assets/stylesheets/palette.06af60db.min.css><link rel=preconnect href=https://fonts.gstatic.com crossorigin><link rel=stylesheet href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback"><style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style><link rel=stylesheet href=../css/timeago.css><link rel=stylesheet href=../styles/extra.css><script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script><script id=__analytics>function __md_analytics(){function e(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],e("js",new Date),e("config","G-XXXXXXXXXX"),document.addEventListener("DOMContentLoaded",(function(){document.forms.search&&document.forms.search.query.addEventListener("blur",(function(){this.value&&e("event","search",{search_term:this.value})}));document$.subscribe((function(){var t=document.forms.feedback;if(void 0!==t)for(var a of t.querySelectorAll("[type=submit]"))a.addEventListener("click",(function(a){a.preventDefault();var n=document.location.pathname,d=this.getAttribute("data-md-value");e("event","feedback",{page:n,data:d}),t.firstElementChild.disabled=!0;var r=t.querySelector(".md-feedback__note [data-md-value='"+d+"']");r&&(r.hidden=!1)})),t.hidden=!1})),location$.subscribe((function(t){e("config","G-XXXXXXXXXX",{page_path:t.pathname})}))}));var t=document.createElement("script");t.async=!0,t.src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX",document.getElementById("__analytics").insertAdjacentElement("afterEnd",t)}</script><script>"undefined"!=typeof __md_analytics&&__md_analytics()</script></head> <body dir=ltr data-md-color-scheme=default data-md-color-primary=indigo data-md-color-accent=indigo> <input class=md-toggle data-md-toggle=drawer type=checkbox id=__drawer autocomplete=off> <input class=md-toggle data-md-toggle=search type=checkbox id=__search autocomplete=off> <label class=md-overlay for=__drawer></label> <div data-md-component=skip> <a href=#hexagonal-architecture-in-anya-core class=md-skip> Skip to content </a> </div> <div data-md-component=announce> </div> <div data-md-color-scheme=default data-md-component=outdated hidden> </div> <header class="md-header md-header--shadow md-header--lifted" data-md-component=header> <nav class="md-header__inner md-grid" aria-label=Header> <a href=.. title="Anya Core" class="md-header__button md-logo" aria-label="Anya Core" data-md-component=logo> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg> </a> <label class="md-header__button md-icon" for=__drawer> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg> </label> <div class=md-header__title data-md-component=header-title> <div class=md-header__ellipsis> <div class=md-header__topic> <span class=md-ellipsis> Anya Core </span> </div> <div class=md-header__topic data-md-component=header-topic> <span class=md-ellipsis> Hexagonal </span> </div> </div> </div> <form class=md-header__option data-md-component=palette> <input class=md-option data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme=default data-md-color-primary=indigo data-md-color-accent=indigo aria-label="Switch to dark mode" type=radio name=__palette id=__palette_0> <label class="md-header__button md-icon" title="Switch to dark mode" for=__palette_1 hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 7a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0-7 2.39 3.42C13.65 5.15 12.84 5 12 5s-1.65.15-2.39.42zM3.34 7l4.16-.35A7.2 7.2 0 0 0 5.94 8.5c-.44.74-.69 1.5-.83 2.29zm.02 10 1.76-3.77a7.131 7.131 0 0 0 2.38 4.14zM20.65 7l-1.77 3.79a7.02 7.02 0 0 0-2.38-4.15zm-.01 10-4.14.36c.59-.51 1.12-1.14 1.54-1.86.42-.73.69-1.5.83-2.29zM12 22l-2.41-3.44c.74.27 1.55.44 2.41.44.82 0 1.63-.17 2.37-.44z"/></svg> </label> <input class=md-option data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme=slate data-md-color-primary=indigo data-md-color-accent=indigo aria-label="Switch to light mode" type=radio name=__palette id=__palette_1> <label class="md-header__button md-icon" title="Switch to light mode" for=__palette_0 hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="m17.75 4.09-2.53 1.94.91 3.06-2.63-1.81-2.63 1.81.91-3.06-2.53-1.94L12.44 4l1.06-3 1.06 3zm3.5 6.91-1.64 1.25.59 1.98-1.7-1.17-1.7 1.17.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95zm-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14.4-.4.82-.76 1.27-1.08.75-.53 1.93.36 1.85 1.19-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82-2.81 3.14-2.7 7.96.31 10.98 3.02 3.01 7.84 3.12 10.98.31"/></svg> </label> </form> <script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script> <label class="md-header__button md-icon" for=__search> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg> </label> <div class=md-search data-md-component=search role=dialog> <label class=md-search__overlay for=__search></label> <div class=md-search__inner role=search> <form class=md-search__form name=search> <input type=text class=md-search__input name=query aria-label=Search placeholder=Search autocapitalize=off autocorrect=off autocomplete=off spellcheck=false data-md-component=search-query required> <label class="md-search__icon md-icon" for=__search> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg> </label> <nav class=md-search__options aria-label=Search> <a href=javascript:void(0) class="md-search__icon md-icon" title=Share aria-label=Share data-clipboard data-clipboard-text data-md-component=search-share tabindex=-1> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg> </a> <button type=reset class="md-search__icon md-icon" title=Clear aria-label=Clear tabindex=-1> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg> </button> </nav> <div class=md-search__suggest data-md-component=search-suggest></div> </form> <div class=md-search__output> <div class=md-search__scrollwrap tabindex=0 data-md-scrollfix> <div class=md-search-result data-md-component=search-result> <div class=md-search-result__meta> Initializing search </div> <ol class=md-search-result__list role=presentation></ol> </div> </div> </div> </div> </div> <div class=md-header__source> <a href=https://github.com/anya-org/anya-core title="Go to repository" class=md-source data-md-component=source> <div class="md-source__icon md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 448 512"><!-- Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81"/></svg> </div> <div class=md-source__repository> anya-org/anya-core </div> </a> </div> </nav> <nav class=md-tabs aria-label=Tabs data-md-component=tabs> <div class=md-grid> <ul class=md-tabs__list> <li class=md-tabs__item> <a href=.. class=md-tabs__link> Home </a> </li> <li class=md-tabs__item> <a href=../INSTALLATION/ class=md-tabs__link> Getting Started </a> </li> <li class=md-tabs__item> <a href=../ARCHITECTURE/ class=md-tabs__link> Architecture </a> </li> <li class=md-tabs__item> <a href=../CONTRIBUTING/ class=md-tabs__link> Development </a> </li> <li class=md-tabs__item> <a href=../BITCOIN_PROTOCOL/ class=md-tabs__link> Bitcoin & Layer2 </a> </li> <li class=md-tabs__item> <a href=../WEB5_INTEGRATION/ class=md-tabs__link> Web5 & Identity </a> </li> <li class=md-tabs__item> <a href=../ENTERPRISE_GUIDE/ class=md-tabs__link> Enterprise </a> </li> <li class=md-tabs__item> <a href=../DAO_OVERVIEW/ class=md-tabs__link> DAO & Governance </a> </li> <li class=md-tabs__item> <a href=../API/ class=md-tabs__link> API Reference </a> </li> <li class=md-tabs__item> <a href=../ROADMAP/ class=md-tabs__link> Maintenance </a> </li> </ul> </div> </nav> </header> <div class=md-container data-md-component=container> <main class=md-main data-md-component=main> <div class="md-main__inner md-grid"> <div class="md-sidebar md-sidebar--primary" data-md-component=sidebar data-md-type=navigation> <div class=md-sidebar__scrollwrap> <div class=md-sidebar__inner> <nav class="md-nav md-nav--primary md-nav--lifted" aria-label=Navigation data-md-level=0> <label class=md-nav__title for=__drawer> <a href=.. title="Anya Core" class="md-nav__button md-logo" aria-label="Anya Core" data-md-component=logo> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg> </a> Anya Core </label> <div class=md-nav__source> <a href=https://github.com/anya-org/anya-core title="Go to repository" class=md-source data-md-component=source> <div class="md-source__icon md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 448 512"><!-- Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81"/></svg> </div> <div class=md-source__repository> anya-org/anya-core </div> </a> </div> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=.. class=md-nav__link> <span class=md-ellipsis> Home </span> </a> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_2> <label class=md-nav__link for=__nav_2 id=__nav_2_label tabindex=0> <span class=md-ellipsis> Getting Started </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=1 aria-labelledby=__nav_2_label aria-expanded=false> <label class=md-nav__title for=__nav_2> <span class="md-nav__icon md-icon"></span> Getting Started </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../INSTALLATION/ class=md-nav__link> <span class=md-ellipsis> Installation </span> </a> </li> <li class=md-nav__item> <a href=../SETUP_USAGE/ class=md-nav__link> <span class=md-ellipsis> Setup </span> </a> </li> <li class=md-nav__item> <a href=../ENVIRONMENT/ class=md-nav__link> <span class=md-ellipsis> Environment </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_3> <label class=md-nav__link for=__nav_3 id=__nav_3_label tabindex=0> <span class=md-ellipsis> Architecture </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=1 aria-labelledby=__nav_3_label aria-expanded=false> <label class=md-nav__title for=__nav_3> <span class="md-nav__icon md-icon"></span> Architecture </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../ARCHITECTURE/ class=md-nav__link> <span class=md-ellipsis> Overview </span> </a> </li> <li class=md-nav__item> <a href=../AGENT_ARCHITECTURE/ class=md-nav__link> <span class=md-ellipsis> Agent System </span> </a> </li> <li class=md-nav__item> <a href=../PERFORMANCE_ARCHITECTURE/ class=md-nav__link> <span class=md-ellipsis> Performance </span> </a> </li> <li class=md-nav__item> <a href=../SECURITY_ARCHITECTURE/ class=md-nav__link> <span class=md-ellipsis> Security </span> </a> </li> <li class=md-nav__item> <a href=../ML_SYSTEM_ARCHITECTURE/ class=md-nav__link> <span class=md-ellipsis> ML System </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_4> <label class=md-nav__link for=__nav_4 id=__nav_4_label tabindex=0> <span class=md-ellipsis> Development </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=1 aria-labelledby=__nav_4_label aria-expanded=false> <label class=md-nav__title for=__nav_4> <span class="md-nav__icon md-icon"></span> Development </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../CONTRIBUTING/ class=md-nav__link> <span class=md-ellipsis> Contributing </span> </a> </li> <li class=md-nav__item> <a href=../development/ class=md-nav__link> <span class=md-ellipsis> Development Guide </span> </a> </li> <li class=md-nav__item> <a href=../TESTING/ class=md-nav__link> <span class=md-ellipsis> Testing </span> </a> </li> <li class=md-nav__item> <a href=../ERROR_HANDLING/ class=md-nav__link> <span class=md-ellipsis> Error Handling </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_5> <label class=md-nav__link for=__nav_5 id=__nav_5_label tabindex=0> <span class=md-ellipsis> Bitcoin & Layer2 </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=1 aria-labelledby=__nav_5_label aria-expanded=false> <label class=md-nav__title for=__nav_5> <span class="md-nav__icon md-icon"></span> Bitcoin & Layer2 </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../BITCOIN_PROTOCOL/ class=md-nav__link> <span class=md-ellipsis> Bitcoin Protocol </span> </a> </li> <li class=md-nav__item> <a href=../BITCOIN_COMPLIANCE/ class=md-nav__link> <span class=md-ellipsis> Bitcoin Compliance </span> </a> </li> <li class=md-nav__item> <a href=../BIP_COMPLIANCE/ class=md-nav__link> <span class=md-ellipsis> BIP Compliance </span> </a> </li> <li class=md-nav__item> <a href=../HSM_FEATURE_GUIDE/ class=md-nav__link> <span class=md-ellipsis> HSM Integration </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_6> <label class=md-nav__link for=__nav_6 id=__nav_6_label tabindex=0> <span class=md-ellipsis> Web5 & Identity </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=1 aria-labelledby=__nav_6_label aria-expanded=false> <label class=md-nav__title for=__nav_6> <span class="md-nav__icon md-icon"></span> Web5 & Identity </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../WEB5_INTEGRATION/ class=md-nav__link> <span class=md-ellipsis> Web5 Integration </span> </a> </li> <li class=md-nav__item> <a href=../identity/ class=md-nav__link> <span class=md-ellipsis> Identity </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_7> <label class=md-nav__link for=__nav_7 id=__nav_7_label tabindex=0> <span class=md-ellipsis> Enterprise </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=1 aria-labelledby=__nav_7_label aria-expanded=false> <label class=md-nav__title for=__nav_7> <span class="md-nav__icon md-icon"></span> Enterprise </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../ENTERPRISE_GUIDE/ class=md-nav__link> <span class=md-ellipsis> Enterprise Guide </span> </a> </li> <li class=md-nav__item> <a href=../ENTERPRISE_FEATURES/ class=md-nav__link> <span class=md-ellipsis> Enterprise Features </span> </a> </li> <li class=md-nav__item> <a href=../CONFIGURATION_MANAGEMENT/ class=md-nav__link> <span class=md-ellipsis> Configuration </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_8> <label class=md-nav__link for=__nav_8 id=__nav_8_label tabindex=0> <span class=md-ellipsis> DAO & Governance </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=1 aria-labelledby=__nav_8_label aria-expanded=false> <label class=md-nav__title for=__nav_8> <span class="md-nav__icon md-icon"></span> DAO & Governance </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../DAO_OVERVIEW/ class=md-nav__link> <span class=md-ellipsis> DAO Overview </span> </a> </li> <li class=md-nav__item> <a href=../DAO_SYSTEM_GUIDE/ class=md-nav__link> <span class=md-ellipsis> DAO System </span> </a> </li> <li class=md-nav__item> <a href=../GOVERNANCE_FRAMEWORK/ class=md-nav__link> <span class=md-ellipsis> Governance </span> </a> </li> <li class=md-nav__item> <a href=../BUSINESS_PLAN/ class=md-nav__link> <span class=md-ellipsis> Business Plan </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_9> <label class=md-nav__link for=__nav_9 id=__nav_9_label tabindex=0> <span class=md-ellipsis> API Reference </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=1 aria-labelledby=__nav_9_label aria-expanded=false> <label class=md-nav__title for=__nav_9> <span class="md-nav__icon md-icon"></span> API Reference </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../API/ class=md-nav__link> <span class=md-ellipsis> API Overview </span> </a> </li> <li class=md-nav__item> <a href=../CLI_REFERENCE/ class=md-nav__link> <span class=md-ellipsis> CLI Reference </span> </a> </li> <li class=md-nav__item> <a href=../DEPENDENCIES/ class=md-nav__link> <span class=md-ellipsis> Dependencies </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_10> <label class=md-nav__link for=__nav_10 id=__nav_10_label tabindex=0> <span class=md-ellipsis> Maintenance </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=1 aria-labelledby=__nav_10_label aria-expanded=false> <label class=md-nav__title for=__nav_10> <span class="md-nav__icon md-icon"></span> Maintenance </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../ROADMAP/ class=md-nav__link> <span class=md-ellipsis> Roadmap </span> </a> </li> <li class=md-nav__item> <a href=../MIGRATION/ class=md-nav__link> <span class=md-ellipsis> Migration </span> </a> </li> <li class=md-nav__item> <a href=../TROUBLESHOOTING/ class=md-nav__link> <span class=md-ellipsis> Troubleshooting </span> </a> </li> <li class=md-nav__item> <a href=../SECURITY/ class=md-nav__link> <span class=md-ellipsis> Security </span> </a> </li> </ul> </nav> </li> </ul> </nav> </div> </div> </div> <div class="md-sidebar md-sidebar--secondary" data-md-component=sidebar data-md-type=toc> <div class=md-sidebar__scrollwrap> <div class=md-sidebar__inner> <nav class="md-nav md-nav--secondary" aria-label="Table of contents"> <label class=md-nav__title for=__toc> <span class="md-nav__icon md-icon"></span> Table of contents </label> <ul class=md-nav__list data-md-component=toc data-md-scrollfix> <li class=md-nav__item> <a href=#table-of-contents class=md-nav__link> <span class=md-ellipsis> Table of Contents </span> </a> </li> <li class=md-nav__item> <a href=#overview class=md-nav__link> <span class=md-ellipsis> Overview </span> </a> </li> <li class=md-nav__item> <a href=#core-concepts class=md-nav__link> <span class=md-ellipsis> Core Concepts </span> </a> <nav class=md-nav aria-label="Core Concepts"> <ul class=md-nav__list> <li class=md-nav__item> <a href=#domain-layer class=md-nav__link> <span class=md-ellipsis> Domain Layer </span> </a> </li> <li class=md-nav__item> <a href=#application-layer class=md-nav__link> <span class=md-ellipsis> Application Layer </span> </a> </li> <li class=md-nav__item> <a href=#infrastructure-layer class=md-nav__link> <span class=md-ellipsis> Infrastructure Layer </span> </a> </li> </ul> </nav> </li> <li class=md-nav__item> <a href=#directory-structure class=md-nav__link> <span class=md-ellipsis> Directory Structure </span> </a> </li> <li class=md-nav__item> <a href=#implementing-a-new-feature class=md-nav__link> <span class=md-ellipsis> Implementing a New Feature </span> </a> <nav class=md-nav aria-label="Implementing a New Feature"> <ul class=md-nav__list> <li class=md-nav__item> <a href=#1-define-domain-models class=md-nav__link> <span class=md-ellipsis> 1. Define Domain Models </span> </a> </li> <li class=md-nav__item> <a href=#2-define-ports-traits class=md-nav__link> <span class=md-ellipsis> 2. Define Ports (Traits) </span> </a> </li> <li class=md-nav__item> <a href=#3-implement-application-service class=md-nav__link> <span class=md-ellipsis> 3. Implement Application Service </span> </a> </li> <li class=md-nav__item> <a href=#4-implement-adapters class=md-nav__link> <span class=md-ellipsis> 4. Implement Adapters </span> </a> </li> </ul> </nav> </li> <li class=md-nav__item> <a href=#testing class=md-nav__link> <span class=md-ellipsis> Testing </span> </a> <nav class=md-nav aria-label=Testing> <ul class=md-nav__list> <li class=md-nav__item> <a href=#unit-tests class=md-nav__link> <span class=md-ellipsis> Unit Tests </span> </a> </li> <li class=md-nav__item> <a href=#integration-tests class=md-nav__link> <span class=md-ellipsis> Integration Tests </span> </a> </li> </ul> </nav> </li> <li class=md-nav__item> <a href=#best-practices class=md-nav__link> <span class=md-ellipsis> Best Practices </span> </a> <nav class=md-nav aria-label="Best Practices"> <ul class=md-nav__list> <li class=md-nav__item> <a href=#1-dependency-rule class=md-nav__link> <span class=md-ellipsis> 1. Dependency Rule </span> </a> </li> <li class=md-nav__item> <a href=#2-use-traits-for-dependencies class=md-nav__link> <span class=md-ellipsis> 2. Use Traits for Dependencies </span> </a> </li> <li class=md-nav__item> <a href=#3-error-handling class=md-nav__link> <span class=md-ellipsis> 3. Error Handling </span> </a> </li> <li class=md-nav__item> <a href=#4-testing class=md-nav__link> <span class=md-ellipsis> 4. Testing </span> </a> </li> </ul> </nav> </li> <li class=md-nav__item> <a href=#examples class=md-nav__link> <span class=md-ellipsis> Examples </span> </a> <nav class=md-nav aria-label=Examples> <ul class=md-nav__list> <li class=md-nav__item> <a href=#domain-event class=md-nav__link> <span class=md-ellipsis> Domain Event </span> </a> </li> <li class=md-nav__item> <a href=#command-handler class=md-nav__link> <span class=md-ellipsis> Command Handler </span> </a> </li> </ul> </nav> </li> <li class=md-nav__item> <a href=#conclusion class=md-nav__link> <span class=md-ellipsis> Conclusion </span> </a> </li> <li class=md-nav__item> <a href=#see-also class=md-nav__link> <span class=md-ellipsis> See Also </span> </a> </li> </ul> </nav> </div> </div> </div> <div class=md-content data-md-component=content> <article class="md-content__inner md-typeset"> <a href=https://github.com/anya-org/anya-core/edit/main/docs/hexagonal.md title="Edit this page" class="md-content__button md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M10 20H6V4h7v5h5v3.1l2-2V8l-6-6H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h4zm10.2-7c.1 0 .3.1.4.2l1.3 1.3c.2.2.2.6 0 .8l-1 1-2.1-2.1 1-1c.1-.1.2-.2.4-.2m0 3.9L14.1 23H12v-2.1l6.1-6.1z"/></svg> </a> <a href=https://github.com/anya-org/anya-core/raw/main/docs/hexagonal.md title="View source of this page" class="md-content__button md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M17 18c.56 0 1 .44 1 1s-.44 1-1 1-1-.44-1-1 .44-1 1-1m0-3c-2.73 0-5.06 1.66-6 4 .94 2.34 3.27 4 6 4s5.06-1.66 6-4c-.94-2.34-3.27-4-6-4m0 6.5a2.5 2.5 0 0 1-2.5-2.5 2.5 2.5 0 0 1 2.5-2.5 2.5 2.5 0 0 1 2.5 2.5 2.5 2.5 0 0 1-2.5 2.5M9.27 20H6V4h7v5h5v4.07c.7.08 1.36.25 2 .49V8l-6-6H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h4.5a8.2 8.2 0 0 1-1.23-2"/></svg> </a> <p>[AIR-3][AIS-3][BPC-3][RES-3]</p> <h1 id=hexagonal-architecture-in-anya-core>Hexagonal Architecture in Anya Core<a class=headerlink href=#hexagonal-architecture-in-anya-core title="Permanent link">¶</a></h1> <p>This document describes the Hexagonal (Ports and Adapters) architecture used in Anya Core.</p> <h2 id=table-of-contents>Table of Contents<a class=headerlink href=#table-of-contents title="Permanent link">¶</a></h2> <ul> <li><a href=#overview>Overview</a></li> <li><a href=#core-concepts>Core Concepts</a></li> <li><a href=#directory-structure>Directory Structure</a></li> <li><a href=#implementing-a-new-feature>Implementing a New Feature</a></li> <li><a href=#testing>Testing</a></li> <li><a href=#best-practices>Best Practices</a></li> <li><a href=#examples>Examples</a></li> </ul> <h2 id=overview>Overview<a class=headerlink href=#overview title="Permanent link">¶</a></h2> <p>Hexagonal Architecture, also known as Ports and Adapters, is an architectural pattern that isolates the core business logic from external concerns. This separation makes the application more maintainable, testable, and adaptable to change.</p> <h2 id=core-concepts>Core Concepts<a class=headerlink href=#core-concepts title="Permanent link">¶</a></h2> <h3 id=domain-layer>Domain Layer<a class=headerlink href=#domain-layer title="Permanent link">¶</a></h3> <ul> <li>Contains the core business logic</li> <li>Pure Rust code with no external dependencies</li> <li>Defines domain models and business rules</li> </ul> <h3 id=application-layer>Application Layer<a class=headerlink href=#application-layer title="Permanent link">¶</a></h3> <ul> <li>Orchestrates the flow of data between the domain and infrastructure layers</li> <li>Implements use cases</li> <li>Defines ports (traits) for external interactions</li> </ul> <h3 id=infrastructure-layer>Infrastructure Layer<a class=headerlink href=#infrastructure-layer title="Permanent link">¶</a></h3> <ul> <li>Implements the ports defined by the application layer</li> <li>Handles external concerns like:</li> <li>Database access</li> <li>Network communication</li> <li>File I/O</li> <li>External services</li> </ul> <h2 id=directory-structure>Directory Structure<a class=headerlink href=#directory-structure title="Permanent link">¶</a></h2> <div class="language-text highlight"><pre><span></span><code><span id=__span-0-1><a id=__codelineno-0-1 name=__codelineno-0-1 href=#__codelineno-0-1></a>src/
</span><span id=__span-0-2><a id=__codelineno-0-2 name=__codelineno-0-2 href=#__codelineno-0-2></a>├── domain/ # Domain layer
</span><span id=__span-0-3><a id=__codelineno-0-3 name=__codelineno-0-3 href=#__codelineno-0-3></a>│ ├── models/ # Domain models
</span><span id=__span-0-4><a id=__codelineno-0-4 name=__codelineno-0-4 href=#__codelineno-0-4></a>│ └── services/ # Domain services
</span><span id=__span-0-5><a id=__codelineno-0-5 name=__codelineno-0-5 href=#__codelineno-0-5></a>├── application/ # Application layer
</span><span id=__span-0-6><a id=__codelineno-0-6 name=__codelineno-0-6 href=#__codelineno-0-6></a>│ ├── ports/ # Ports (traits)
</span><span id=__span-0-7><a id=__codelineno-0-7 name=__codelineno-0-7 href=#__codelineno-0-7></a>│ └── services/ # Application services
</span><span id=__span-0-8><a id=__codelineno-0-8 name=__codelineno-0-8 href=#__codelineno-0-8></a>└── infrastructure/ # Infrastructure layer
</span><span id=__span-0-9><a id=__codelineno-0-9 name=__codelineno-0-9 href=#__codelineno-0-9></a> ├── adapters/ # Adapters implementing ports
</span><span id=__span-0-10><a id=__codelineno-0-10 name=__codelineno-0-10 href=#__codelineno-0-10></a> └── config/ # Configuration
</span></code></pre></div> <h2 id=implementing-a-new-feature>Implementing a New Feature<a class=headerlink href=#implementing-a-new-feature title="Permanent link">¶</a></h2> <h3 id=1-define-domain-models>1. Define Domain Models<a class=headerlink href=#1-define-domain-models title="Permanent link">¶</a></h3> <div class="language-rust highlight"><pre><span></span><code><span id=__span-1-1><a id=__codelineno-1-1 name=__codelineno-1-1 href=#__codelineno-1-1></a><span class=c1>// domain/models/user.rs</span>
</span><span id=__span-1-2><a id=__codelineno-1-2 name=__codelineno-1-2 href=#__codelineno-1-2></a><span class=k>pub</span><span class=w> </span><span class=k>struct</span><span class=w> </span><span class=nc>User</span><span class=w> </span><span class=p>{</span>
</span><span id=__span-1-3><a id=__codelineno-1-3 name=__codelineno-1-3 href=#__codelineno-1-3></a><span class=w> </span><span class=k>pub</span><span class=w> </span><span class=n>id</span><span class=p>:</span><span class=w> </span><span class=nc>UserId</span><span class=p>,</span>
</span><span id=__span-1-4><a id=__codelineno-1-4 name=__codelineno-1-4 href=#__codelineno-1-4></a><span class=w> </span><span class=k>pub</span><span class=w> </span><span class=n>username</span><span class=p>:</span><span class=w> </span><span class=nb>String</span><span class=p>,</span>
</span><span id=__span-1-5><a id=__codelineno-1-5 name=__codelineno-1-5 href=#__codelineno-1-5></a><span class=w> </span><span class=k>pub</span><span class=w> </span><span class=n>email</span><span class=p>:</span><span class=w> </span><span class=nb>String</span><span class=p>,</span>
</span><span id=__span-1-6><a id=__codelineno-1-6 name=__codelineno-1-6 href=#__codelineno-1-6></a><span class=p>}</span>
</span></code></pre></div> <h3 id=2-define-ports-traits>2. Define Ports (Traits)<a class=headerlink href=#2-define-ports-traits title="Permanent link">¶</a></h3> <div class="language-rust highlight"><pre><span></span><code><span id=__span-2-1><a id=__codelineno-2-1 name=__codelineno-2-1 href=#__codelineno-2-1></a><span class=c1>// application/ports/user_repository.rs</span>
</span><span id=__span-2-2><a id=__codelineno-2-2 name=__codelineno-2-2 href=#__codelineno-2-2></a><span class=cp>#[async_trait]</span>
</span><span id=__span-2-3><a id=__codelineno-2-3 name=__codelineno-2-3 href=#__codelineno-2-3></a><span class=k>pub</span><span class=w> </span><span class=k>trait</span><span class=w> </span><span class=n>UserRepository</span><span class=p>:</span><span class=w> </span><span class=nb>Send</span><span class=w> </span><span class=o>+</span><span class=w> </span><span class=nb>Sync</span><span class=w> </span><span class=p>{</span>
</span><span id=__span-2-4><a id=__codelineno-2-4 name=__codelineno-2-4 href=#__codelineno-2-4></a><span class=w> </span><span class=k>async</span><span class=w> </span><span class=k>fn</span><span class=w> </span><span class=nf>find_by_id</span><span class=p>(</span><span class=o>&</span><span class=bp>self</span><span class=p>,</span><span class=w> </span><span class=n>id</span><span class=p>:</span><span class=w> </span><span class=kp>&</span><span class=nc>UserId</span><span class=p>)</span><span class=w> </span><span class=p>-></span><span class=w> </span><span class=nb>Result</span><span class=o><</span><span class=nb>Option</span><span class=o><</span><span class=n>User</span><span class=o>></span><span class=p>,</span><span class=w> </span><span class=n>Error</span><span class=o>></span><span class=p>;</span>
</span><span id=__span-2-5><a id=__codelineno-2-5 name=__codelineno-2-5 href=#__codelineno-2-5></a><span class=w> </span><span class=k>async</span><span class=w> </span><span class=k>fn</span><span class=w> </span><span class=nf>save</span><span class=p>(</span><span class=o>&</span><span class=bp>self</span><span class=p>,</span><span class=w> </span><span class=n>user</span><span class=p>:</span><span class=w> </span><span class=kp>&</span><span class=nc>User</span><span class=p>)</span><span class=w> </span><span class=p>-></span><span class=w> </span><span class=nb>Result</span><span class=o><</span><span class=p>(),</span><span class=w> </span><span class=n>Error</span><span class=o>></span><span class=p>;</span>
</span><span id=__span-2-6><a id=__codelineno-2-6 name=__codelineno-2-6 href=#__codelineno-2-6></a><span class=p>}</span>
</span></code></pre></div> <h3 id=3-implement-application-service>3. Implement Application Service<a class=headerlink href=#3-implement-application-service title="Permanent link">¶</a></h3> <div class="language-rust highlight"><pre><span></span><code><span id=__span-3-1><a id=__codelineno-3-1 name=__codelineno-3-1 href=#__codelineno-3-1></a><span class=c1>// application/services/user_service.rs</span>
</span><span id=__span-3-2><a id=__codelineno-3-2 name=__codelineno-3-2 href=#__codelineno-3-2></a><span class=k>pub</span><span class=w> </span><span class=k>struct</span><span class=w> </span><span class=nc>UserService</span><span class=o><</span><span class=n>T</span><span class=p>:</span><span class=w> </span><span class=nc>UserRepository</span><span class=o>></span><span class=w> </span><span class=p>{</span>
</span><span id=__span-3-3><a id=__codelineno-3-3 name=__codelineno-3-3 href=#__codelineno-3-3></a><span class=w> </span><span class=n>user_repository</span><span class=p>:</span><span class=w> </span><span class=nc>Arc</span><span class=o><</span><span class=n>T</span><span class=o>></span><span class=p>,</span>
</span><span id=__span-3-4><a id=__codelineno-3-4 name=__codelineno-3-4 href=#__codelineno-3-4></a><span class=p>}</span>
</span><span id=__span-3-5><a id=__codelineno-3-5 name=__codelineno-3-5 href=#__codelineno-3-5></a>
</span><span id=__span-3-6><a id=__codelineno-3-6 name=__codelineno-3-6 href=#__codelineno-3-6></a><span class=k>impl</span><span class=o><</span><span class=n>T</span><span class=p>:</span><span class=w> </span><span class=nc>UserRepository</span><span class=o>></span><span class=w> </span><span class=n>UserService</span><span class=o><</span><span class=n>T</span><span class=o>></span><span class=w> </span><span class=p>{</span>
</span><span id=__span-3-7><a id=__codelineno-3-7 name=__codelineno-3-7 href=#__codelineno-3-7></a><span class=w> </span><span class=k>pub</span><span class=w> </span><span class=k>async</span><span class=w> </span><span class=k>fn</span><span class=w> </span><span class=nf>get_user</span><span class=p>(</span><span class=o>&</span><span class=bp>self</span><span class=p>,</span><span class=w> </span><span class=n>id</span><span class=p>:</span><span class=w> </span><span class=kp>&</span><span class=nc>UserId</span><span class=p>)</span><span class=w> </span><span class=p>-></span><span class=w> </span><span class=nb>Result</span><span class=o><</span><span class=nb>Option</span><span class=o><</span><span class=n>User</span><span class=o>></span><span class=p>,</span><span class=w> </span><span class=n>Error</span><span class=o>></span><span class=w> </span><span class=p>{</span>
</span><span id=__span-3-8><a id=__codelineno-3-8 name=__codelineno-3-8 href=#__codelineno-3-8></a><span class=w> </span><span class=bp>self</span><span class=p>.</span><span class=n>user_repository</span><span class=p>.</span><span class=n>find_by_id</span><span class=p>(</span><span class=n>id</span><span class=p>).</span><span class=k>await</span>
</span><span id=__span-3-9><a id=__codelineno-3-9 name=__codelineno-3-9 href=#__codelineno-3-9></a><span class=w> </span><span class=p>}</span>
</span><span id=__span-3-10><a id=__codelineno-3-10 name=__codelineno-3-10 href=#__codelineno-3-10></a><span class=p>}</span>
</span></code></pre></div> <h3 id=4-implement-adapters>4. Implement Adapters<a class=headerlink href=#4-implement-adapters title="Permanent link">¶</a></h3> <div class="language-rust highlight"><pre><span></span><code><span id=__span-4-1><a id=__codelineno-4-1 name=__codelineno-4-1 href=#__codelineno-4-1></a><span class=c1>// infrastructure/adapters/postgres_user_repository.rs</span>
</span><span id=__span-4-2><a id=__codelineno-4-2 name=__codelineno-4-2 href=#__codelineno-4-2></a><span class=k>pub</span><span class=w> </span><span class=k>struct</span><span class=w> </span><span class=nc>PostgresUserRepository</span><span class=w> </span><span class=p>{</span>
</span><span id=__span-4-3><a id=__codelineno-4-3 name=__codelineno-4-3 href=#__codelineno-4-3></a><span class=w> </span><span class=n>pool</span><span class=p>:</span><span class=w> </span><span class=nc>PgPool</span><span class=p>,</span>
</span><span id=__span-4-4><a id=__codelineno-4-4 name=__codelineno-4-4 href=#__codelineno-4-4></a><span class=p>}</span>
</span><span id=__span-4-5><a id=__codelineno-4-5 name=__codelineno-4-5 href=#__codelineno-4-5></a>
</span><span id=__span-4-6><a id=__codelineno-4-6 name=__codelineno-4-6 href=#__codelineno-4-6></a><span class=cp>#[async_trait]</span>
</span><span id=__span-4-7><a id=__codelineno-4-7 name=__codelineno-4-7 href=#__codelineno-4-7></a><span class=k>impl</span><span class=w> </span><span class=n>UserRepository</span><span class=w> </span><span class=k>for</span><span class=w> </span><span class=n>PostgresUserRepository</span><span class=w> </span><span class=p>{</span>
</span><span id=__span-4-8><a id=__codelineno-4-8 name=__codelineno-4-8 href=#__codelineno-4-8></a><span class=w> </span><span class=k>async</span><span class=w> </span><span class=k>fn</span><span class=w> </span><span class=nf>find_by_id</span><span class=p>(</span><span class=o>&</span><span class=bp>self</span><span class=p>,</span><span class=w> </span><span class=n>id</span><span class=p>:</span><span class=w> </span><span class=kp>&</span><span class=nc>UserId</span><span class=p>)</span><span class=w> </span><span class=p>-></span><span class=w> </span><span class=nb>Result</span><span class=o><</span><span class=nb>Option</span><span class=o><</span><span class=n>User</span><span class=o>></span><span class=p>,</span><span class=w> </span><span class=n>Error</span><span class=o>></span><span class=w> </span><span class=p>{</span>
</span><span id=__span-4-9><a id=__codelineno-4-9 name=__codelineno-4-9 href=#__codelineno-4-9></a><span class=w> </span><span class=c1>// Implementation using SQLx</span>
</span><span id=__span-4-10><a id=__codelineno-4-10 name=__codelineno-4-10 href=#__codelineno-4-10></a><span class=w> </span><span class=p>}</span>
</span><span id=__span-4-11><a id=__codelineno-4-11 name=__codelineno-4-11 href=#__codelineno-4-11></a><span class=p>}</span>
</span></code></pre></div> <h2 id=testing>Testing<a class=headerlink href=#testing title="Permanent link">¶</a></h2> <h3 id=unit-tests>Unit Tests<a class=headerlink href=#unit-tests title="Permanent link">¶</a></h3> <p>Test domain and application layers in isolation:</p> <div class="language-rust highlight"><pre><span></span><code><span id=__span-5-1><a id=__codelineno-5-1 name=__codelineno-5-1 href=#__codelineno-5-1></a><span class=cp>#[cfg(test)]</span>
</span><span id=__span-5-2><a id=__codelineno-5-2 name=__codelineno-5-2 href=#__codelineno-5-2></a><span class=k>mod</span><span class=w> </span><span class=nn>tests</span><span class=w> </span><span class=p>{</span>
</span><span id=__span-5-3><a id=__codelineno-5-3 name=__codelineno-5-3 href=#__codelineno-5-3></a><span class=w> </span><span class=k>use</span><span class=w> </span><span class=k>super</span><span class=p>::</span><span class=o>*</span><span class=p>;</span>
</span><span id=__span-5-4><a id=__codelineno-5-4 name=__codelineno-5-4 href=#__codelineno-5-4></a><span class=w> </span><span class=k>use</span><span class=w> </span><span class=n>mockall</span><span class=p>::</span><span class=n>predicate</span><span class=p>::</span><span class=o>*</span><span class=p>;</span>
</span><span id=__span-5-5><a id=__codelineno-5-5 name=__codelineno-5-5 href=#__codelineno-5-5></a>
</span><span id=__span-5-6><a id=__codelineno-5-6 name=__codelineno-5-6 href=#__codelineno-5-6></a><span class=w> </span><span class=cp>#[tokio::test]</span>
</span><span id=__span-5-7><a id=__codelineno-5-7 name=__codelineno-5-7 href=#__codelineno-5-7></a><span class=w> </span><span class=k>async</span><span class=w> </span><span class=k>fn</span><span class=w> </span><span class=nf>test_get_user</span><span class=p>()</span><span class=w> </span><span class=p>{</span>
</span><span id=__span-5-8><a id=__codelineno-5-8 name=__codelineno-5-8 href=#__codelineno-5-8></a><span class=w> </span><span class=c1>// Setup mock</span>
</span><span id=__span-5-9><a id=__codelineno-5-9 name=__codelineno-5-9 href=#__codelineno-5-9></a><span class=w> </span><span class=kd>let</span><span class=w> </span><span class=k>mut</span><span class=w> </span><span class=n>mock_repo</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>MockUserRepository</span><span class=p>::</span><span class=n>new</span><span class=p>();</span>
</span><span id=__span-5-10><a id=__codelineno-5-10 name=__codelineno-5-10 href=#__codelineno-5-10></a><span class=w> </span><span class=n>mock_repo</span>
</span><span id=__span-5-11><a id=__codelineno-5-11 name=__codelineno-5-11 href=#__codelineno-5-11></a><span class=w> </span><span class=p>.</span><span class=n>expect_find_by_id</span><span class=p>()</span>
</span><span id=__span-5-12><a id=__codelineno-5-12 name=__codelineno-5-12 href=#__codelineno-5-12></a><span class=w> </span><span class=p>.</span><span class=n>returning</span><span class=p>(</span><span class=o>|</span><span class=n>_</span><span class=o>|</span><span class=w> </span><span class=nb>Ok</span><span class=p>(</span><span class=nb>Some</span><span class=p>(</span><span class=n>User</span><span class=p>::</span><span class=n>new</span><span class=p>(</span><span class=s>"test"</span><span class=p>))));</span>
</span><span id=__span-5-13><a id=__codelineno-5-13 name=__codelineno-5-13 href=#__codelineno-5-13></a>
</span><span id=__span-5-14><a id=__codelineno-5-14 name=__codelineno-5-14 href=#__codelineno-5-14></a><span class=w> </span><span class=c1>// Test</span>
</span><span id=__span-5-15><a id=__codelineno-5-15 name=__codelineno-5-15 href=#__codelineno-5-15></a><span class=w> </span><span class=kd>let</span><span class=w> </span><span class=n>service</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>UserService</span><span class=p>::</span><span class=n>new</span><span class=p>(</span><span class=n>Arc</span><span class=p>::</span><span class=n>new</span><span class=p>(</span><span class=n>mock_repo</span><span class=p>));</span>
</span><span id=__span-5-16><a id=__codelineno-5-16 name=__codelineno-5-16 href=#__codelineno-5-16></a><span class=w> </span><span class=kd>let</span><span class=w> </span><span class=n>result</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>service</span><span class=p>.</span><span class=n>get_user</span><span class=p>(</span><span class=o>&</span><span class=n>UserId</span><span class=p>::</span><span class=n>new</span><span class=p>()).</span><span class=k>await</span><span class=p>;</span>
</span><span id=__span-5-17><a id=__codelineno-5-17 name=__codelineno-5-17 href=#__codelineno-5-17></a><span class=w> </span><span class=fm>assert!</span><span class=p>(</span><span class=n>result</span><span class=p>.</span><span class=n>is_ok</span><span class=p>());</span>
</span><span id=__span-5-18><a id=__codelineno-5-18 name=__codelineno-5-18 href=#__codelineno-5-18></a><span class=w> </span><span class=p>}</span>
</span><span id=__span-5-19><a id=__codelineno-5-19 name=__codelineno-5-19 href=#__codelineno-5-19></a><span class=p>}</span>
</span></code></pre></div> <h3 id=integration-tests>Integration Tests<a class=headerlink href=#integration-tests title="Permanent link">¶</a></h3> <p>Test the entire stack:</p> <div class="language-rust highlight"><pre><span></span><code><span id=__span-6-1><a id=__codelineno-6-1 name=__codelineno-6-1 href=#__codelineno-6-1></a><span class=cp>#[tokio::test]</span>
</span><span id=__span-6-2><a id=__codelineno-6-2 name=__codelineno-6-2 href=#__codelineno-6-2></a><span class=k>async</span><span class=w> </span><span class=k>fn</span><span class=w> </span><span class=nf>test_user_flow</span><span class=p>()</span><span class=w> </span><span class=p>{</span>
</span><span id=__span-6-3><a id=__codelineno-6-3 name=__codelineno-6-3 href=#__codelineno-6-3></a><span class=w> </span><span class=c1>// Setup test database</span>
</span><span id=__span-6-4><a id=__codelineno-6-4 name=__codelineno-6-4 href=#__codelineno-6-4></a><span class=w> </span><span class=kd>let</span><span class=w> </span><span class=n>pool</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>setup_test_db</span><span class=p>().</span><span class=k>await</span><span class=p>;</span>
</span><span id=__span-6-5><a id=__codelineno-6-5 name=__codelineno-6-5 href=#__codelineno-6-5></a>
</span><span id=__span-6-6><a id=__codelineno-6-6 name=__codelineno-6-6 href=#__codelineno-6-6></a><span class=w> </span><span class=c1>// Create repository with test DB</span>
</span><span id=__span-6-7><a id=__codelineno-6-7 name=__codelineno-6-7 href=#__codelineno-6-7></a><span class=w> </span><span class=kd>let</span><span class=w> </span><span class=n>repo</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>PostgresUserRepository</span><span class=p>::</span><span class=n>new</span><span class=p>(</span><span class=n>pool</span><span class=p>);</span>
</span><span id=__span-6-8><a id=__codelineno-6-8 name=__codelineno-6-8 href=#__codelineno-6-8></a>
</span><span id=__span-6-9><a id=__codelineno-6-9 name=__codelineno-6-9 href=#__codelineno-6-9></a><span class=w> </span><span class=c1>// Test operations</span>
</span><span id=__span-6-10><a id=__codelineno-6-10 name=__codelineno-6-10 href=#__codelineno-6-10></a><span class=w> </span><span class=kd>let</span><span class=w> </span><span class=n>user</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>User</span><span class=p>::</span><span class=n>new</span><span class=p>(</span><span class=s>"test"</span><span class=p>);</span>
</span><span id=__span-6-11><a id=__codelineno-6-11 name=__codelineno-6-11 href=#__codelineno-6-11></a><span class=w> </span><span class=n>repo</span><span class=p>.</span><span class=n>save</span><span class=p>(</span><span class=o>&</span><span class=n>user</span><span class=p>).</span><span class=k>await</span><span class=p>.</span><span class=n>unwrap</span><span class=p>();</span>
</span><span id=__span-6-12><a id=__codelineno-6-12 name=__codelineno-6-12 href=#__codelineno-6-12></a>
</span><span id=__span-6-13><a id=__codelineno-6-13 name=__codelineno-6-13 href=#__codelineno-6-13></a><span class=w> </span><span class=kd>let</span><span class=w> </span><span class=n>found</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>repo</span><span class=p>.</span><span class=n>find_by_id</span><span class=p>(</span><span class=o>&</span><span class=n>user</span><span class=p>.</span><span class=n>id</span><span class=p>).</span><span class=k>await</span><span class=p>.</span><span class=n>unwrap</span><span class=p>();</span>
</span><span id=__span-6-14><a id=__codelineno-6-14 name=__codelineno-6-14 href=#__codelineno-6-14></a><span class=w> </span><span class=fm>assert!</span><span class=p>(</span><span class=n>found</span><span class=p>.</span><span class=n>is_some</span><span class=p>());</span>
</span><span id=__span-6-15><a id=__codelineno-6-15 name=__codelineno-6-15 href=#__codelineno-6-15></a><span class=p>}</span>
</span></code></pre></div> <h2 id=best-practices>Best Practices<a class=headerlink href=#best-practices title="Permanent link">¶</a></h2> <h3 id=1-dependency-rule>1. Dependency Rule<a class=headerlink href=#1-dependency-rule title="Permanent link">¶</a></h3> <p>Dependencies should always point inward:</p> <ul> <li>Domain has no dependencies</li> <li>Application depends on domain</li> <li>Infrastructure depends on application and domain</li> </ul> <h3 id=2-use-traits-for-dependencies>2. Use Traits for Dependencies<a class=headerlink href=#2-use-traits-for-dependencies title="Permanent link">¶</a></h3> <div class="language-rust highlight"><pre><span></span><code><span id=__span-7-1><a id=__codelineno-7-1 name=__codelineno-7-1 href=#__codelineno-7-1></a><span class=c1>// Good: Depend on trait</span>
</span><span id=__span-7-2><a id=__codelineno-7-2 name=__codelineno-7-2 href=#__codelineno-7-2></a><span class=k>struct</span><span class=w> </span><span class=nc>UserService</span><span class=o><</span><span class=n>T</span><span class=p>:</span><span class=w> </span><span class=nc>UserRepository</span><span class=o>></span><span class=w> </span><span class=p>{</span>
</span><span id=__span-7-3><a id=__codelineno-7-3 name=__codelineno-7-3 href=#__codelineno-7-3></a><span class=w> </span><span class=n>repo</span><span class=p>:</span><span class=w> </span><span class=nc>T</span><span class=p>,</span>
</span><span id=__span-7-4><a id=__codelineno-7-4 name=__codelineno-7-4 href=#__codelineno-7-4></a><span class=p>}</span>
</span><span id=__span-7-5><a id=__codelineno-7-5 name=__codelineno-7-5 href=#__codelineno-7-5></a>
</span><span id=__span-7-6><a id=__codelineno-7-6 name=__codelineno-7-6 href=#__codelineno-7-6></a><span class=c1>// Bad: Depend on concrete implementation</span>
</span><span id=__span-7-7><a id=__codelineno-7-7 name=__codelineno-7-7 href=#__codelineno-7-7></a><span class=k>struct</span><span class=w> </span><span class=nc>UserService</span><span class=w> </span><span class=p>{</span>
</span><span id=__span-7-8><a id=__codelineno-7-8 name=__codelineno-7-8 href=#__codelineno-7-8></a><span class=w> </span><span class=n>repo</span><span class=p>:</span><span class=w> </span><span class=nc>PostgresUserRepository</span><span class=p>,</span>
</span><span id=__span-7-9><a id=__codelineno-7-9 name=__codelineno-7-9 href=#__codelineno-7-9></a><span class=p>}</span>
</span></code></pre></div> <h3 id=3-error-handling>3. Error Handling<a class=headerlink href=#3-error-handling title="Permanent link">¶</a></h3> <ul> <li>Define domain-specific errors</li> <li>Use <code>thiserror</code> for error types</li> <li>Convert between error types at boundaries</li> </ul> <h3 id=4-testing>4. Testing<a class=headerlink href=#4-testing title="Permanent link">¶</a></h3> <ul> <li>Test domain logic in isolation</li> <li>Use mocks for external dependencies</li> <li>Write integration tests for critical paths</li> </ul> <h2 id=examples>Examples<a class=headerlink href=#examples title="Permanent link">¶</a></h2> <h3 id=domain-event>Domain Event<a class=headerlink href=#domain-event title="Permanent link">¶</a></h3> <div class="language-rust highlight"><pre><span></span><code><span id=__span-8-1><a id=__codelineno-8-1 name=__codelineno-8-1 href=#__codelineno-8-1></a><span class=c1>// domain/events/user_created.rs</span>
</span><span id=__span-8-2><a id=__codelineno-8-2 name=__codelineno-8-2 href=#__codelineno-8-2></a><span class=k>pub</span><span class=w> </span><span class=k>struct</span><span class=w> </span><span class=nc>UserCreated</span><span class=w> </span><span class=p>{</span>
</span><span id=__span-8-3><a id=__codelineno-8-3 name=__codelineno-8-3 href=#__codelineno-8-3></a><span class=w> </span><span class=k>pub</span><span class=w> </span><span class=n>user_id</span><span class=p>:</span><span class=w> </span><span class=nc>UserId</span><span class=p>,</span>
</span><span id=__span-8-4><a id=__codelineno-8-4 name=__codelineno-8-4 href=#__codelineno-8-4></a><span class=w> </span><span class=k>pub</span><span class=w> </span><span class=n>timestamp</span><span class=p>:</span><span class=w> </span><span class=nc>DateTime</span><span class=o><</span><span class=n>Utc</span><span class=o>></span><span class=p>,</span>
</span><span id=__span-8-5><a id=__codelineno-8-5 name=__codelineno-8-5 href=#__codelineno-8-5></a><span class=p>}</span>
</span><span id=__span-8-6><a id=__codelineno-8-6 name=__codelineno-8-6 href=#__codelineno-8-6></a>
</span><span id=__span-8-7><a id=__codelineno-8-7 name=__codelineno-8-7 href=#__codelineno-8-7></a><span class=k>impl</span><span class=w> </span><span class=n>DomainEvent</span><span class=w> </span><span class=k>for</span><span class=w> </span><span class=n>UserCreated</span><span class=w> </span><span class=p>{</span>
</span><span id=__span-8-8><a id=__codelineno-8-8 name=__codelineno-8-8 href=#__codelineno-8-8></a><span class=w> </span><span class=k>fn</span><span class=w> </span><span class=nf>event_type</span><span class=p>(</span><span class=o>&</span><span class=bp>self</span><span class=p>)</span><span class=w> </span><span class=p>-></span><span class=w> </span><span class=kp>&</span><span class=o>'</span><span class=nb>static</span><span class=w> </span><span class=kt>str</span><span class=w> </span><span class=p>{</span>
</span><span id=__span-8-9><a id=__codelineno-8-9 name=__codelineno-8-9 href=#__codelineno-8-9></a><span class=w> </span><span class=s>"user_created"</span>
</span><span id=__span-8-10><a id=__codelineno-8-10 name=__codelineno-8-10 href=#__codelineno-8-10></a><span class=w> </span><span class=p>}</span>
</span><span id=__span-8-11><a id=__codelineno-8-11 name=__codelineno-8-11 href=#__codelineno-8-11></a>
</span><span id=__span-8-12><a id=__codelineno-8-12 name=__codelineno-8-12 href=#__codelineno-8-12></a><span class=w> </span><span class=k>fn</span><span class=w> </span><span class=nf>timestamp</span><span class=p>(</span><span class=o>&</span><span class=bp>self</span><span class=p>)</span><span class=w> </span><span class=p>-></span><span class=w> </span><span class=nc>DateTime</span><span class=o><</span><span class=n>Utc</span><span class=o>></span><span class=w> </span><span class=p>{</span>
</span><span id=__span-8-13><a id=__codelineno-8-13 name=__codelineno-8-13 href=#__codelineno-8-13></a><span class=w> </span><span class=bp>self</span><span class=p>.</span><span class=n>timestamp</span>
</span><span id=__span-8-14><a id=__codelineno-8-14 name=__codelineno-8-14 href=#__codelineno-8-14></a><span class=w> </span><span class=p>}</span>
</span><span id=__span-8-15><a id=__codelineno-8-15 name=__codelineno-8-15 href=#__codelineno-8-15></a><span class=p>}</span>
</span></code></pre></div> <h3 id=command-handler>Command Handler<a class=headerlink href=#command-handler title="Permanent link">¶</a></h3> <div class="language-rust highlight"><pre><span></span><code><span id=__span-9-1><a id=__codelineno-9-1 name=__codelineno-9-1 href=#__codelineno-9-1></a><span class=c1>// application/commands/create_user.rs</span>
</span><span id=__span-9-2><a id=__codelineno-9-2 name=__codelineno-9-2 href=#__codelineno-9-2></a><span class=k>pub</span><span class=w> </span><span class=k>struct</span><span class=w> </span><span class=nc>CreateUserCommand</span><span class=w> </span><span class=p>{</span>
</span><span id=__span-9-3><a id=__codelineno-9-3 name=__codelineno-9-3 href=#__codelineno-9-3></a><span class=w> </span><span class=k>pub</span><span class=w> </span><span class=n>username</span><span class=p>:</span><span class=w> </span><span class=nb>String</span><span class=p>,</span>
</span><span id=__span-9-4><a id=__codelineno-9-4 name=__codelineno-9-4 href=#__codelineno-9-4></a><span class=w> </span><span class=k>pub</span><span class=w> </span><span class=n>email</span><span class=p>:</span><span class=w> </span><span class=nb>String</span><span class=p>,</span>
</span><span id=__span-9-5><a id=__codelineno-9-5 name=__codelineno-9-5 href=#__codelineno-9-5></a><span class=p>}</span>
</span><span id=__span-9-6><a id=__codelineno-9-6 name=__codelineno-9-6 href=#__codelineno-9-6></a>
</span><span id=__span-9-7><a id=__codelineno-9-7 name=__codelineno-9-7 href=#__codelineno-9-7></a><span class=k>pub</span><span class=w> </span><span class=k>struct</span><span class=w> </span><span class=nc>CreateUserHandler</span><span class=o><</span><span class=n>T</span><span class=p>:</span><span class=w> </span><span class=nc>UserRepository</span><span class=p>,</span><span class=w> </span><span class=n>E</span><span class=p>:</span><span class=w> </span><span class=nc>EventBus</span><span class=o>></span><span class=w> </span><span class=p>{</span>
</span><span id=__span-9-8><a id=__codelineno-9-8 name=__codelineno-9-8 href=#__codelineno-9-8></a><span class=w> </span><span class=n>user_repo</span><span class=p>:</span><span class=w> </span><span class=nc>Arc</span><span class=o><</span><span class=n>T</span><span class=o>></span><span class=p>,</span>
</span><span id=__span-9-9><a id=__codelineno-9-9 name=__codelineno-9-9 href=#__codelineno-9-9></a><span class=w> </span><span class=n>event_bus</span><span class=p>:</span><span class=w> </span><span class=nc>Arc</span><span class=o><</span><span class=n>E</span><span class=o>></span><span class=p>,</span>
</span><span id=__span-9-10><a id=__codelineno-9-10 name=__codelineno-9-10 href=#__codelineno-9-10></a><span class=p>}</span>
</span><span id=__span-9-11><a id=__codelineno-9-11 name=__codelineno-9-11 href=#__codelineno-9-11></a>
</span><span id=__span-9-12><a id=__codelineno-9-12 name=__codelineno-9-12 href=#__codelineno-9-12></a><span class=cp>#[async_trait]</span>
</span><span id=__span-9-13><a id=__codelineno-9-13 name=__codelineno-9-13 href=#__codelineno-9-13></a><span class=k>impl</span><span class=o><</span><span class=n>T</span><span class=p>,</span><span class=w> </span><span class=n>E</span><span class=o>></span><span class=w> </span><span class=n>CommandHandler</span><span class=o><</span><span class=n>CreateUserCommand</span><span class=o>></span><span class=w> </span><span class=k>for</span><span class=w> </span><span class=n>CreateUserHandler</span><span class=o><</span><span class=n>T</span><span class=p>,</span><span class=w> </span><span class=n>E</span><span class=o>></span>
</span><span id=__span-9-14><a id=__codelineno-9-14 name=__codelineno-9-14 href=#__codelineno-9-14></a><span class=k>where</span>
</span><span id=__span-9-15><a id=__codelineno-9-15 name=__codelineno-9-15 href=#__codelineno-9-15></a><span class=w> </span><span class=n>T</span><span class=p>:</span><span class=w> </span><span class=nc>UserRepository</span><span class=p>,</span>
</span><span id=__span-9-16><a id=__codelineno-9-16 name=__codelineno-9-16 href=#__codelineno-9-16></a><span class=w> </span><span class=n>E</span><span class=p>:</span><span class=w> </span><span class=nc>EventBus</span><span class=p>,</span>
</span><span id=__span-9-17><a id=__codelineno-9-17 name=__codelineno-9-17 href=#__codelineno-9-17></a><span class=p>{</span>
</span><span id=__span-9-18><a id=__codelineno-9-18 name=__codelineno-9-18 href=#__codelineno-9-18></a><span class=w> </span><span class=k>async</span><span class=w> </span><span class=k>fn</span><span class=w> </span><span class=nf>handle</span><span class=p>(</span><span class=o>&</span><span class=bp>self</span><span class=p>,</span><span class=w> </span><span class=n>cmd</span><span class=p>:</span><span class=w> </span><span class=nc>CreateUserCommand</span><span class=p>)</span><span class=w> </span><span class=p>-></span><span class=w> </span><span class=nb>Result</span><span class=o><</span><span class=p>(),</span><span class=w> </span><span class=n>Error</span><span class=o>></span><span class=w> </span><span class=p>{</span>
</span><span id=__span-9-19><a id=__codelineno-9-19 name=__codelineno-9-19 href=#__codelineno-9-19></a><span class=w> </span><span class=kd>let</span><span class=w> </span><span class=n>user</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>User</span><span class=p>::</span><span class=n>new</span><span class=p>(</span><span class=n>cmd</span><span class=p>.</span><span class=n>username</span><span class=p>,</span><span class=w> </span><span class=n>cmd</span><span class=p>.</span><span class=n>email</span><span class=p>);</span>
</span><span id=__span-9-20><a id=__codelineno-9-20 name=__codelineno-9-20 href=#__codelineno-9-20></a><span class=w> </span><span class=bp>self</span><span class=p>.</span><span class=n>user_repo</span><span class=p>.</span><span class=n>save</span><span class=p>(</span><span class=o>&</span><span class=n>user</span><span class=p>).</span><span class=k>await</span><span class=o>?</span><span class=p>;</span>
</span><span id=__span-9-21><a id=__codelineno-9-21 name=__codelineno-9-21 href=#__codelineno-9-21></a>
</span><span id=__span-9-22><a id=__codelineno-9-22 name=__codelineno-9-22 href=#__codelineno-9-22></a><span class=w> </span><span class=kd>let</span><span class=w> </span><span class=n>event</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>UserCreated</span><span class=w> </span><span class=p>{</span>
</span><span id=__span-9-23><a id=__codelineno-9-23 name=__codelineno-9-23 href=#__codelineno-9-23></a><span class=w> </span><span class=n>user_id</span><span class=p>:</span><span class=w> </span><span class=nc>user</span><span class=p>.</span><span class=n>id</span><span class=p>,</span>
</span><span id=__span-9-24><a id=__codelineno-9-24 name=__codelineno-9-24 href=#__codelineno-9-24></a><span class=w> </span><span class=n>timestamp</span><span class=p>:</span><span class=w> </span><span class=nc>Utc</span><span class=p>::</span><span class=n>now</span><span class=p>(),</span>
</span><span id=__span-9-25><a id=__codelineno-9-25 name=__codelineno-9-25 href=#__codelineno-9-25></a><span class=w> </span><span class=p>};</span>
</span><span id=__span-9-26><a id=__codelineno-9-26 name=__codelineno-9-26 href=#__codelineno-9-26></a>
</span><span id=__span-9-27><a id=__codelineno-9-27 name=__codelineno-9-27 href=#__codelineno-9-27></a><span class=w> </span><span class=bp>self</span><span class=p>.</span><span class=n>event_bus</span><span class=p>.</span><span class=n>publish</span><span class=p>(</span><span class=n>event</span><span class=p>).</span><span class=k>await</span><span class=o>?</span><span class=p>;</span>
</span><span id=__span-9-28><a id=__codelineno-9-28 name=__codelineno-9-28 href=#__codelineno-9-28></a><span class=w> </span><span class=nb>Ok</span><span class=p>(())</span>
</span><span id=__span-9-29><a id=__codelineno-9-29 name=__codelineno-9-29 href=#__codelineno-9-29></a><span class=w> </span><span class=p>}</span>
</span><span id=__span-9-30><a id=__codelineno-9-30 name=__codelineno-9-30 href=#__codelineno-9-30></a><span class=p>}</span>
</span></code></pre></div> <h2 id=conclusion>Conclusion<a class=headerlink href=#conclusion title="Permanent link">¶</a></h2> <p>The Hexagonal Architecture provides a clean separation of concerns, making the codebase more maintainable and testable. By following these patterns, we ensure that Anya Core remains flexible and adaptable to future changes.</p> <h2 id=see-also>See Also<a class=headerlink href=#see-also title="Permanent link">¶</a></h2> <ul> <li><a href=./related1.md>Related Document 1</a></li> <li><a href=./related2.md>Related Document 2</a></li> </ul> <aside class=md-source-file> <span class=md-source-file__fact> <span class=md-icon title="Last update"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z"/></svg> </span> <span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago" title="May 30, 2025 09:53:32 UTC"><span class=timeago datetime=2025-05-30T09:53:32+00:00 locale=en></span></span><span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date" title="May 30, 2025 09:53:32 UTC">2025-05-30</span> </span> </aside> </article> </div> <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script> </div> <button type=button class="md-top md-icon" data-md-component=top hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg> Back to top </button> </main> <footer class=md-footer> <div class="md-footer-meta md-typeset"> <div class="md-footer-meta__inner md-grid"> <div class=md-copyright> <div class=md-copyright__highlight> Copyright © 2025 Anya Foundation </div> Made with <a href=https://squidfunk.github.io/mkdocs-material/ target=_blank rel=noopener> Material for MkDocs </a> </div> <div class=md-social> <a href=https://github.com/botshelomokoka/Anya-core target=_blank rel=noopener title=github.com class=md-social__link> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 496 512"><!-- Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8M97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg> </a> <a href=https://twitter.com/anyacore target=_blank rel=noopener title=twitter.com class=md-social__link> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 512 512"><!-- Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253"/></svg> </a> <a href=https://discord.gg/anya-core target=_blank rel=noopener title=discord.gg class=md-social__link> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 640 512"><!-- Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M524.531 69.836a1.5 1.5 0 0 0-.764-.7A485 485 0 0 0 404.081 32.03a1.82 1.82 0 0 0-1.923.91 338 338 0 0 0-14.9 30.6 447.9 447.9 0 0 0-134.426 0 310 310 0 0 0-15.135-30.6 1.89 1.89 0 0 0-1.924-.91 483.7 483.7 0 0 0-119.688 37.107 1.7 1.7 0 0 0-.788.676C39.068 183.651 18.186 294.69 28.43 404.354a2.02 2.02 0 0 0 .765 1.375 487.7 487.7 0 0 0 146.825 74.189 1.9 1.9 0 0 0 2.063-.676A348 348 0 0 0 208.12 430.4a1.86 1.86 0 0 0-1.019-2.588 321 321 0 0 1-45.868-21.853 1.885 1.885 0 0 1-.185-3.126 251 251 0 0 0 9.109-7.137 1.82 1.82 0 0 1 1.9-.256c96.229 43.917 200.41 43.917 295.5 0a1.81 1.81 0 0 1 1.924.233 235 235 0 0 0 9.132 7.16 1.884 1.884 0 0 1-.162 3.126 301.4 301.4 0 0 1-45.89 21.83 1.875 1.875 0 0 0-1 2.611 391 391 0 0 0 30.014 48.815 1.86 1.86 0 0 0 2.063.7A486 486 0 0 0 610.7 405.729a1.88 1.88 0 0 0 .765-1.352c12.264-126.783-20.532-236.912-86.934-334.541M222.491 337.58c-28.972 0-52.844-26.587-52.844-59.239s23.409-59.241 52.844-59.241c29.665 0 53.306 26.82 52.843 59.239 0 32.654-23.41 59.241-52.843 59.241m195.38 0c-28.971 0-52.843-26.587-52.843-59.239s23.409-59.241 52.843-59.241c29.667 0 53.307 26.82 52.844 59.239 0 32.654-23.177 59.241-52.844 59.241"/></svg> </a> </div> </div> </div> </footer> </div> <div class=md-dialog data-md-component=dialog> <div class="md-dialog__inner md-typeset"></div> </div> <script id=__config type=application/json>{"base": "..", "features": ["navigation.tabs", "navigation.tabs.sticky", "navigation.sections", "navigation.indexes", "navigation.instant", "navigation.tracking", "navigation.expand", "navigation.top", "navigation.footer", "search.highlight", "search.suggest", "search.share", "content.code.annotate", "content.code.copy", "content.tooltips", "content.action.edit", "content.action.view"], "search": "../assets/javascripts/workers/search.d50fe291.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": {"provider": "mike"}}</script> <script src=../assets/javascripts/bundle.13a4f30d.min.js></script> <script src=../js/timeago.min.js></script> <script src=../js/timeago_mkdocs_material.js></script> <script src=../js/extra.js></script> </body> </html>