Bir SaaS uygulamasında Google, GitHub ve Apple ile giriş yapılandırıyordum ve Google’a app yayınlamak için, kullanım şartları ve gizlilik politikası için genel erişime açık bir anasayfa gerekli. Benimkinin ise, herhangi bir ürüne uygun olan, dolayısıyla hiç birine uymayan beş genel şablon bölümünden oluşuyordu. Oturdum ve sadece bir şey yazmayı amaçladım: inceleme yapan kişiye otorite kazandırmak.
Ancak olanlar daha iyi ve oldukça rahatsız edici oldu. Belge, sistemin gerçekten ne yaptığını tanımladığında, sistemin ne yapmadığını ortaya çıkarmaya başladı. Dürüst bir politika, bürokratik bir maske altında yapılan bir kod denetimidir ve bunu daha önce yazdığım tüm SaaS’lerimde fark etmemiştim.
Belge Neyi Ortaya Koydu
Belge Neyi Ortaya Koydu
Politika, verilerin iptalden sonra 30 gün boyunca saklandığını ve ardından kalıcı olarak silindiğini ifade ediyordu. Güzel, piyasa standardı, ve bunun doğru olduğundan emindim çünkü Team SoftDeletes kullanıyordu. Kontrol ettim: üretim kodunun tamamında tek bir forceDelete bile yok. İki yıl önce silinmiş bir takım, veritabanında tamamen mevcut. Soft delete’in, implementasyonun yarısı olduğu düşündüğüm şey aslında sorunun ta kendisiydi; çünkü bana bir tür veri saklama uyguladığımı düşünmemi sağlıyordu, oysa ben sadece “silmemek” için bir şey yapmıştım.
Sonrasında beni sinirle gülümseten bir kısım vardı. Kullanıcı silme bölümüne baktım:
// app/Http/Controllers/Settings/ProfileController.php
Auth::logout();
$user->delete(); // Kullanıcı SoftDeletes kullanmıyor. Bu, artık hard delete.
Aynı ifadelerin politika kapsamında aynı anda iki farklı yönde yanlış olduğu, bir uçta takımın her zaman kalması, diğer uçta kullanıcının hemen kaybolması ve ikisinin de yazılı olarak vadettiğim 30 gün süresine sahip olmadığı anlaşılmıştı.
Sonra loglar geldi. Politika, 12 ay boyunca erişim kayıtlarının tutulacağını belirtiyordu ve bu, Marco Civil’in 15. maddesine tabiydi. Yapılandırmam böyleydi:
// config/activitylog.php
'delete_records_older_than_days' => null, // null = sonsuza dek
Bu log, her eylemin IP ve kullanıcı aracını kaydediyor. 15. madde, saklama süresinin minimum olduğunu belirtirken, asla sonsuza dek saklamak için izin vermezdi; dolayısıyla, kendi dokümanımı ihlal ediyordum.
Üçüncü bulguyu ise veri dışa aktarma konusuydu. Politika, takım sahibinin verileri panel üzerinden dışa aktarabileceğini söylüyordu ama bunun için bir rota yoktu. Mevcut olan, son kullanıcıyı dışa aktaran bir API nihai uç noktasıydı; bu, tamamen farklı bir şeydir: bu, müşterimin, kendi kullanıcılarına hizmet etmesine yardımcı olmak için bir araçtır, ben ona hizmet etmiyorum. İki durum arasında karışıklık yaşamıştım.
Kimsenin Yalan Söylemediği Yanlış Klausül
Kimsenin Yalan Söylemediği Yanlış Klausül
Şimdi önemli olabilecek kısım: o panelde veri dışa aktarımına dair cümle, aynı oturumda, yalan olduğu keşfedilmeden birkaç saat önce yazılmıştı. Kimse yalan söylemedi. AI, kodu okudu, bir DataExportsController buldu ve bunun veri dışa aktardığını gördü, dolayısıyla dışa aktarıma dair bir çıkarımda bulundu. Bu, makul bir çıkarım, güvenle yazılmış ancak tamamen yanlıştı. Eğer o cümleyi her bir maddeyle karşılaştırmak için kontrol etmeseydim, bunu gerçek gibi gösteren bir üretime geçecekti.
Bu durum, önceki gönderide bahsettiğim sorunun bir başka haliydi. Orada AI, görünür olan hatalı standardı kopyaladı; burada ise, olasılıkları geliştirdi çünkü olasılık her zaman optimize edilir. İkna edici taklit, başarısızlık modudur; yalan değil. Ve hukuki metin, bunun gerçekleşmesi için en kötü yer çünkü kimse gizlilik politikasını bir pull request kadar titiz gözle kontrol etmiyor. Belge, aslında sıkıcı olduğu için gözden kaçıyor.
Yapılandırmalarda Kimlik, Metinde Değil
Yapılandırmalarda Kimlik, Metinde Değil
İki şey kod haline dönüşüp her proje için geçerli oldu.
Birincisi oldukça basit ve gerçek bir sorunu çözmekte: şirket kimliği ve süreleri metinden çıkarmak. Artık bir config/legal.php var; burada şirket adı, vergi numarası (CNPJ), adres, mahkeme, e-posta ve saklama süreleri mevcut. Hukuki metin sadece :taxId, :retentionDays, :privacyEmail interpolasyonunu yapıyor. Adresi değiştirmek artık bir ortam değişkeni ile bir satır değişiklik yapmak olurken, yayınlanan süre artık gerçekten tek bir yer edinmiş oldu.
Bu aşamada hoşlandığım küçük bir detay var. Varsayılan boş değer, “CNPJ kaydedilmiş, no. .” ifadesini döndürüyor ve kimse bunu incelemede göremiyor, çünkü göz hukuk metninde bölünmüş bir cümle atlıyor. Dolayısıyla varsayılan değer [CNPJ] kelime grubu haline geldi, böylece yanlışlıkla yayınlaması imkansız hale geldi.
Kapı: Çünkü Kural Olmadan Kapı, Öneri Olur
Kapı: Çünkü Kural Olmadan Kapı, Öneri Olur
İkinci kısım ise süreci tamamlayan bir diğer husus. Eğer metin :taxId değerini interpolasyon yapıyor ve yapılandırmada anahtar yoksa, Laravel hata vermez: :taxId kelime grubu, politika içerisinde doğrudan görünür. Okuyucu bunu görür, ben göremem. Sessiz bir hata; bu da en nefret ettiğim türdür.
Bu nedenle hukuki metinler, tüm dizgeleri tarayan ve her bir token’ı çıkaran, eğer eşleşmiyorsa hata veren bir test kazandı:
// tests/Feature/LegalPagesTest.php
// Eşleşme olmayan tokenlar hata vermez, doğrudan görücüde çıkar. Bu test, bunu hataya dönüştürüyor.
foreach ($matches[1] as $token) {
$this->assertContains(
$token,
$known,
"landing.{$key} interpolasyon :{$token}, yapılandırma/legal.php içinde paylaşılmamış",
);
}
Bununla birlikte, her iki dilde 29 bölümün yanı sıra yapılandırmalardan herhangi biri boş çıkarsa hata verecek bir testin uygulamasını geliştirdim. Bu, önceki gönderinin aksine, daha önce hiç düşünmediğim bir yerde uygulanmış oldu: önemli olan, test olmayı gerektiriyor. Gizlilik politikası önemlidir, bu nedenle ciddiye aldığım başka herhangi bir kurallar gibi test haline gelmelidir.
Belgeyi Genel Görünümden Çıkaran Unsurları
Belgeyi Genel Görünümden Çıkaran Unsurları
Beklemediğim bir şey: otorite sağlayan şey, belgenin güzel yazılmış olması değil, uygulamanın ne yaptığının arka planda olmasıdır.
Ürünün, aynı anda iki rol üstlendiğini belirtmek önemlidir. Ben veri kontrolörü olarak müşteri hesabına (kayıt, giriş, faturalandırma) hizmet ederken, aynı zamanda veri operatörü olarak müşterimin sonunda kullanıcılarına hizmet sağlıyorum; bu da kendi ürününde kurduğu widget aracılığıyla sağlanır. Farklı hukuki rejimler ve farklı sorumluluklar içerir, aynı veritabanında. Hiçbir şablon bu ayrımı yapamaz, çünkü şablon, oluşturduğun ürünün ne yaptığını bilemez.
Bu farklılığı ayrı bir bölümde belirtmek, metni “güzel genel” olmaktan “bu kişi işin ne olduğunu biliyor” seviyesine çıkardı. Bu, bir B2B müşterisinin hukuki departmanının ilk bakacağı detaydır.
Çıkarımlarım
Çıkarımlarım
- Politikayı kod karşısında yazın, şablon değil. Her bir madde, sisteminiz hakkında doğrulanabilir bir ifade olmalıdır. Eğer o ifadeyi yerine getiren dosyayı gösteremiyorsanız, o ifade bir kurgudan ibarettir.
- Yayınlanan süre, uygulanabilir süre olmalıdır. “30 gün” veya “12 ay” yazdığınız andan itibaren, bu bir beklenti olmaktan çıkıp bir yükümlülük haline gelmiştir. Ya zamanlama işlevini yerine getirir ya da o sayı metinden kaldırılmalıdır.
- Hukuki metinler, tıpkı diğer kurallar gibi geçerlilik kazanmalıdır. Hataların en çok gizlice hayatta kalabildiği, çünkü kimsenin dikkatle gözden geçirmediği yerdir ve hata durumu, sorun değil; kullanıcı politikası ortasında
:taxIdifadesini görmek olur.
Sonuç
Sonuç
Hiçbirini henüz yayımlamadım. Üç hata, repo’mda bir sorun olarak kaydedildi ve veri saklama maddesi kritik: bir takım silindiğinde veritabanında sonsuza kadar kalırsa, belge kodun yaptığı sözü veriyor ve bunu yayınlamak, bir şablon sorununu LGPD sorunu ile değiştirmek olur. Logların silinmesi en kolay olanı ve yapılandırmaya sadece bir satır eklemek yeterli, ama yine de orada duruyordu.
Yanlış ifadeleri, mevcut süreci doğru bir şekilde tanımlayacak şekilde hemen düzelttim; veri dışa aktarma için mevcut durumda, bir e-posta ile manuel bir talep olarak belirteceğim. Bu, “panelden dışa aktar” ifadesinden daha az güzel ama en azından gerçektir.
Şu an bir SaaS uygulamanız varsa, bir test yapın: gizlilik politikanızı açın ve herhangi birini seçin, herhangi bir cümleyi, bir süre vaat eden. Koda gidin ve o sözü kimin yerine getirdiğini arayın. Ne bulduğunuzu söyleyin.
Kaynak: Orijinal Makale


