Profil
Planlarını üreten bütün motorlar tek bir kayıttan besleniyor: profilin. Burada değiştirdiğin her satır, hangi motoru tazeleyeceğini bilerek kaydediliyor.

Profil · 1/10
Profil modülünün ana ekranı. Alt menüden ya da her ekranın hesap girişinden buraya gelirsin; modülün geri kalanı (sağlık beyanı, ölçüler, ayarlar) buradan dallanır.
Motorların kullandığı verini bölüm bölüm görür, eskiyeni düzenleyip kaydedersin.
- Ayarlar — sağ üstteki dişli (profile_screen.dart:394)
- Sağlık Durumum — sağlık beyanı bölümündeki detay bağlantısı (profile_health_declaration_section.dart:148)
- Manuel Ölçümler — vücut ölçüleri bölümü (profile_screen.dart:146)
- Market — sahip olmadığın bir ekipmana dokununca o kategori (profile_screen.dart:267)
- Geri — geldiğin ekran, yoksa ana ekran (profile_screen.dart:264)
Bu ekranda ne var 4
Diyelim ki üstteki dört kutuda "ANTREN %96 · BESLENME %88 · FORM %92 · DOKTOR ONAYI %100" yazıyor ve sen "bu yüzdeleri kim hesapladı" diye merak ediyorsun.
Bu dört sayıyı telefonun değil, sunucu hesaplıyor ve hazır gönderiyor.
Yüzdeler bir eşiğe bakıyor: verinin kaç gün önce girildiğine. O "kaç gün" hesabının başlangıç saatini telefon verseydi, saati geri alınmış bir telefonda gün farkı hiç büyümez ve hazırlık hep %100 görünürdü. Bu yüzden saat, profil omurgası ve ölçü sayıları sunucunun kasasından kuruluyor; istemci bu alanları hiç göndermiyor.
Bir sayı düştüğünde bu bir arıza değil, gerçek bir sinyaldir: o motorun okuduğu alanlardan biri eskimiş. İlgili bölümü açıp güncelle, sayı geri çıkar.
Buna sistemde "sunucu-otoriteli girdi" denir.
Diyelim ki uçaktasın, internet yok ve profili açtın. Hazırlık kutuları ve "2 gün önce" satırları görünmüyor.
Tazelik cevabı alınamadığında ekran o bandı ve o satırları hiç çizmez.
Cevap gelmediğinde iki kolay yalan var: %0 yazmak ("profilin bomboş") ya da %100 yazmak ("her şey tamam"). İkincisi tehlikeli, çünkü kullanıcı iki ay önceki kiloyla üretilmiş planı güncel sanar. Kod bu yüzden üçüncü bir dal açmıyor — sonuç tipi iki dallı ve derleyici çağıranı ikisini de yazmaya zorluyor.
Bant görünmüyorsa panik yok; bağlantı gelince yeniden çıkar. Bantın yokluğu "verim kötü" demek değil, "şu an ölçemiyorum" demektir.
Buna sistemde "fail-closed" (şüphede güvence verme) denir.
Diyelim ki her bölümün üstünde küçük ANTREN / BESLENME jetonları var ve "bu bölümü değiştirirsem ne olur" diye düşünüyorsun.
O jetonlar süs değil; o bölümdeki alanların hangi motorları beslediğini alan tanımlarından okuyup gösteriyor.
Her profil alanının tanımında iki bayrak var: antrenman motorunu etkiler mi, beslenme motorunu etkiler mi. Bölüm başlığındaki jeton bu bayrakların toplamı. Yani liste elle yazılmıyor, alan tanımlarından türüyor — yeni bir alan eklendiğinde jeton kendiliğinden doğru kalıyor.
Bir bölümü düzenlemeden önce jetonlara bak: hangi planının yeniden kurulacağını kaydetmeden önce görürsün.
Buna sistemde "türetilmiş etki haritası" denir.
Diyelim ki "Boy (cm)" satırının yanında küçük bir kilit simgesi var ve boyunu değiştiremiyorsun.
18 yaşını doldurmuş kullanıcılarda boy alanı kilitlenir.
Boy, yetişkinlikte artık değişmeyen bir ölçüdür ve yağ oranı formülünün paydasında durur. Kazara girilen bir rakam (178 yerine 187) hem vücut yağ yüzdesini hem de günlük kalori hedefini sessizce kaydırır. Eşik kodda tek yerde tanımlı; ekran o sayıyı tekrar yazmıyor, okuyor. Yaş bilinmiyorsa alan yine kilitli kalır — güvenli yön.
Boyun gerçekten yanlışsa destek üzerinden düzeltilir; kendi kendine değiştirilebilseydi bütün geçmiş ölçümlerin karşılaştırılabilirliği bozulurdu.
Buna sistemde "yaş politikası kilidi" denir.
Perde arkası — sistem nasıl karar veriyor 6
Profil neden tek doğruluk kaynağı
Diyelim ki kayıt olurken kilonu 88 kg yazdın, aylar sonra profilden 82 kg olarak güncelledin. Şimdi motorlar hangi sayıyı okuyacak?
Profilde biriken kayıt varsa motorlar onu okur; yoksa kayıt sırasındaki cevaplarına düşer.
İki kayıt birden var: onboarding cevapların ve profilde biriken güncel omurga. Okuma sırası tek bir yerde tanımlı — önce omurga, boşsa onboarding. Bu sıra olmasaydı her motor kendi tercih ettiği kaynağı okur ve antrenman planı 88 kg, beslenme planı 82 kg ile üretilirdi. Aynı kullanıcı için iki farklı gerçek, kullanıcının fark edemeyeceği bir çelişki demektir.
Bir sayıyı değiştireceksen profilden değiştir; onboarding cevapların arşivdir, motorlar oraya ancak profil boşsa bakar.
Buna sistemde "tek doğruluk kaynağı" (single source of truth) denir.
Hangi alan hangi motoru besliyor
Diyelim ki iki değişiklik yaptın: birinde antrenman seviyeni L2'den L3'e çektin, ötekinde gün içi hareketliliğini "masa başı"ndan "hareketli iş"e aldın.
Birincisi yalnız antrenman planını, ikincisi yalnız beslenme planını yeniden ürettirir; kilo/boy/doğum tarihi ise ikisini birden.
Her profil alanının tanımında iki bayrak var. Seviye ve hedef antrenman bayrağını taşıyor (split, hacim ve hareket havuzu bunlardan kuruluyor); gün içi hareketlilik ve adım bandı beslenme bayrağını taşıyor (günlük harcama tahmini bunlardan kuruluyor); kilo, boy ve doğum tarihi ikisinde de işaretli, çünkü hem yük hesabına hem kalori hesabına giriyor. Kaydettiğinde bu bayraklar kesiştiriliyor ve yalnız etkilenen planın önbelleği düşürülüyor.
Küçük bir düzeltme yaptığında bütün planların baştan kurulmaz — yalnız o alanın dokunduğu motor tazelenir. Antrenman etkilenen bir değişiklikte ekranda bunu söyleyen bir bilgi şeridi de çıkar.
Buna sistemde "alan → motor etki haritası" denir.
Aynı haftanın beslenme planı ne zaman yeniden kurulur
Diyelim ki çarşamba günü hedefini "yağ kaybı"ndan "kas kazanımı"na çevirdin. Bu haftanın planı ne olacak?
Beslenmeyi etkileyen bir alan değiştiyse sunucuya "aynı hafta yeniden üretilsin mi" diye sorulur; değişmediyse hiç sorulmaz.
Karar sunucuda, çünkü "hafta ortasında planı değiştirmek doğru mu" bir ürün kararıdır ve uygulama güncellemesi beklemeden değişebilmelidir. Ama bu soru her kayıtta sorulmuyor: yalnız avatarını değiştirdiğinde bir ağ turu beklemek, kaydet düğmesinin önüne sebepsiz bir gecikme koymak olurdu. Bu yüzden kapı yalnız beslenme-etkileyen bir alan değiştiğinde açılıyor.
Hedef değişikliğini haftanın başında yapmak en temiz sonucu verir; hafta ortasındaki değişikliğin bu haftaya mı yoksa gelecek haftaya mı yansıyacağını sunucu kararı belirler.
Buna sistemde "sunucu kapısı" (feature gate) denir.
Sağlık beyanı planı nasıl kısıtlar
Diyelim ki omuz hassasiyetini "hafif" olarak işaretledin ve ertesi hafta planında bazı bastırma hareketlerinin yerine başkaları geldi.
Beyanın, hareket havuzunu plan üretilmeden önce daraltır.
Zincir üç adım: işaretlediğin durum bir kısıt bayrağına, seçtiğin şiddet bir yük tavanına, ikisi birlikte havuz filtresine dönüşüyor. Filtre plan kurulmadan ÖNCE çalışıyor — sonradan çalışsaydı sana önce gösterilip sonra geri çekilen hareketler olurdu. Hiçbir şey işaretlemezsen filtre adımı hiç kurulmuyor ve havuzun tamamı kullanılıyor.
Bir sakatlık yaşadığında beyanı güncelle ve planını yenile; motor bir sonraki üretimde otomatik uyum sağlar.
Buna sistemde "üretim öncesi havuz filtresi" denir.
Beslenme planı ve ölçü bölümleri neden herkeste görünmüyor
Diyelim ki arkadaşının profilinde "Beslenme Planı" ve "Vücut Ölçüleri" bölümleri var, seninkinde yok.
Bu iki bölüm yalnız beslenme erişimi olan kullanımlarda çizilir.
İki bölüm de beslenme-özel veri topluyor: diyet tipi, erzak erişimi ve yedi çevre ölçüsü. Antrenman motoru bunları kullanmıyor. Erişimi olmayan bir kullanıcıdan bu veriyi istemek, hiçbir çıktısı olmayan bir formu doldurtmak olurdu. Aynı sebeple profil tamamlanma yüzdesi de bu bölümleri gizliyken saymıyor — görünmeyen bir bölüm "eksik" sayılıp yüzdeyi düşüremez.
Bölümleri görmüyorsan profilin eksik değil; o veriyi okuyan motor senin kullanımında kapalı.
Buna sistemde "segment ayrımı" denir.
Bilinmeyen yaş neden "—" olarak yazılır
Diyelim ki doğum tarihini hiç seçmedin. Ekranda "Doğum Tarihi: Seçilmedi" yazıyor, yanında yaş satırı da "—".
Yaş hesaplanamadığında sıfır değil, boş gösterilir.
Veri modelinde yaş sayısı boş kalamıyor ve doğum tarihi yokken sıfır dönüyordu; ekran bunu olduğu gibi yazınca "Doğum Tarihi: Seçilmedi" satırının hemen yanında "0 yaş" görünüyordu. Yani sistem, bilmediği bir şeyi biliyormuş gibi konuşuyordu. Bu üründe sıfır geçerli bir yaş olmadığı için tek kaynakta boşa çevriliyor ve bu satırı okuyan bütün yüzeyler aynı anda dürüst hâle geliyor.
Bir alanda "—" görüyorsan sistem o veriyi bilmiyor demektir; doldurduğunda ilgili motorun hazırlık yüzdesi de yükselir.
Buna sistemde "dürüst boş" (honest empty) denir.
Verin ne işe yarar 8
Doğum tarihi, boy ve kilo
Girersen Günlük kalori hedefin ve antrenman yükün senin ölçülerinden hesaplanır; her ikisi de bu üç alanı birden okur.
Girmezsen Profil ve onboarding kaydı birlikte boşsa sistem sentetik bir varsayılan profille (30 yaş, 170 cm, 70 kg) çalışmak zorunda kalır. Plan yine üretilir ama sana ait olmaz; bu durum sessiz de değildir, veri-bütünlüğü sinyali olarak kayda düşer.
Antrenman seviyesi ve hedefi
Girersen Haftalık bölünme, hacim ve hareket havuzu bu ikisinden kurulur; değiştirdiğinde plan yeniden üretilir ve ekranda bunu söyleyen bir bilgi şeridi çıkar.
Girmezsen Seviye okunamadığında en düşük seviye (L1) varsayılır. Yanlış bir program almazsın ama olduğundan kolay bir program alırsın — ilerleme beklediğinden yavaş olur.
Gün içi hareketlilik ve günlük adım bandı
Girersen Günlük enerji harcaman antrenman dışı hareketini de sayar; masa başı çalışan biriyle gün boyu ayakta olan birinin kalori hedefi ayrışır.
Girmezsen Bu iki alan yalnız beslenme motorunu besler. Boş kaldığında antrenman planın etkilenmez, ama kalori hedefin gerçek harcamandan sapar — kilo hedefinde ilerlemenin durmasının en sık sebeplerinden biri budur.
Boyun, bel ve kalça ölçüsü
Girersen Vücut yağ yüzdesi Navy formülüyle hesaplanır, oradan da günlük kalori hedefin kurulur.
Girmezsen Kaydetme adımı engellenir ve hangi üç ölçünün gerektiği söylenir. Ölçü hiç girilmezse yağ yüzdesi hesaplanamaz; form analizi bölge bazında konuşamaz, yalnız kilo üzerinden genel bir tahmin kalır.
Sağlık beyanı (kısıtlar ve eklem hassasiyetleri)
Girersen İşaretlediğin her kısıt, plan üretilmeden önce hareket havuzunu daraltır; şiddet seçimin eklem yükü tavanına çevrilir.
Girmezsen Hiçbir şey işaretlemezsen motor sıfır filtre uygular ve havuzun tamamını kullanır. Bu bir eksiklik değil, kasıtlı varsayılandır — ama gerçekten bir kısıtın varsa ve yazmadıysan plan onu bilemez.
Beslenme planı kurulumu (diyet tipi, maliyet standardı, sevmediğin gıdalar)
Girersen Haftalık öğün planı senin ulaşabildiğin ve yiyeceğin gıdalardan kurulur; kaydettiğinde o haftanın planı yeniden üretilmek üzere düşürülür.
Girmezsen Üç alanın üçü de açıkça seçilene kadar plan üretimi kapalı kalır. Kasıtlı bir karar: seçilmemiş bir alanı sessizce "normal beslenme" saymak, vejetaryen bir kullanıcıya et içeren plan üretmek demekti.
Verilerin güncelliği (ne zaman dokunduğun)
Girersen Hazırlık yüzdeleri yüksek kalır ve profilin üstünde uyarı çıkmaz.
Girmezsen Veri eskidikçe sunucu önce hazırlık yüzdesini düşürür, sonra profilin üstüne bir uyarı kutusu koyar. Plan üretilmeye devam eder ama eski ölçüyle üretilir; uyarı tam olarak bunu görmen içindir.
Hatırlatıcı saatleri
Girersen Antrenman saatinden 30 dakika, öğünden 15 dakika önce ve tam saatinde bildirim alırsın.
Girmezsen Hiç hatırlatıcı kurmazsan uygulama sana kendiliğinden antrenman veya öğün bildirimi göndermez. Haftalık rapor bundan bağımsızdır ve varsayılan olarak açıktır.