İçeriğe atla
openplate

Uygulama

Mimari

Üç program ve besin veritabanı, her birinin ne içerdiği ve birlikte nasıl çalıştıkları

Bu sayfa, İngilizce belgeden makine çevirisiyle çevrildi.

Üç program, bir ürün ve iki isteğe bağlı eklenti, ayrıca yemek adlarını yanıtlayan bir dış servis. Bu sayfa her birinin ne tuttuğunu ve hangisinin verilerinin yolu üzerinde durduğunu açıklar.

Aşağıdaki çizim beş okla tüm sistemi gösterir. Cihazın günlüğü ve tabak fotoğrafını tutar. Günlük şifrelenmiş olarak openplate-core için çıkar. Fotoğraf, yapılandırdığın yapay zeka uç noktası hangisiyse oraya gider. Uygulama sunucusu sayfayı gönderir ve aradığın yemeklerin adlarını bir besin veritabanına iletir. Sunucu ne günlüğün ne de fotoğrafın yolu üzerinde durur.

Cihaz günlüğü ve fotoğrafı tutar. Günlük şifrelenmiş olarak openplate-core için çıkar, fotoğraf yapılandırdığın yapay zeka uç noktasına gider ve yemek adları uygulama sunucusu üzerinden besin veritabanına iletilir.
Diyagram kaynağı
flowchart LR
  app["openplate app server"] -->|"the page"| device["Your device"]
  device -->|"diary, encrypted"| sync["openplate-core"]
  device -->|"photo"| ai["Your AI endpoint"]
  device -->|"food names"| app
  app -->|"food names"| fooddb["LowCarbCheck food database"]

"Yapay zeka uç noktanız" arkasına üç şey sığar: anahtarına sahip olduğun bir bulut sağlayıcı, kendi donanımındaki bir openplate-inference kutusu veya yönetilen bir kurulumda, fotoğrafı ileten ve bunu kotana sayan çekirdek sunucunun kendisi. topologies.md, openplate'i çalıştırmanın dört yolunun tamamını, her biri için küçük bir resimle çizer.

Ürün istemcidir

Bir kullanıcının sahip olduğu her şey (yemek kayıtları, kilolar, kişisel yiyecekler, hedefler, yapay zeka ayarları) girildiği cihazdaki tarayıcının IndexedDB alanına yazılır (app/lib/local-store/). Orada şifresiz tutulur, çünkü bu senin cihazındır ve seçtiğin iki biçim dışında oradan asla ayrılmaz: indirdiğin bir JSON dışa aktarımı ya da şifreli bir eşitleme blobu.

Uygulama sunucusu durumsuz tek bir konteynerdir. Veritabanı yok, ORM yok, migrasyon yok ve başlamak için ihtiyaç duyduğu hiçbir gizli bilgi yok. aşağıda içinde açıklanan, besin veritabanı için yöneticinin anahtarı olan isteğe bağlı tam bir gizli bilgiyi tutabilir. Konteyneri silmek hiçbir şey kaybettirmez. Bu bir tasarruf değil, vaadin ta kendisidir: bakınız ADR-0006.

Eşitleme kimliktir, fotoğraf yolunun yanındadır ve asla içinde yer almaz

openplate-core bir günlüğü cihazlar arasında taşır. openplate içinde hesapları tutan tek hizmettir. Kendi imajı, veritabanı ve sırrı olan ayrı bir dağıtılabilir birimdir ve tarayıcı onunla doğrudan konuşur. Uygulama sunucusu onun adına hiçbir şeyi vekil olarak iletmez ve hiçbir eşitleme rotasına hizmet vermez.

Günlük, cihazdan çıkmadan önce şifrelenir. İstemci yerel depoyu serileştirir, gzip ile sıkıştırır, rastgele bir veri anahtarıyla AES-256-GCM kullanarak şifreler ve sonucu tek bir opak ikili veri bloğu olarak yükler. Veri anahtarı, parolandan türetilen bir anahtarla sarmalanır: parola Argon2id ile uzatılır ve HKDF ile bağımsız dallara bölünür. Bunlardan ikisi cihazda kalır ve sana ait olanın sarmalamasını çözer, üçüncüsü ise oturum açma kimlik bilgisi olarak gönderilir. Bunlar ebeveyn ve çocuk değil kardeştir, bu nedenle kimlik bilgisine sahip olmak anahtar hakkında hiçbir şey ortaya çıkarmaz.

İşletmeci bir kurtarma anahtarı tutar. Kayıt sırasında uygulama bir kurtarma kodu oluşturur ve veri anahtarını bununla sarmalar. Kodu openplate-core servisine gönderir, o da kodu kendi gizli anahtarıyla kilitler. Postayla gelen parola sıfırlamasının boş bir hesap yerine günlüğünü geri getirmesini sağlayan şey budur. Bu durum aynı zamanda bir örneğin yöneticisinin o örnekteki bir günlüğü geri yükleyebileceği ve prensipte okuyabileceği anlamına gelir. Kendi barındırdığın bir örnekte o yönetici sensin. sync.md bu dengeyi eksiksiz açıklar.

Sunucunun şifreli metin dışında ne gördüğü PROTOCOL.md §9 içinde açıkça belirtilmiştir: bir e-posta adresi, ikili veri boyutu, yazma sıklığı ile zamanlaması, sürüm numaraları ve KDF parametreleri.

İsteğe bağlı araştırma konsolu, aynı sunucuda kendine ait ayrı hesaplar tutar. Ne zaman açık olduğunu Eşitleme, uygulamada neden yer aldığını ise ADR-0008 açıklar.

Çıkarım hesaplamadır ve fotoğraf doğrudan ona gider

Bir tabak fotoğrafı tarayıcıda okunur ve yapılandırdığın OpenAI uyumlu uç nokta hangisiyse doğrudan oraya gönderilir. openplate sunucusu bu istekte asla yer almaz. Buraya yüklenmez, diske yazılmaz, günlüğe kaydedilmez. Yalnızca ortaya çıkan sayılar cihazın yerel deposuna kaydedilir; fotoğraf onu çeken cihazda kalır, JSON dışa aktarımlarından da eşitleme yüklerinden de hariç tutulur.

Bu uç nokta ya ödemesini yaptığın bir bulut sağlayıcısıdır (BYOK yolu) ya da kendi openplate-inference kapsayıcındır. Kendi barındırdığın senaryoda model tabaktaki yiyecekleri adlandırır ve gramajları tahmin eder, ardından makrolar uydurulmaz, aranıp bulunur: karbonhidrat, protein, yağ ve kcal, yapılandırılmış yiyecek kaynağına göre ada bakılarak çözümlenir; bu varsayılan olarak USDA FoodData Central'ın paketlenmiş bir özetidir (imaj içinde gelen 8.041 genel yiyecek, ağ çağrısı yok, kamu malı). Dil modeli hiçbir zaman bir makro sayısı üretmez.

Bu çağrıyı tarayıcı yaptığı için uç noktanın bir tarayıcının ulaşabileceği bir adres olması gerekir. İki kapsayıcı birbirine bu şekilde ulaşabilse bile http://inference:8300/v1 gibi bir compose ana bilgisayar adı çalışmaz. Ana makinenin yerel ağ adresini, bir tailnet adını veya ters vekil sunucundaki bir ana bilgisayar adını kullan.

Besin veritabanı, uygulama sunucusu üzerinden adla yapılan bir aramadır

Bir bulut modeli veya yönetilen model, bulduğu her yemek için kendi makro tahminini döndürür. Uygulama ardından bu besinleri derlenmiş bir veritabanına karşı kontrol eder. Tarayıcı uygulama sunucusunun /api/food-matches yoluna yalnızca modelin bulduğu adları gönderir. Sunucu her adı LowCarbCheck (FOOD_DB_API_URL) üzerinde arar. Bir eşleşme, onay ekranındaki model tahmininin yerini alabilir. Ekle ekranındaki arama ve Besin ögeleri ekranındaki referans değerleri aynı sunucu taraflı arama üzerinden gelir.

Bu, uygulama sunucusunun üzerinde durduğu tek yoldur ve tasarım gereği dardır:

  • Yemek adlarını, besin öğesi adlarını ve ekran dilini taşır. Asla bir fotoğrafı, asla yapay zeka anahtarını, asla bir günlük girdisini taşımaz.
  • LowCarbCheck uygulama sunucusunun adresini ve örneğin anahtarını görür, senin adresini asla görmez. Bir örnekteki herkes bu anahtarı ve onun kotasını paylaşır.
  • Sunucu yanıtları önbelleğe alır ve yalnızca önbelleği ıskalayan bir arama adres başına hız sınırına dahil edilir.
  • Açık kalarak hata verir. Veritabanına ulaşılamazsa, anahtar reddedilirse veya kota biterse tarama modelin kendi sayılarıyla yine de tamamlanır ve ekran bunu belirtir.
  • FOOD_DB_API_URL="" bunu kapatır ve ardından sunucundan hiçbir yemek adı çıkmaz.
  • FOOD_DB_BACKFILL=true ile birlikte önerileri de taşır: Bir kullanıcının yapay zeka yanıtından kaydettiği bir yiyeceğin tüm uygulama dillerindeki adları ve eşleşmeyen yiyecekler için 100 g başına makro değerleri. Kullanıcının yazdığı bir ad, bir fotoğraf veya bir günlük girdisi asla aktarılmaz. Bkz. configuration.md.

Tarayıcıda değil sunucuda çalışır. Bu anahtarı sayfadan uzak tutar ve adların sunucudan çıkıp çıkmayacağına yönetici ayarının karar vermesini sağlar. Anahtar FOOD_DB_API_KEY ayarıdır. Bir anahtar olmadan örnek, LowCarbCheck servisinin anonim katmanını kullanır; configuration.md katmanları listeler.

Çekirdek sunucu çok kullanıcılılığı sağlar ve yönetilen bir kurulumda hesaplama kaynağının önünde yer alır

Bir bulut örneği INSTANCE_MODE=managed ayarlayabilir (bkz. configuration.md). Bu tek bir şeyi bildirir: bir kuruluş bu bulut örneğini çalıştırır, kişilerini e-posta ile davet eder ve her birine günlük bir yapay zeka kotası verir. openplate-core bunu taşıyan bileşendir, eşitleme için zaten tuttuğu hesap aynı zamanda kotayı da tutar, böylece ikinci bir bağlantı adımı ve ikinci bir kimlik bilgisi olmaz.

Tarayıcı için hiçbir şey değişmez: kotası olan oturum açmış bir hesap, openplate-core'un sunduğu yapay zeka vekili üzerinden tarama yapar; bu, istemcinin eşitleme için zaten konuştuğu servisin aynısıdır. Arkasındaki şey içinse openplate-core bir istemcidir: ya bir bulut sağlayıcıya ya da kendi openplate-inference konteynerine işaret eder. Çıkarım hesaplama katmanıdır, openplate-core yönetilen bir bulut örneğindeki çoklu kiracılık katmanıdır ve birlikte çalışırlar: çekirdek sunucu hiçbir model barındırmaz ve taramaları kendisi yanıtlamaz.

Fotoğraf yolundadır, dürüst maliyeti de budur. Önlem ise bir ayar değil, kodun kendi özelliğidir: günlükleyicinin alan türü yalnızca ilkel değerleri kabul eder, bu nedenle bir gövde asla günlük satırına ulaşamaz ve üst sunucu hata dizgeleri günlüğe kaydedilmeden veya döndürülmeden önce temizlenir. Bir organizasyonun üyeleri veriyi değil, harcamayı paylaşır; vekil sunucuya ulaşan bir tabak fotoğrafı bir kez okunur ve saklanmaz.

Kota para birimini değil istekleri sayar. Bir yönetici tüm örneği günlük olarak da sınırlayabilir (AI_INSTANCE_DAILY_LIMIT) ve sağlayıcıdaki üst anahtarda harcama sınırı yine de gereklidir.

Bir yönetici örneği uygulamadaki /admin üzerinden çalıştırır: kişiler ve kotaları, davetler, etkinlik, bildirilen tahminler ve Besin ögeleri ekranının hangi referans değerlerini alıntıladığı.

Geçmiş

Ağustos - Eylül 2026 arasında bu, openplate-gateway adında ayrı bir servisti: tek bir üst anahtarı tutan ve her üyeye kendi günlük kotasına sahip bir opk_… belirteci veren, OpenAI uyumlu küçük bir vekil sunucuydu. M192 (Eylül 2026) bunu openplate-core içine birleştirdi: artık tek bir hesap hem günlüğü hem de kotayı taşır; böylece ikinci bir servis, ikinci bir davet bağlantısı ve dağıtılacak ikinci bir kimlik bilgisi kalmamıştır.

openplate-core başka neler taşıyabilir

Aşağıdaki her özellik varsayılan olarak kapalıdır ve her biri sunucunun tuttuklarını değiştirir. openplate-core deposunun README belgesi her birini açıklar.

  • Bir günlüğü uzmanla paylaşma (SYNC_SHARING=true). Sahip, veri anahtarını üçüncü kez, uzmanın genel anahtarıyla sarmalar ve sunucu bu sarmalanmış anahtarı saklar. Uzmanın tarayıcısı bunun sarmalamasını çözer ve günlüğü /shared adresinde okur. Paylaşım sunucuya açabileceği yeni hiçbir şey vermez.
  • Araştırma katkıları (SYNC_RESEARCH=true). Kişi bir bağlantı üzerinden araştırmaya kaydolur ve bir takma ad altında günlük toplamları gönderir. Toplamlar araştırma için mühürlenir, ancak sunucu hangi hesabın hangi araştırmaya katkı sağladığını öğrenir.
  • Bildirilen tahminler (SYNC_FEEDBACK=true). "Hatalı tahmini bildir", fotoğrafı, sayıları ve bir onay kaydını sunucuya gönderir, yönetici bunları /admin adresinde inceler. Taramanın aksine bu fotoğraf saklanır.
  • Nabız operatör ayarı gerektirmez: her kişi bunu Ayarlar, Paylaşım altından açar. Yuvarlanmış sayıları gönderir. Bir öğün, kalorisi 50'ye ve proteini 5 g'a yuvarlanarak bir kez sayılır. Bir tarama bir kez sayılır ve devam eden bir açlık bir sinyal gönderir. Ana ekran bugünün örnek toplamını gösterir. Sunucu, günlük toplamları ve her gün kimin katkıda bulunduğunun kaydını 30 gün boyunca tutar.
  • Push bildirimleri (VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, VAPID_SUBJECT). Sunucu cihaz başına bir abonelik saklar: tarayıcının push adresi ile anahtarları, bir saat dilimi, bir dil ve hatırlatıcı ayarları. Her cihaza günde en fazla iki bildirim gönderir ve her bildirim sadece türünü taşır, seninle ilgili asla metin içermez. Bildirimi tarayıcının push servisi iletir.
  • Ücretli planlar (PLANS_UPSTREAM_URL, PLANS_UPSTREAM_SECRET). openplate-core, /v1/plans/* bilgisini hesap kimliği ve e-posta adresiyle birlikte operatörün çalıştırdığı bir planlar servisine iletir. Uygulama Ayarlar, Plan seçeneğini yalnızca sunucu planların açık olduğunu söylediğinde gösterir.

BYOK sıfır sunuculu yoldur

Ortada hiçbir çıkarım konteyneri olmadan tarayıcı, o cihaza girdiğin anahtarla doğrudan bir bulut sağlayıcısını çağırır. Anahtar cihazın yerel deposunda saklanır, JSON dışa aktarımına dahil edilmez ve openplate sunucusuna asla gönderilmez: şifreli veya başka türlü hiçbir sunucu taraflı kopyası ve çağrının sunucu taraflı bir vekil iletimi yoktur.

Üretim ortamındaki Content-Security-Policy bir süs değil, bu sözün bir parçasıdır: connect-src izin verilenler listesi sağlayıcı kayıt defterinden türetilir ve sayfada bulunan bir anahtarın, araya sızan bir betik tarafından dışarı sızdırılmasını engelleyen de tam olarak budur. Bkz. configuration.md.

Kimin elinde ne var

BileşenNe saklarAktarım sırasında ne görür
TarayıcınTüm günlüğü, açık halde, IndexedDB içinde. Yapay zeka anahtarını. Önbelleğe alınmış tabak fotoğraflarını.Her şeyi. Cihaz senin.
openplate uygulama sunucusuVeritabanı yok, hesap yok, günlük yok. En fazla bir gizli bilgi: operatörün gıda veritabanı için olan anahtarı.Sayfa istekleri ve aradığın veya taradığın gıdaların adları; bunları gıda veritabanına iletir. Asla bir fotoğraf, asla AI anahtarın, asla bir günlük kaydı, asla bir eşitleme blobu değil.
openplate-core (isteğe bağlı)Bir e-posta adresi, bir kimlik doğrulama doğrulayıcısı, KDF parametreleri, şifreli metin olarak günlük ve bunu açabilen emanetteki kurtarma kodu. Yönetilen bir örnekte ayrıca her hesabın günlük kotası ve kullanım sayısı. Yukarıdaki özellikler açıldığında, ayrıca her birinin listelediği veriler.Blob boyutu, yazma zamanlaması, oturum metaverileri. Yönetilen bir örnekte ayrıca AI vekil sunucusuna iletilen fotoğraf; yalnızca iletilmesi için gereken süre boyunca, bir kez okunur, saklanmaz.
openplate-inference (isteğe bağlı)Kullanıcı başına hiçbir şey: hesaplar yok, oturumlar yok, çerezler yok. Model ağırlıkları ve bir besin veri kümesi.İstek sürdüğü müddetçe, ona gönderdiğin fotoğraf. Varsayılan gıda kaynağıyla, tek seferlik ağırlık indirme işlemi dışında hiçbir dış çağrı yapmaz. FOOD_SOURCE=lcc veya off ile dışarıya gıda adlarını gönderir, asla fotoğrafı göndermez.
LowCarbCheck besin veritabanı (kapatılmadığı sürece açık)Anahtar başına bir kullanım sayısı veya anahtarı olmayan bir çağıran için ağ adresi başına bir kullanım sayısı.Uygulama sunucusundan, örneğin anahtarıyla birlikte gıda adları ve bir dil. Asla bir fotoğraf ve asla kim olduğun değil.
Bulut yapay zeka sağlayıcısı (BYOK yolu)Kendi ilkeleri ne diyorsa onu.Fotoğrafı ve anahtarını. Bizim değil, onların koşulları geçerlidir.

Bu sayfayı GitHub üzerinde düzenle