Upgrade to Pro — share decks privately, control downloads, hide ads and more …

NEWT Backend Evolution

NEWT Backend Evolution

About NEWT Backend Tech Selection and how this has evolved since 2021
What are the challenges we are facing, and how do we plan to solve them?

Challenges:
- TypeScript Library Dependency Risks
- TypeScript Decorator Usage Risks
- From Modular Monolith to Modular Monolith Monorepo
- TypeScript Freedom

Avatar for Rodrigo Ramirez

Rodrigo Ramirez

July 14, 2025
Tweet

More Decks by Rodrigo Ramirez

Other Decks in Programming

Transcript

  1. © 2023 Reiwa Travel, Inc.
 Profile • Nationality: Argentinian •

    Language: Spanish, English, Japanese • Full Stack Developer (+10y) Career • 󰎆 2006~: Freelance • 󰎆 2008~: PowerSite ( CTO/CEO ) ◦ Email Marketing SaaS • 󰏦 2015~: Travelience ( CTO ) ◦ Tour Guide Marketplace • 󰏦 2021~: ReiwaTravel ( Senior Engineer ) Senior Engineer / Product-Dev Rodrigo Ramirez
  2. 社名 株式会社令和トラベル 代表者 篠塚 孝哉 創業 2021年4⽉5⽇ 従業員 100名(役員‧正社員)※2024年5⽉1⽇時点 登録番号

    観光庁⻑官登録旅⾏業第2123号 資本⾦ 70.2億円 (資本剰余⾦を含む) 会社概要 About Us
  3. 私たちのサービス Our Service 海外ツアー予約 宿‧ホテル予約 (ホテル + 航空券セット) 旅⾏ ガイド

    トラベル コンシェルジュ グループトラベル ‧修学旅⾏  ‧企業の研修旅⾏など かんたん‧おトク‧えらべる‧あんしんな旅⾏の提供 ‧旅⾏相談 ‧VIP対応
  4. Backend Stack 📆 Tech choices made in 2021 (PoC start

    – now ~4 years) • Language: TypeScript: ( Full-Stack team ) • Framework: None ( Build on top of Apollo Server and Express ) • ORM: TypeORM • Architecture: Modular Monolith • Infrastructure: GCP ├ 📁modules │ ├ 📁module-A │ ├ 📁module-B │ └ 📁… └ 📄server.ts
  5. Issue • TypeScript ecosystem moves quickly → upgrades and replacements

    are necessary • Core libraries used directly without abstraction layer → expensive technical debt Challenge ① : 📦 Library Dependency Risks
  6. e.g: TypeORM • We decided to use TypeORM in 2021

    ( 4 years ago ) • Poor maintenance (project abandoned for long time) • Uncertainty about long-term evolution • Community migrating to Prisma Challenge ① : 📦 Library Dependency Risks
  7. Migration Pains: • Entities are imported directly from module •

    Business logic mixed with ORM calls • Hard to replace Booking/User entity implementation • Tests must hit the database Challenge ① : 📦 Library Dependency Risks
  8. Solution: • Added our Own repository layer to make swapping

    the ORM (TypeORM ↔ Prisma) easy • Testing simplified by mocking the repository interface • Incremental Replacement of current modules Challenge ① : 📦 Library Dependency Risks
  9. Lesson learned: • Libraries can become outdated or stop being

    maintained • To reduce future migration pain, add an abstraction layer around any library you use deeply in your system Challenge ① : 📦 Library Dependency Risks
  10. Context • We used TypeGraphQL + TypeORM that works based

    on decorators Issue • Magic Behavior • Refactoring Challenges • Mixing decorators can cause issues and coupling Challenge ② : 🪄 Decorator Coupling Risks
  11. Problems • GraphQL schema tied to entities • Cross-module cycles

    & tight coupling Challenge ② : 🪄 Decorator Coupling Risks
  12. Growth Pain • Modular Monolith → many products → many

    teams Issues • Products mixed inside monolith • No rules → no isolation • One change affects many modules • Single deploy → can’t split apps Challenge ③ : 🏢 Monolith Scalability Issues
  13. Issue • No rules → no isolation Challenge ③ :

    🏢 Monolith Scalability Issues
  14. Issue • No rules → no isolation Challenge ③ :

    🏢 Monolith Scalability Issues
  15. We changed the directory structure to a typical TypeScript monorepo

    ├ 📁modules │ ├ 📁module-A │ ├ 📁module-B │ └ 📁… └ 📄server.ts ├ 📁apps │ ├ 📁app-A │ └ 📁app-B └ 📁packages ├ 📁package-A ├ 📁package-B └ 📁core Before After Challenge ③ : 🏢 Monolith Scalability Issues
  16. Moved legacy code inside one of the apps and incrementally

    migrate it ├ 📁modules │ ├ 📁module-A │ ├ 📁module-B │ └ 📁… └ 📄server.ts ├ 📁apps │ ├ 📁app-A │ └ 📁app-B └ 📁packages ├ 📁package-A ├ 📁package-B └ 📁core Before After Challenge ③ : 🏢 Monolith Scalability Issues
  17. • Turborepo for builds & parallel tasks • CODEOWNERS to

    assign ownership • ESLint rules block forbidden imports Challenge ③ : 🏢 Monolith Scalability Issues
  18. • Issue: TS has no single framework (unlike RoR/Laravel) ◦

    → Developers do as they like → more of the above problems • Need: Clear Structure + Coding Rules Challenge ④ : 🎨 Freedom & Governance
  19. • Solution: ◦ Documentation as Code in .agent-rules/ ▪ AI

    agents read these rules automatically Challenge ④ : 🎨 Freedom & Governance
  20. AI Code Agents can • Generate code by our standards

    • Migrate old code → new style • Answer architecture questions • Suggest improvements in code review Implementation • .agent-rules/ mirrors monorepo layout • GitHub Actions runs AI review jobs • Agents (Cursor, Cline, Claude) load rules Challenge ④ : 🎨 Freedom & Governance
  21. 🎯 Lessons Learned • Don’t over-engineer eraly, instead incrementally evolve

    your code before it hurts. • Correct usage of Code Isolation and Layers are important when growing • AI code agents are the future, clear rules helps us to fully use their potential 振り返り