Tüm yazılar
14 · Mühendislik · 2026.08 · 5 dk

Bir ürün, üç yüz: Motice'te web, servis ve mobil aynı monorepoda

Motice; pilates, yoga, kişisel antrenman ve wellness stüdyoları için geliştirilen bir CRM/ERP ürünü. Yönetim uygulaması, müşteri portalı ve mobil uygulama aynı işletme süreçlerinin farklı yüzleri. Bu yazı, onları tek bir TypeScript monoreposunda tutmanın ne anlama geldiğini anlatıyor.

01Dağınık araçların maliyeti

Randevu tabanlı bir stüdyoda günlük iş; randevular, müşteriler, dersler ve işletme işlemleri arasında gidip geliyor. Bunlar farklı araçlara dağıldığında hem işletme hem müşteri aynı bilgiyi birkaç yerde arıyor. Motice bu akışları, işletmelerin kendi ayrı çalışma alanlarında yönetebileceği ortak bir üründe topluyor.

Bu tür bir dağınıklığın maliyeti çoğu zaman tek bir büyük hata olarak görünmüyor; küçük sürtünmeler olarak birikiyor. Bir bilgi bir yerde güncellenip başka bir yerde eski kalıyor, aynı soru iki farklı kaynaktan iki farklı cevap alıyor. Randevu tabanlı işlerde zamanın kendisi ürünün parçası olduğu için bu tür tutarsızlıklar doğrudan işletmenin gününe yansıyor. Bence akışları tek bir ürün modelinde toplamanın değeri tam olarak burada.

02Üç yüz, tek model

Ürünün üç yüzü var: işletmenin kullandığı yönetim uygulaması, müşterinin tarayıcıdan eriştiği portal ve Expo ile geliştirilen müşteri uygulaması. Üçü de aynı randevuya, aynı müşteriye, aynı derse bakıyor. Bu yüzden onları ayrı projeler olarak değil, ortak bir ürün modelinin farklı görünümleri olarak ele alıyoruz.

Her yüzün kullanıcısı ve beklentisi farklı. İşletme tarafı geniş bir görünüm, hızlı düzenleme ve operasyonu bir bakışta görebilmek istiyor. Müşteri ise kendi randevusuna ve kendi bilgisine kısa yoldan ulaşmak istiyor; bunu bazen tarayıcıdan, bazen telefondan yapıyor. Ekranlar farklılaşabilir, ama altta yatan kavramlar aynı kalmalı. Bir randevunun ne olduğu ve kime ait olduğu, hangi yüzden bakılırsa bakılsın aynı cevabı vermeli.

yapı
TypeScript monorepo
├─ React + Vite   web arayüzleri
├─ Expo           müşteri uygulaması
├─ Fastify + tRPC servis katmanı
└─ PostgreSQL + Drizzle ORM

03Neden monorepo

Tek bir TypeScript monoreposu, React arayüzlerini, Fastify ve tRPC servis katmanını ve PostgreSQL ile Drizzle veri katmanını aynı çatı altında tutuyor. Ortak bileşenler web ve mobil arasında tutarlılığı hedefliyor; tRPC sayesinde arayüzler servis tarafındaki tiplerle aynı dili konuşuyor. Bir alanın adı ya da şekli değiştiğinde bu değişiklik derleme sırasında ilgili bütün yüzlerde görünür hâle geliyor.

Bunun bir bedeli de var. Monorepo, sınırları gevşetmeye çok müsait bir yapı; her şey aynı yerde olduğu için bir paketin başka bir paketin iç ayrıntısına uzanması kolaylaşıyor. Bu yüzden bu tür yapılarda neyin paylaşılacağını bilinçli seçmek gerektiğini düşünüyorum: tipler, sözleşmeler ve gerçekten ortak olan bileşenler paylaşılmalı; tek bir yüze özgü davranış o yüzde kalmalı. Ortak bileşenlerin amacı her şeyi aynı yapmak değil, aynı kavramın her yerde aynı biçimde görünmesini sağlamak.

Bir işletmenin günlük ritmini anlayan yazılım, tek ekranla değil akışların uyumuyla ölçülür.

04Çalışma alanları ve veri sınırları

Motice'te işletmeler kendi ayrı çalışma alanları içinde çalışıyor. Bu tür ürünlerde benim için en önemli sorulardan biri, bir işletmenin verisinin hiçbir koşulda başka bir işletmenin görünümüne karışmaması. Bunu yalnızca arayüzde bir filtreyle sağlamaya çalışmak kırılgan bir yaklaşım; sınırın servis ve veri katmanında, her isteğin bağlamının parçası olarak düşünülmesi bana daha sağlam geliyor. Tipli bir servis ve veri katmanı, bu tür sınırları kodda görünür kılmaya yardımcı oluyor.

Aynı düşünce takvim için de geçerli. Ders, randevu ve müşteri birbirinden bağımsız kayıtlar gibi görünse de gerçekte sürekli birbirine referans veriyor. Bir değişiklik bir yerde yapıldığında diğer yüzlerin bunu aynı biçimde yansıtması, kullanıcının ürüne güvenmesinin temel koşulu.

Bu tür ürünlerde zor kısım genellikle tek tek özellikler değil, özelliklerin kesiştiği yerler. Bir ders, o derse ait randevular ve işletmenin gün içindeki görünümü aslında aynı bilginin farklı okumaları. Bu kesişimleri ortak bir modelde ifade etmek, her yeni ekranın kendi kurallarını sıfırdan icat etmesini engelliyor.

05Benim için asıl ilginç olan

Motice, Unitic ekibinin ortak ürünü ve ben geliştirmesine ekip içinde katkı sağlıyorum. Bu projede beni en çok çeken şey tek bir ekranı tamamlamak değil; takvim, müşteri ve operasyon akışlarının aynı ürün içinde birbirini doğru tamamlaması. Ortak bir kod tabanında ekip olarak çalışmanın bir getirisi de, bir değişikliğin başka birinin işini nasıl etkilediğini erken görmek. Paylaşılan tipler bu konuşmayı somutlaştırıyor: bir sözleşme değiştiğinde etkilenen yerler tartışmaya gerek kalmadan ortaya çıkıyor.

Geliştirme aşamasındaki bir ürün üzerinde çalışmak da ayrı bir deneyim. Kararlar henüz donmadığı için, bugün kurulan modelin yarın eklenecek akışları da taşıyabilmesi gerekiyor. Bu yüzden bir yapıyı ele alırken yalnızca bugünkü ekranı değil, o yapının ileride nasıl genişleyebileceğini de düşünmeye çalışıyorum.

İlgili yazılar
  1. 15Gerçek cihazlarda blockchain: üç Raspberry Pi ile 72 saatAr-Ge ve donanım2026.075 dk
  2. 16Kod yazmadan önce: Mentorual'da kararları netleştirmekÜrün ve analiz2026.065 dk