Notları, projeleri, görevleri, toplantıları ve yapay zekâyı tek yerde birleştiren; çevrimdışı çalışan, web, masaüstü ve Android için geliştirdiğim üretkenlik uygulaması.
Tek kişilik full-stack proje: ürün tasarımı, frontend, backend, DevOps ve mobil uygulama geliştirme.
Web + masaüstü + AndroidMasaüstü v1.7.6 yayındaAndroid v1.0.0 · Kapalı test
Notları ayrı belgeler olarak bırakmak yerine [[wikilink]] bağlantılarıyla birbirine bağladım. Yazılan başlık henüz yoksa yeni not oluşturulup bağlantı kuruluyor; backlink ve giden bağlantılar bağlamı görünür tutuyor.
Gerçek ürün ekranı: bağlantılı not kümesi, AI önerileri ve ağın büyümesini gösteren zaman tüneli.
Canvas tabanlı kuvvet-yönlendirmeli grafta renk bağlantılı kümeyi, düğüm boyutu bağlantı sayısını gösteriyor. Akan parçacıklar, zaman tüneli, sürükleyerek bağlama, kalıcı düzen ve öksüz not filtresi ağın keşfini destekliyor. Her notun altında iki adımlık komşuluk grafı da bulunuyor.
MCP: Claude’u notlara bağlamak
Notları bir AI sohbetine tekrar tekrar taşımak yerine Artiboard’u Model Context Protocol sunucusu olarak dış istemcilere açtım. Claude ve uyumlu istemciler, kullanıcının yetkisiyle not ve panoları okuyup düzenleyebiliyor.
Claude veya uyumlu AI istemcisi
Artiboard verisiyle çalışmak isteyen harici istemci.
Yerel: stdio + API anahtarı
Alternatif uzak yol: kullanıcı onayıyla OAuth 2.1 + PKCE.
Artiboard MCP sunucusu
Not ve pano okuma / düzenleme için 32 araç.
Mimari akış: iki bağlantı yolu, kullanıcıya ait aynı not ve pano araçları.
32 araç, iki bağlantı yolu: yerelde API anahtarıyla stdio; uzakta OAuth 2.1 + PKCE. Harici AI erişimi, kullanıcının açık onayından geçiyor.
AI not-ajanı ve yazım asistanı
Yazım asistanı özetleme, çeviri, genişletme, dil bilgisi düzeltme, fikir ve görev önerileri sunuyor. Çok adımlı not düzenlemelerini ise önce planlayan, onaydan sonra uygulayan ve geri alabilen ayrı bir ajan akışına taşıdım.
Not editörü: bağlantılı içerik, not bazında AI erişimi kontrolü ve yazım asistanına giriş.
Groq üzerinde llama-3.3-70b kullanılıyor; model bana ait değil. Ajan onaysız değişiklik yapmıyor. Geri alma, silinen içeriği çöp kutusunda tutan yumuşak silme yaklaşımını kullanıyor.
Bağlantı kesilince durmayan çalışma
Not, görev ve pano oluşturma veya düzenleme işlemlerini bağlantıya bağımlı bırakmadım. Çevrimdışı değişiklikler kuyruğa alınıyor; internet geri geldiğinde bağımlılık sırasına göre sunucuya aktarılıyor.
Kuyruğun taşıdığı çalışma alanlarından biri: pano, sütun ve görev hiyerarşisi.
Aynı işlem yeniden gönderildiğinde ikinci bir kayıt üretmeyen idempotent senkron, geçici ağ sorunlarını kullanıcı verisinden ayrı ele alıyor.
Android’de ayrı, yerel bir deneyim
Web arayüzünü telefona sığdırmak yerine React Native ve Expo ile ayrı bir mobil uygulama geliştirdim. Ortak API ve tip katmanını kullanırken ekranları mobil etkileşimlere göre ele aldım.
Android ekran kaydı: not düğümleri, aralarındaki bağlantılar ve kesikli AI önerileri. Ses içermeyen kayıt; oynatmayı sen başlatırsın.
Android v1.0.0, Google Play kapalı testinde. Henüz herkese açık mağaza yayını veya iOS sürümü yok.
Başlıktan değil, anlamdan arama
Bir notu bulmak için tam başlığını hatırlamak gerekmemeli. İçeriği kendi sunucumda çalışan transformer ile vektöre dönüştürüp pgvector üzerinden anlamsal arama ve ilgili not önerileri oluşturdum.
Not içeriği
İçerik uzunluğu eşiğiyle boş notların ürettiği gürültü elenir.
Yerel transformer → 384 boyutlu vektör
Transformers.js + all-MiniLM-L6-v2; harici AI API çağrısı yok.
pgvector → arama ve bağlantı önerileri
Not sahibinin verisi üzerinde anlamsal yakınlık hesaplanır.
Anlamsal katmanın veri akışı; embedding modeli kendi sunucumda çalışıyor.
Graftaki kesikli hayalet bağlantılar, henüz bağlanmamış anlamsal komşuları öneriyor; kullanıcı tıkladığında gerçek wikilink’e dönüşüyor. Embedding üretimi için üçüncü taraf AI çağrısı yapılmıyor.
Video toplantıdan özete ve aksiyonlara
LiveKit görüntülü toplantı akışını, toplantı sonrası transkript ve özetle birleştirdim. Kararlar ve aksiyon maddeleri, görev çalışmasının devam edebileceği aynı ürün içinde kalıyor.
LiveKit görüşmesi
Ürün içindeki görüntülü toplantı.
İstemci tarafında kayıt
Transkripsiyon için ses Groq’a gönderilir.
Transkript → özet ve aksiyonlar
whisper-large-v3 + llama-3.3-70b.
Toplantı işleme akışı; kayıt sunucuda değil, istemci tarafında alınıyor.
Kayıt istemci tarafında alınıyor. Transkripsiyon whisper-large-v3, analiz llama-3.3-70b ile Groq üzerinde çalışıyor; bu işlemde ses ve ilgili içerik dış servise aktarılıyor.
Aynı ürünün içinde
Dashboard: notlar, görevler, favoriler ve yaklaşan işler için ortak başlangıç ekranı.
Notlar ve görsel düşünme
TipTap: başlık, liste, kontrol listesi, alıntı, tablo ve görsel; PDF, kapak ve ikon.
Excalidraw ve tldraw beyaz tahtaları; wikilink, graf, favoriler, herkese açık paylaşım ve çöp kutusundan geri yükleme.
AI-kilit ile not bazında AI erişimini kapatma.
Projeler ve görevler
Paylaşılan panolar, sütunlar ve sürükle-bırak görevler; pano üyeleri, atananlar ve yorumlar.
Öncelik, son tarih ve etiketler; görevlerde kanban ve takvim görünümü.
Günlük çalışma
Pomodoro oturum takibi ve kişiler.
Dashboard’da notlar, görevler, favoriler ve yaklaşan işler; başlık ve semantik arama.
İşbirliği ve iletişim
Socket.io ile gerçek zamanlı senkron; P2P anlık aramalar, pano sohbeti ve DM kanalları.
Arkadaşlık, bildirimler, çevrimiçi durum; LiveKit toplantıları, AI transkript ve özet.
AI ve dış istemciler
Yazım asistanı, sohbet, fikir ve görev önerileri; planlama, onay ve geri alma akışına sahip not-ajanı.
Yerel veya uzak bağlantıyla 32 araç sunan MCP sunucusu.
Hesap ve ürün işletimi
Supabase Auth, MFA/TOTP, RLS ve oran sınırlama.
Varsayılan Türkçe ve İngilizce; Free / Starter / Pro planları, 7 günlük deneme ve Lemon Squeezy abonelikleri.
Ortak TypeScript çekirdeği, üç platform
Paylaşılan katman API ve tip sözleşmeleri. Web ile Electron aynı web tabanını kullanıyor; Android arayüzü React Native ile ayrı geliştiriliyor. Ortak çekirdek, her ekranın aynı kod olduğu anlamına gelmiyor.
TypeScript · Paylaşılan API ve tip katmanı
NestJS + Prisma + PostgreSQL backend
Web
Tarayıcıdan erişim
React SPA · Vite · nginx
Web istemcisi, ortak API sözleşmeleri üzerinden aynı backend ile çalışıyor.
Masaüstü
Windows / macOS / Linux · v1.7.6
Electron 30 · electron-updater
Web tabanını masaüstüne taşıyan uygulama, sürüm yayınlama ve otomatik güncelleme akışına bağlı.
Android
v1.0.0 · Google Play kapalı testi
React Native · Expo
Paylaşılan API ve tip katmanı üzerinde ayrı native ekranlar. Henüz iOS sürümü bulunmuyor.
NestJS, Prisma ORM, PostgreSQL, PgBouncer, Socket.io, class-validator ve pgvector.
AI ve servisler
Transformers.js (@xenova/transformers), all-MiniLM-L6-v2; Groq, LiveKit, Supabase Auth / DB / Realtime / Storage ve Lemon Squeezy.
Masaüstü ve mobil
Electron 30, electron-updater, React Native ve Expo.
Yayın ve operasyon
Docker, nginx, GitHub Actions CI, gitleaks, Dependabot, husky ve Sentry; tag → build → otomatik güncelleme akışı.
Problem · Karar · Taviz
Çözülen mühendislik zorlukları
Araçları bir araya getirmekten daha zor olan; bağlantı kesildiğinde, bir olay tekrarlandığında veya AI yanlış bir araç çağrısı yaptığında ne olacağını tasarlamaktı.
01Aynı çevrimdışı işlemi iki kez uygulamamak
Karşılaştığım sorun
Bağlantı koptuğunda bir yazmanın sunucuya ulaşıp ulaşmadığı belirsizleşebiliyor. Tekrar denemek mükerrer kayıt, yanlış sırada göndermek ise henüz oluşmamış bir panoya bağlı görev üretebiliyor.
Seçtiğim çözüm
İşlemleri UUID v4 kimlikleriyle idempotent hale getirip pano → sütun → görev sırasıyla oynatan kuyruk kullandım. Kalıcı 4xx hataları aktif tekrar kuyruğundan çıkarılıyor; ağ ve 5xx hataları yeniden deneniyor. Beş deneme sonunda başarısız işlem silinmek yerine dead-letter alanında saklanıyor.
Taviz ve sınır
Sonsuz tekrar yerine sınırlı deneme seçtim. Bağlantının gelmesi, bütün işlemlerin hemen başarılı olduğu anlamına gelmiyor; başarısız kayıtlar ayrıca ele alınabiliyor.
02Harici AI erişimini açık onaya bağlamak
Karşılaştığım sorun
Bir AI istemcisine okuma ve düzenleme araçları sunmak, kullanıcı hesabı üzerinde işlem yetkisi vermek demek. Bağlantı kurmayı kolaylaştırırken erişim sınırını da korumak gerekiyordu.
Seçtiğim çözüm
Uzak MCP bağlantısında OAuth 2.1 + PKCE ve kullanıcı onayı kullandım. Redirect URI yalnızca izin listesindeki adresle birebir eşleştiğinde kabul ediliyor. Yerel kullanım için API anahtarıyla stdio bağlantısını ayrı tuttum.
Taviz ve sınır
Tek tıkla sınırsız erişim yerine belirgin bir yetkilendirme adımı var. Yerel ve uzak istemcilerin bağlantı gereksinimleri ayrı yönetiliyor.
03Tek kullanıcıda doğru görünen vektör sorgusunu düzeltmek
Karşılaştığım sorun
İlk sorguda global HNSW komşuları bulunduktan sonra sahiplik filtresi uygulanıyordu. Diğer kullanıcıların verisi arttıkça adaylar eleniyor, sonuçlar seyrekleşiyordu. Aynı başlıklı boş notlar da birbirine çok benzer öneriler üretiyordu.
Seçtiğim çözüm
MATERIALIZED CTE ile önce not sahibini süzüp ardından bu kümede tam benzerlik sıralaması yaptım; sorgu planını EXPLAIN ile doğruladım. İçerik uzunluğu eşiğinin altındaki notları öneri havuzundan çıkardım. Vektörler, sunucuda all-MiniLM-L6-v2 ile 384 boyutta üretilip pgvector’da saklanıyor.
Taviz ve sınır
Global yaklaşık indeksin hız avantajından vazgeçip kullanıcıya ait sonuçların doğruluğunu seçtim. İçerik eşiği, kısa ama anlamlı bazı notları da dışarıda bırakabiliyor.
04Ajan araçlarını modelin gerçekten kullanabildiği hale getirmek
Karşılaştığım sorun
llama-3.3-70b, araç çağrıları arasında not UUID’lerini taşırken yer tutucular ve geçersiz kimlikler gönderebiliyordu. Teknik olarak doğru bir araç sözleşmesi, model için güvenilir bir arayüz değildi.
Seçtiğim çözüm
Not-ajanının araçlarını kimlik yerine başlık alacak şekilde yeniden tasarladım. Çok adımlı değişiklikleri plan → kullanıcı onayı → uygulama → geri alma akışına bağladım.
Taviz ve sınır
Kontrolsüz otomasyon yerine kullanıcı denetimini seçtim. Bu onay akışı uygulama içi not-ajanına aittir; harici MCP istemcisinin yetkilendirmesi ayrı yürür.
05Üç platformu tek arayüze zorlamadan ortaklaştırmak
Karşılaştığım sorun
Web, masaüstü ve mobil için her veri sözleşmesini ayrı tutmak değişiklikleri çoğaltıyor; aynı arayüzü her platforma taşımak ise etkileşim farklarını göz ardı ediyor.
Seçtiğim çözüm
Ortak TypeScript çekirdeğinde API ve tip katmanını paylaştım. Web ve Electron aynı web tabanını kullanırken Android için React Native / Expo ekranlarını ayrı geliştirdim.
Taviz ve sınır
Paylaşılan çekirdek, bütün UI kodunun ortak olduğu anlamına gelmiyor. Native mobil deneyim karşılığında platforma özel ekran ve yayın sorumluluğunu korudum.
06Olayları doğru kullanıcıya ve doğru panoya ulaştırmak
Karşılaştığım sorun
Not, pano ve mesaj olaylarını aynı kanaldan yayınlamak, ilgili olmayan istemcileri de güncellemeye zorlayabiliyor. Bağlantının açık olması tek başına kullanıcının hâlâ çevrimiçi olduğunu göstermiyor.
Seçtiğim çözüm
Socket.io iletişimini user:, board: ve dm: odalarıyla ayırdım. Çevrimiçi durum için heartbeat presence kullandım; iletişim kanallarını kullanıcı, pano ve doğrudan mesaj bağlamına göre düzenledim.
Taviz ve sınır
Tek yayın kanalı yerine oda üyeliklerini ve bağlantı yaşam döngüsünü yönetmek gerekiyor. Presence bilgisinin güncelliği de heartbeat akışına bağlı.
07Tekrarlanan ödeme bildirimini ikinci kez işlememek
Karşılaştığım sorun
Ödeme webhook’ları tekrar teslim edilebiliyor. Her teslimi yeni bir olay gibi ele almak abonelik durumunu yeniden veya yanlış biçimde değiştirebiliyor.
Seçtiğim çözüm
Lemon Squeezy webhook’larında event-id üzerinden tekrarları ayıklayan idempotent işleme kurdum. Abonelik modelini iki sağlayıcıyı desteklemeye hazır tasarladım; kullanılan ödeme servisi Lemon Squeezy, Merchant of Record rolünü üstleniyor.
Taviz ve sınır
İkinci sağlayıcıya hazır model, iki sağlayıcının bugün aktif olduğu iddiası değil. Esneklik karşılığında olay kayıtlarını ve sağlayıcı eşlemelerini yönetiyorum.
08Güvenliği tek bir kontrol noktasına bırakmamak
Karşılaştığım sorun
Çok kiracılı veride erişim sınırları, API girdileri ve yayın sırasında açığa çıkabilecek sırlar farklı riskler oluşturuyor; yalnızca oturum açma bunların hepsini karşılamıyor.
Seçtiğim çözüm
RLS, Supabase Auth, MFA/TOTP ve oran sınırlamayı; beklenmeyen alanları reddeden forbidNonWhitelisted ValidationPipe ile birleştirdim. Her push’ta gitleaks sır taraması, Dependabot ve pre-commit kontrollerini yayın sürecine ekledim.
Taviz ve sınır
Daha sıkı doğrulama istemci sözleşmelerini güncel tutmayı gerektiriyor. Bu kontroller riski azaltan katmanlar; hatasızlık veya mutlak güvenlik garantisi değil.
Hangi AI işlemi nerede çalışıyor?
Gizlilik sınırı özelliğe göre değişiyor. Yerel anlamsal model, Groq servisleri ve harici MCP istemcisi aynı veri akışını kullanmıyor.
Semantik arama ve hayalet bağlantılarKendi sunucum
Transformers.js / all-MiniLM-L6-v2 ile embedding üretimi. Bu işlem için not içeriği üçüncü taraf AI servisine gönderilmiyor.
Yazım asistanı ve not-ajanıGroq · llama-3.3-70b
İşlem için kullanılan ilgili not içeriği Groq’a iletiliyor. Not-ajanı değişiklikleri kullanıcı onayından sonra uyguluyor.
Toplantı transkripti ve analiziİstemci kaydı → Groq
Kayıt istemci tarafında alınıyor. Ses whisper-large-v3 ile transkripte, toplantı içeriği llama-3.3-70b ile özete dönüştürülüyor.
MCP üzerinden harici AIYetkilendirilen AI istemcisi
İzin verilen not ve pano içeriği bağlı istemciye açılıyor. MCP erişimi, yerel embedding işlemiyle aynı veri sınırına sahip değil.
Bilgi grafı ve wikilink’ler Starter’da; anlamsal arama, AI bağlantı önerileri, yazım asistanı, not-ajanı ve toplantı analizi Pro planında. Not bazındaki AI-kilit, AI erişimini ayrıca kapatabiliyor.