[{"data":1,"prerenderedAt":193},["ShallowReactive",2],{"content-\u002Fblog\u002Fclean-architecture-for-enterprise-apps":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"tags":11,"readingTime":16,"draft":6,"body":17,"_type":187,"_id":188,"_source":189,"_file":190,"_stem":191,"_extension":192},"\u002Fblog\u002Fclean-architecture-for-enterprise-apps","blog",false,"","Clean architecture for enterprise apps","Module boundaries, domain services, and persistence isolation so enterprise applications stay evolvable—especially in fintech and regulated workflows.","2026-04-26",[12,13,14,15],"Architecture","Enterprise","Backend","Fintech","6 min",{"type":18,"children":19,"toc":178},"root",[20,43,50,55,61,66,72,91,97,111,117,142,148],{"type":21,"tag":22,"props":23,"children":24},"element","p",{},[25,28,34,36,41],{"type":26,"value":27},"text","Enterprise applications accumulate requirements faster than any team can rewrite. ",{"type":21,"tag":29,"props":30,"children":31},"strong",{},[32],{"type":26,"value":33},"Clean architecture",{"type":26,"value":35}," here does not mean a diagram from a book—it means ",{"type":21,"tag":29,"props":37,"children":38},{},[39],{"type":26,"value":40},"dependencies point inward",{"type":26,"value":42},", and domain rules stay testable when the database or UI framework changes.",{"type":21,"tag":44,"props":45,"children":47},"h2",{"id":46},"separate-domain-services-from-delivery-mechanisms",[48],{"type":26,"value":49},"Separate domain services from delivery mechanisms",{"type":21,"tag":22,"props":51,"children":52},{},[53],{"type":26,"value":54},"HTTP controllers, CLI jobs, and message consumers should be thin. They parse input, call application services, and map results to responses. The “what should happen when a loan is approved?” question belongs in a service that does not know about Express, Nuxt, or Nest decorators.",{"type":21,"tag":44,"props":56,"children":58},{"id":57},"persistence-should-not-own-your-behavior",[59],{"type":26,"value":60},"Persistence should not own your behavior",{"type":21,"tag":22,"props":62,"children":63},{},[64],{"type":26,"value":65},"ORM models are convenient but dangerous as the home for business rules. Keep persistence mapping predictable: load aggregates, apply domain operations, persist changes. If SQL becomes the source of truth for policy, you will eventually lose the ability to reason about the system in code review.",{"type":21,"tag":44,"props":67,"children":69},{"id":68},"boundaries-that-match-how-teams-work",[70],{"type":26,"value":71},"Boundaries that match how teams work",{"type":21,"tag":22,"props":73,"children":74},{},[75,77,82,84,89],{"type":26,"value":76},"Modules should reflect ",{"type":21,"tag":29,"props":78,"children":79},{},[80],{"type":26,"value":81},"team boundaries",{"type":26,"value":83}," or ",{"type":21,"tag":29,"props":85,"children":86},{},[87],{"type":26,"value":88},"bounded contexts",{"type":26,"value":90}," where possible. Two teams fighting over one “god” package is a scaling problem for people, not machines. Clear interfaces between modules make refactors feasible.",{"type":21,"tag":44,"props":92,"children":94},{"id":93},"connect-architecture-to-outcomes",[95],{"type":26,"value":96},"Connect architecture to outcomes",{"type":21,"tag":22,"props":98,"children":99},{},[100,102,109],{"type":26,"value":101},"Readable structure shows up in hiring conversations and delivery speed. On this site, the ",{"type":21,"tag":103,"props":104,"children":106},"a",{"href":105},"\u002Fprojects\u002Floan-management-platform",[107],{"type":26,"value":108},"loan management platform case study",{"type":26,"value":110}," ties architecture language to a concrete product story—use the same pattern in your portfolio.",{"type":21,"tag":44,"props":112,"children":114},{"id":113},"practical-checklist",[115],{"type":26,"value":116},"Practical checklist",{"type":21,"tag":118,"props":119,"children":120},"ul",{},[121,127,132,137],{"type":21,"tag":122,"props":123,"children":124},"li",{},[125],{"type":26,"value":126},"Domain rules live in services, not controllers.",{"type":21,"tag":122,"props":128,"children":129},{},[130],{"type":26,"value":131},"DTOs validate shape; services validate meaning.",{"type":21,"tag":122,"props":133,"children":134},{},[135],{"type":26,"value":136},"Side effects (email, webhooks) are explicit and retry-safe.",{"type":21,"tag":122,"props":138,"children":139},{},[140],{"type":26,"value":141},"Migrations are reviewed like application code.",{"type":21,"tag":44,"props":143,"children":145},{"id":144},"summary",[146],{"type":26,"value":147},"Summary",{"type":21,"tag":22,"props":149,"children":150},{},[151,155,157,162,164,169,171,176],{"type":21,"tag":29,"props":152,"children":153},{},[154],{"type":26,"value":8},{"type":26,"value":156}," is about ",{"type":21,"tag":29,"props":158,"children":159},{},[160],{"type":26,"value":161},"testable domain logic",{"type":26,"value":163},", ",{"type":21,"tag":29,"props":165,"children":166},{},[167],{"type":26,"value":168},"honest persistence",{"type":26,"value":170},", and ",{"type":21,"tag":29,"props":172,"children":173},{},[174],{"type":26,"value":175},"module boundaries",{"type":26,"value":177}," that match how the product actually evolves—especially when financial logic is involved.",{"title":7,"searchDepth":179,"depth":179,"links":180},2,[181,182,183,184,185,186],{"id":46,"depth":179,"text":49},{"id":57,"depth":179,"text":60},{"id":68,"depth":179,"text":71},{"id":93,"depth":179,"text":96},{"id":113,"depth":179,"text":116},{"id":144,"depth":179,"text":147},"markdown","content:blog:clean-architecture-for-enterprise-apps.md","content","blog\u002Fclean-architecture-for-enterprise-apps.md","blog\u002Fclean-architecture-for-enterprise-apps","md",1777380682559]