Kategori: Yazılım Geliştirme

  • Yaz Kızım: 24 Günde 356 Commit – Cursor ile Kodlama Deneyimim

    Geçtiğimiz günlerde “Yapay Zekada Bu Hafta” programında Timur Akkurt’un Cursor için yaptığı “yaz kızım” esprisi, tam olarak hissettiklerimi özetliyor.

    Tanışma: Zorunluluktan Doğan Değişim

    Cursor ile ilk commitimi atmamın üzerinden 24 gün geçti ve toplamda 356 commit biriktirmişim. Cursor’la tanışmam aslında biraz zorunluluktan oldu. İlk kez Selman Kahya’nın canlı yayınında isometrik bir oyun geliştirirken görmüştüm. O sırada detaylı bakmadım ama aklımın bir köşesinde kaldı.

    Prompt: Sin City style, comic book black and white inked illustration of a developer watching a live code stream on a laptop, isometric game preview on screen, minimalist setup, cinematic wide shot, high contrast lighting, anonymous figure, square jaw silhouette

    Kısa süre sonra, uzun zamandır kullandığım ve destek ekibinden memnun olmadığım e-ticaret altyapı sağlayıcı firmada bardağı taşıran birkaç olay yaşadım. Sonunda altyapıyı değiştirmeye karar verdim. Shopify’a da bakıyordum ama sezon başında köklü bir geçiş yapmak gerçekçi değildi. Mantıklı davranıp, sezon sonunda bu işi halletmeye karar vermiştim. Ancak üst üste bir iki olumsuz deneyim yaşayınca, sabrım taştı.

    “En basit problemimi bile 10 günde çözemeyen bir destek ortamında, ben kendi altyapımı kendim yazarım.”

    Kodun Başına Dönüş ve Cursor’la İlk Temas

    Daha önce Laravel ile birkaç proje geliştirmiştim. Şirketimin üretim takip sistemini de Laravel ile yazmıştım. Uzun zamandır ise sadece mevcut sistemleri ayakta tutacak kadar kod yazıyordum. Şimdi sıfırdan ve zaman baskısı altında bir projeye başlıyordum. AI tabanlı araçları farklı alanlarda takip ettiğim için kod tarafında işimi kolaylaştıracak bir şey aradım ve Cursor’u denemeye karar verdim.

    Prompt: anonymous developer seated at ultrawide screen in a dark room, code and Laravel logo glowing on monitors, inking style of a graphic novel, noir tones, bold shadows, Sin City inspired lighting and framing, moody, cinematic

    ChatGPT ile Tasarım, Cursor ile Kodlama

    İlk iş olarak ChatGPT ile uzun bir sohbet ettim:

    • İş modelimi, sipariş tiplerini, stok senaryolarını modül modül anlattım.
    • Modüllerin birbirleriyle nasıl etkileşeceğini, veri tabanı mimarisini planladık.

    Prompt: over-the-shoulder shot of a silhouetted developer having a conversation with an AI interface, database flowcharts on side screen, black and white Sin City aesthetic, bold comic shadows, cinematic composition, graphic novel lighting, moody, digital noir

    ChatGPT bana çok iyi bir veritabanı mimarisi çıkardı. Projeye başladığımda, orijinal kurgudan çok az sapmıştım.

    İlk Geceler: Hız ve Etki

    Selman Kahya’nın videosundan programın adına tekrar bakıp Cursor’u kurdum. Development environment’ı hazırlayıp Laravel’in son sürümünü kurdum. User login, admin rotaları ve kullanıcı yönetimi ekranlarını ilk gece tamamladım.

    Çalışırken klasik editörlerden farklı bir şeyle karşı karşıya olduğumu hemen hissettim. Bir gecede geliştirme ortamını kurup birkaç temel modülü ayağa kaldırmak bana ciddi bir hız kazandırdı. Cursor ile devam etmeye karar verdim.

    Cursor ve Kod Otomasyonu

    İkinci gün YouTube’da “rules” kavramını öğrendim ve hazır rule dosyalarını indirdim, Cursor’u çok daha iyi konfigüre etmeye başladım. Komut hatalarını azalttım, .env dosyası sorunlarını çözdüm.

    Her modül öncesi ChatGPT’ye tam olarak ihtiyacımı anlattım, Cursor’a aktardım ve birkaç dakika içinde hatasız, eksiksiz kod çıktı.

    “Kendime bir kural koydum: En ufak değişiklik bile bir commit olacak.”

    Sonuç: Sıfırdan E-Ticaret Projesi ve Cursor’un Getirdikleri

    Projeye genellikle saat 21:00 civarında başlayıp 02:00–03:00 aralığına kadar çalışıyordum. Elimi ya hiç koda sürmüyordum, ya da çok basit değişikleri hızlıca yapmak için kod yazıyordum. Onun dışında sadece neyin yanlış gittiğini Cursor’a anlatıyordum ve benim saatlerce uğraşacağım satır satır kodları bir kaç dakika içinde daha sonradan aklıma gelecek eksik kısımları da düşünerek yazıyordu. Böylece geceleri mesai sonrası ayırdığım zamanda, yaklaşık bir ayda, frontend ve backend dahil tam teşekküllü bir e-ticaret projesi kurdum. Pazaryeri entegrasyonundan stok güncellemesine, hiçbir detayı atlamadım.

    Kapanış

    Benim için Cursor deneyimi, klasik IDE alışkanlıklarını ve kodla ilişkimi değiştiren hızlı ve verimli bir süreç oldu. AI destekli kodlama, yeni nesil yazılımcılar için standarda dönüşüyor.

  • Ubuntu Bluetooth Yeniden Bağlantı Sorunu Çözümü

    Mac ve Ubuntu laptopları aynı anda kullanıyorum. İki bilgisayar arasında kolay geçiş yapabilmek için Logitech’in MX serisi klavye ve mouse kullanıyorum. Ancak zaman zaman MacOS tarafından Ubuntu’ya geçerken geçiş gerçekleşmiyor. Bluetooth’u yeniden başlatmak gerekiyor ancak arayüz kullanarak yeniden başlatamıyorsunuz çünkü Settings çöküyor. Bilgisayarı yeniden başlattığınızda çözüm oluyor ancak her seferinde bilgisayarı yeniden başlatmak istemiyorsunuz.

    Bu sorunu çözmek için bir script paylaşıyorum. sudo olarak çalıştırmanız yeterli. Şahsen ben bt kısa yolu ile .bashrc içerisine de kısa yol oluşturdum. İş akışımda rahatlama sağladı.

    Script’e aşağıdan ulaşabilirsiniz.

    A solution for Ubuntu Bluetooth Connectivity Issues.

    I use Mac and Ubuntu laptops at the same time. To easily switch between the two computers, I use Logitech’s MX series keyboard and mouse. However, sometimes the transition does not occur when switching from MacOS to Ubuntu. Bluetooth needs to be restarted, but you can’t restart it using the interface because Settings crashes. Restarting the computer solves the problem, but you don’t want to restart the computer every time.

    To solve this problem, I’m sharing a script. It’s enough to run it with sudo. Personally, I created a alias in .bashrc with the name ‘bt’. I also saved it as an executable shell file on my desktop. It provided significant relief in my workflow.

    You can find the script above.

  • Certbot www sorunu çözümü

    Certbot ile internet siteniz example.com olarak cevap veriyor ancak www.example.com olarak sertifika hatası veriyorsa bunun çözümü oldukça basit.

    Öncelikle sorunun tespiti için aşağıdaki komutu çalıştırın.

    certbot certificates
    Code language: Shell Session (shell)

    Karşınıza aşağıdaki gibi bir çıktı gelecek.

    Found the following certs: Certificate Name: example.com Domains: example.com Expiry Date: 2022-05-02 18:16:59+00:00 (VALID: 88 days) Certificate Path: /etc/letsencrypt/live/example.com/fullchain.pem Private Key Path: /etc/letsencrypt/live/example.com/privkey.pem
    Code language: Shell Session (shell)

    Burada 3. satırda yer alan Domains: kısmında yer alan şekliyle olan siteniz çalışıyor ve diğer alternatif (bu örnekte www.example.com) çalışmıyor. Şimdi bu sertifikaya www alternatifini de ekleyeceğiz.

    sudo certbot certonly --cert-name example.com -d example.com,www.example.com
    Code language: Shell Session (shell)

    Şimdi size hangi yöntem ile yapacağını soracak.

    How would you like to authenticate with the ACME CA? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: Apache Web Server plugin (apache) 2: Spin up a temporary webserver (standalone) 3: Place files in webroot directory (webroot) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Code language: Shell Session (shell)

    Ben Apache sunucunda olduğum için 1 numarayı seçtim. Son olarak Apache servisini yeniden başlatalım

    sudo service apache2 restart
    Code language: Shell Session (shell)
  • İnternet Sitenizde Gerçekleşen Kullanıcı Eylemlerini Kaydedin

    Eskiden beğendiğimiz şekilde internet siteleri üretiyor ve diğer insanlarında internet sitelerini beğenmesini umuyorduk. Neyse ki o günler geride kaldı. Artık tasarımın nasıl olacağına A/B testleri, ürünlerin hangi sırayla sunulacağına çeşitli kullanıcı hareketleri ve ürün açıklamalarının nasıl yazılacağına arama motorları karar veriyor.

    İnsan bunu içinde derinlerde bir yerlerde her zaman biliyor ama ilk kez uyguladığı zaman aldığı sonuçları gördüğü zaman daha önce neden yapmadım diye soruyor kendine.

    Çoğumuz internet sitemizde olup bitenleri ve dönüşümleri takip etmek için Google Analytics ve Yandex Metrica kullanıyoruz. Ancak Google Analytics 4 sürümü API henüz tamamlanmış değil. Ve bazen bu basit bilgileri kendi backend’imizde kayıt altına almak işleri oldukça hızlandırabiliyor. Bu yüzden internet sitemizde kullanıcıların yaptığı şeyleri GA4 benzeri bir sistem ile nasıl kaydedebileceğinizden bahsetmek istedim.

    Örneğin e-ticaret sitenizde hangi ürünü kaç kez gösteriyorsunuz, gösterdiğiniz ürünler kaç kez seçiliyor, hangi ürünün detay sayfaları daha çok ziyaret ediliyor veya ürünlerin sepete eklenme oranı vs. gibi bilgileri oluştuğu anda kaydedeceğiz. Bir ürünü kaç kez gösterdiğinizi, kaç kez seçildiğini, kaç kez sepete eklendiğini ve kaç kez sattığınızı kaydettiğinizde bu bilgileri kullanarak ürünlerinizin müşteriye sunum sıralamasını değiştirebilir ve dönüşüm oranlarınızı %100’den fazla oranlarda arttırabilirsiniz.

    İş sitede olup bitenleri kaydetmek olunca gidilecek yol sınırsız diyebiliriz. Ancak ben her bir hareket için ayrı table ve row açmaktansa örneği kolayca anlatmak için basit bir mimari oluşturmayı tercih ettim. Siz kendi ihtiyaçlarınıza göre bu mimariyi geliştirebilirsiniz.

    Çok basit bir yapı oluşturacağız. Basitçe şöyle çalışacak. Bir JS Object oluşturacağız ve tıklama, görüntüleme gibi bilgileri bu eylemler oluştuğu anda JS Objectimize Push edeceğiz. Sonrasında bir listener yardımıyla JS Object her Push geldiğinde bir ajax request oluşturacak ve sunucu tarafında bu eventleri kaydedeceğiz.

    Buradaki örnekte tüm takip etmek istediğim eventleri günlük olarak tek bir row’da tutmayı tercih ediyorum. Böylelikle hem son 15 günde hangi eylem kaç kez gerçekleşmiş bilgisini sorgulayabilecek, hemde çok fazla veri tutmak zorunda kalmayacağım. Tabiki siz IP ve kullanıcı verilerini de saklamak isterseniz mimariyi geliştirebilirsiniz.

    Öncelikle içerisine eventleri pushlayacağımız objemizi oluşturalım.

    PP = { eventVariable: '', aListener: function(val) {}, set push(val) { this.eventVariable = val; this.aListener(val); }, get push() { return this.eventVariable; }, registerListener: function(listener) { this.aListener = listener; } }
    Code language: JavaScript (javascript)

    Aslında işimiz bitti. Şimdi bu objenin içerisine her push olduğunda bir ajax request yapacağız ve gerçekleşen eylemi ve parametrelerini kaydetmek için backende göndereceğiz.

    PP.registerListener(function(val) { var request = new XMLHttpRequest(); request.open('POST', '/pp', true); request.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); request.setRequestHeader("x-csrf-token", "{{ csrf_token() }}"); request.send(JSON.stringify(val)); });
    Code language: JavaScript (javascript)

    Örneğin bir ürün detay görüntüleme bilgisini pushlayalım.

    PP.push = { event:"view_detail", items: {{$data->id}} };
    Code language: JavaScript (javascript)

    Bu kod çağırıldığı anda /pp bölümüne bir post request gönderilecek ve event: view_detail ve items değişkenlerini bu bölümde yakalayarak veritabanında ilgili kolona ve bugünün tarihini de işleyerek kaydedeceğiz.

    Aynı şekilde gösterdiğiniz ürünlerin ID’lerini dizi olarak pushlayabilir ve ürünü kaç kez gösterdim bilgisini kayıt altına alabilirsiniz. Veya sepete ekleme formu gönderildiği anda e.preventDefault() benzeri bir yapıyla önce add_to_cart event’ini PP değişkeninize doğru parametreler ile pushlayarak sepete eklenme bilgisini kayıt altına alabilirsiniz.

    Aslında burada yaptığımız Google’ın Analytics’deki dataLayer’ına çok benzer bir yapı, sadece bilgileri kendimiz kaydederek işimizi kolaylaştırıyoruz. Burada temelini verdiğim fikri deneyerek geliştirebilirsiniz. Eğer anlaşılmayan bir kısım varsa yorumlar bölümünden sorularınızı sorabilirsiniz. Eğer daha detaylı bir anlatım gerekirse ilerleyen zamanlarda gelen talepler doğrultusunda detaylı bir Youtube videosu yapabilirim.