UAT onaylandı. Canlıya geçiş bir düğme değil, sırası önceden yazılmış bir plandır. İş analisti kodu yayına almaz, ama işin canlıda doğru çalıştığını gösteren kanıtı hazırlar.
Geçiş planı (cutover checklist)
| Ne zaman? | Madde | Sahibi |
|---|---|---|
| Önce | UAT onayı ve açık hata listesi kayıtlı | BA, iş birimi |
| Önce | Destek ekibine metin ve yönlendirme iletildi | BA |
| Önce | Tutar ve sınır ayarları kontrol edildi, bütçe onayı var | Finans, BA |
| Önce | Geri alma adımları yazıldı ve denendi | Geliştirici |
| Sırasında | Yayına alma, özellik anahtarı açma (önce küçük pilot) | Geliştirici |
| Hemen sonra | Duman testleri çalıştı, sonuç sıfır hata | BA, test uzmanı |
| İlk hafta | Günlük KPI ve bütçe takibi | BA |
Duman testi (smoke test) SQL ile
Duman testi, “ayakta mı, en kritik şey doğru mu?” diye bakan kısa kontroldür. Bütün testlerin yerine geçmez. Yine “hata varsa sayı döner” kalıbı. Aşağıdaki kutunun ilk bölümü canlıya çıkan işi taklit eder ve bilerek hata içerir: filtresi iade siparişlerini de alıyor.
CREATE TABLE ba_kupon AS
SELECT o.order_id, o.customer_id, o.status,
CASE WHEN ROUND((julianday(delivered_at) - julianday(placed_at)) * 86400) > 3600 THEN 60 ELSE 30 END AS tutar
FROM lk_orders o
WHERE o.status IN ('teslim', 'iade')
AND o.placed_at >= '2024-12-01' AND o.placed_at < '2025-01-01'
AND ROUND((julianday(delivered_at) - julianday(placed_at)) * 86400) > 2700;
SELECT 'teslim_disi_kupon' AS test, COUNT(*) AS hata FROM ba_kupon WHERE status <> 'teslim'
UNION ALL
SELECT 'tutar_gecersiz', COUNT(*) FROM ba_kupon WHERE tutar NOT IN (30, 60)
UNION ALL
SELECT 'tekrar_eden', COUNT(*) FROM (SELECT order_id FROM ba_kupon GROUP BY order_id HAVING COUNT(*) > 1) AS x;
teslim_disi_kupon sıfırdan büyük çıkıyor: geçiş durur. Testin neye baktığını da sına: işin kendi filtresiyle aynı koşulu arayan bir test, o filtre bozulmadıkça ne bulabilir? Bu yüzden duman testini önce bilerek bozulmuş bir çıktıda dene; doğru çıktıda hep 0 veren test hiçbir şey kanıtlamaz.
Önce ve sonra
Başarı ölçüsü talep aşamasında yazılmıştı: pilot grupta geç teslim şikâyeti, geçişten sonraki 8 haftada, başlangıç değerine göre %20 azalmalı; geç teslimlerde kurye puanı 3,86'ın altına düşmemeli. Şikâyet sayısı bu uygulamanın verisinde yok, müşteri hizmetlerinden gelir. Kupon da verimizde gerçekten olmadığı için burada yalnız yöntemi gösteriyoruz: canlıya geçişi 1 Aralık 2024 varsayıyoruz.
WITH t AS (
SELECT order_id, customer_id, restaurant_id, courier_id, status, placed_at,
ROUND((julianday(delivered_at) - julianday(placed_at)) * 86400) AS sure_sn
FROM lk_orders
WHERE placed_at >= '2024-10-01' AND placed_at < '2025-01-01'
)
SELECT strftime('%Y-%m', placed_at) AS ay,
COUNT(*) AS teslim,
SUM(CASE WHEN sure_sn > 2700 THEN 1 ELSE 0 END) AS gec,
SUM(CASE WHEN sure_sn > 3600 THEN 60 WHEN sure_sn > 2700 THEN 30 ELSE 0 END) AS kupon_tutar
FROM t
WHERE status = 'teslim'
GROUP BY strftime('%Y-%m', placed_at)
ORDER BY ay;
Geri alma ölçütleri (rollback criteria)
Geri alma kararı, sorun çıktığında değil, önceden yazılır. Baskı altında “biraz daha bekleyelim” denmesini önler. Eşikleri geçmiş veriye dayandır: Aralık'ta bir günde en çok 49 geç teslim olmuş.
| Ölçüt | Eşik | Karar |
|---|---|---|
| Teslim dışı siparişe kupon | 1 kayıt bile | Özelliği kapat, inceleme başlat |
| Bir günde üretilen kupon | 100'ü aşarsa (geçmiş zirvenin yaklaşık iki katı) | Özelliği kapat, iş birimine bildir |
| Aylık kupon tutarı | Onaylı bütçeyi aşarsa | Finans kararına kadar durdur |
| Bildirim gönderilemeyen kupon | %5'i aşarsa | Kupon kalır, bildirim düzeltilir |
Geri almak yalnız kodu geri çekmek değildir: verilmiş kuponlar ne olacak? Bunu da yaz. Çoğu durumda müşteriye verilen kupon geri alınmaz. Eşikler bu senaryo için önerimizdir; senin projende iş birimi ve finans belirler.
Jira ve Confluence: işin izi
Birçok ekip iş takibi için Jira, doküman için Confluence kullanır. Araç başka olabilir, mantık aynıdır.
| Nerede? | Ne durur? |
|---|---|
| Epik (epic) | Geç teslim telafi kuponu: bütün iş |
| Hikâye (story) | Geç teslimde kupon üret; kuponu bildir; kupon raporu. Kabul kriterleri içinde |
| Hata (bug) | UAT ve canlı hataları, hikâyeye bağlı |
| Doküman sayfası | BRD, karar tablosu, süreç şeması, toplantı kararları; hikâyelere bağlantılı |
| Durum akışı | Yapılacak → Geliştiriliyor → Testte → UAT → Bitti |
“Bitti”nin tanımı (definition of done) yazılı olsun: kod gözden geçirildi, testler geçti, doküman güncellendi. Tutarı değiştiren bir karar yalnız bir toplantıda ya da mesajda kalırsa altı ay sonra kimse nedenini bilemez.
Değişiklik yönetimi (change management)
Yazılım çalışsa da insanlar eski yolu sürdürebilir. Destek çalışanı elle kupon vermeye devam ederse müşteri iki kupon alır. Kime ne değişiyor, kim ne zaman bilgilendirilecek, sorular kime gidecek: bunları tek sayfada topla. Destek ekibine örnek cevaplar hazırla.
Mini BRD
Her şey bir araya geldi. Şablon olarak kullanabileceğin kısa BRD:
| Bölüm | İçerik |
|---|---|
| 1. Özet ve sorun | Dönemde teslim edilen 6.637 siparişin 1.508 tanesi 45 dakikayı aşıyor. Geç teslimlerde kurye puanı 3,86, diğerlerinde 4,41. Bugün telafi elle ve kişiye göre yapılıyor. |
| 2. Amaç ve başarı ölçüsü | Geç teslim alan müşterinin 5 dakika içinde kupon alması. Ana ölçü: pilot grupta geç teslim şikâyeti, geçişten sonraki 8 haftada %20 azalır; başlangıç değeri geçiş öncesi 8 hafta, kaynağı müşteri hizmetleri kayıtları (bu uygulamanın verisinde yok). Yan ölçü: geç teslimlerde kurye puanı 3,86'ın altına düşmez. Yeniden sipariş artışı garanti edilmiyor; pilotla ölçülecek. |
| 3. Kapsam | İçi: süre hesabı, kupon, bildirim, rapor. Dışı: kurye ve restoran iyileştirmeleri, restorana kesinti. |
| 4. Paydaşlar ve RACI | Müşteri hizmetleri (talep sahibi), operasyon, finans, geliştirme, test. |
| 5. İş kuralları | Yalnız “teslim”. Süre saniye ile, sipariş zamanından teslime. 2.700 saniyeyi aşan 30 TL, 3.600 saniyeyi aşan 60 TL. Sipariş başına bir, ayda en çok iki kupon. Kupon teslim kaydından itibaren 30 gün geçerlidir (karar K-03: ürün sahibi kararı, pazarlama 30 gün, finans 7 gün önerdi; gerekçe ve maliyet etkisi karar kaydında). Karar tablosu ekte. |
| 6. Gereksinimler | GRS-01...: işlevsel. NFR-01: kupon en geç 5 dakikada. Kullanıcı hikâyeleri ve kabul kriterleri. |
| 7. Süreç ve veri | TO-BE şeması, sıra diyagramı, alan eşleme, API sözleşmesi bağlantısı. |
| 8. Varsayım ve riskler | Müşteriye söz verilen süre verisi yok, 45 dakika varsayımdır. Tutar bedeli üst sınırda 51.900 TL. Kuponun getirisi kanıtlı değil. |
| 9. Test ve kabul | Senaryo listesi, mutabakat sorguları, çıkış ölçütü. |
| 10. Geçiş ve kapanış | Geçiş planı, geri alma ölçütleri, ilk ay raporu, kapanış tarihi. |
| 11. Açık sorular | Her satır: soru, karar sahibi, tarih. Başlangıç şikâyet sayısı: müşteri hizmetleri, UAT başlamadan önce. Kupon sonrası iade: kullanılmamış kupon iptal edilsin önerisi; kullanılmış kuponun bedeli kimde kalır? Finans, UAT başlamadan önce. Söz verilen süre: 45 dakika varsayımı doğru mu? Operasyon, geçişten önce. Kapanan soru bu satırdan çıkar, karar kaydına geçer; kupon geçerlilik süresi böyle kapandı. |
BRD'deki sayılar elle yazılmaz, tekrar üretilebilir sorgudan gelir. Aşağıdaki sorgu 1. ve 8. bölümlerin sayılarını verir. Bir yıl sonra biri “bu sayı nereden çıktı?” diye sorduğunda cevabın budur.
WITH t AS (
SELECT order_id, customer_id, restaurant_id, courier_id, status, placed_at,
ROUND((julianday(delivered_at) - julianday(placed_at)) * 86400) AS sure_sn
FROM lk_orders
WHERE placed_at >= '2024-10-01' AND placed_at < '2025-01-01'
)
SELECT 'teslim' AS olcu, COUNT(*) AS deger FROM t WHERE status = 'teslim'
UNION ALL
SELECT 'gec', COUNT(*) FROM t WHERE status = 'teslim' AND sure_sn > 2700
UNION ALL
SELECT 'ust_sinir_tutar', SUM(CASE WHEN sure_sn > 3600 THEN 60 ELSE 30 END) FROM t WHERE status = 'teslim' AND sure_sn > 2700
UNION ALL
SELECT 'etkilenen_musteri', COUNT(DISTINCT customer_id) FROM t WHERE status = 'teslim' AND sure_sn > 2700;
İşin kapanışı: ilk ay raporu sunulur, açık konular sahiplerine devredilir, doküman son hâliyle bırakılır, “ne öğrendik?” toplantısı yapılır. Sonraki talep büyük ihtimalle bu kuponun başka bir yönüyle gelir. Bitirme projesinde tam olarak bunu yapacaksın.