DEV Community

Cover image for Kodlama Aracıları için DESIGN.md Nedir?
Tobias Hoffmann
Tobias Hoffmann

Posted on • Originally published at apidog.com

Kodlama Aracıları için DESIGN.md Nedir?

Kodlama aracıları, siz sınırları açıkça yazana kadar kod tabanınız hakkında hızlı, kendinden emin ve mimari açıdan eksik bilgiyle hareket eder. Claude Code, Codex veya Cursor'a belirsiz bir görev verdiğinizde derlenen, testi geçen ama alan katmanı ile HTTP katmanı arasındaki sınırı bozan kod üretebilir. DESIGN.md, mimari niyeti doğrudan depoya yazarak bu tahmin problemini azaltır.

Apidog'u bugün deneyin

TL;DR

DESIGN.md, kod tabanının mimari niyetini, değişmezlerini, kısıtlarını ve tasarım kararlarını Markdown olarak kaydeden bir depo dosyasıdır. Kodlama aracıları için “bu sistem neden böyle?” sorusunu yanıtlar.

  • README.md: Proje nedir, nasıl başlatılır?
  • AGENTS.md: Nasıl build/test/lint yapılır?
  • CLAUDE.md: Claude Code’a özel çalışma talimatları
  • DESIGN.md: Mimari kararlar, sınırlar ve bozulmaması gereken kurallar

Giriş

Kodlama aracılarını kullanan ekiplerin sık gördüğü hata şudur: Bir aracıdan ödeme servisine iade endpoint’i eklemesini istersiniz. Aracı çalışan bir handler üretir; testler geçer. Fakat handler veritabanını doğrudan controller’dan çağırır, gateway hatasını yutar ve sistemde zaten bulunan para modelini kullanmak yerine yeni bir para tipi oluşturur.

Sorun aracının kod yazamaması değildir. Sorun, aracının şu bilgileri bilmemesidir:

  • Katman sınırları
  • Alan değişmezleri
  • Geçmişte reddedilen tasarım seçenekleri
  • API sözleşmesinin gerçek kaynağı
  • “Bunu asla böyle yapmayın” kararları

DESIGN.md, bu bilgileri deponun köküne koyar. Böylece aracı kodu okuduğu yerde mimari niyeti de okur.

DESIGN.md aslında nedir?

DESIGN.md, kodunuzun neden bu şekilde tasarlandığını anlatan düz metin bir dosyadır.

Şunları belgelemek için kullanılır:

  • Katmanlar ve bağımlılık yönleri
  • Değişmezler
  • Kritik kararların gerekçeleri
  • Reddedilen alternatifler
  • API sözleşmesinin kaynağı
  • Veri modeli kuralları
  • Yeni kodun nereye ekleneceği
  • Aracının dokunmaması gereken alanlar

Örneğin kaynak kodu bir aracının Account.debit() metodunu görmesini sağlar. Ama bu metodun tek yetkili bakiye değiştirme yolu olduğunu söylemez. DESIGN.md bunu açıkça yazar.

Bu yaklaşım, ARCHITECTURE.md ve ADR pratiklerine benzer. Farkı, dosyanın kodlama aracılarının da okuyacağı şekilde daha kısa, daha bildirimsel ve karar odaklı yazılmasıdır.

DESIGN.md vs AGENTS.md vs CLAUDE.md vs README

Bu dosyalar birbirini tamamlar; aynı belgeye dönüştürülmemelidir.

Dosya Kitle Cevapladığı soru Değişim hızı Önerilen uzunluk
README.md İnsanlar Bu proje nedir, nasıl başlatılır? Özelliklerle değişir Orta
AGENTS.md Kodlama aracıları Nasıl build/test/lint/commit yapılır? Araçlarla değişir Kısa
CLAUDE.md Claude Code AGENTS.md + Claude’a özel talimatlar Araçlarla değişir Kısa, yaklaşık 200 satır altı
DESIGN.md Aracılar + mühendisler + reviewer’lar Sistem neden böyle tasarlandı? Mimariyle değişir Orta, karar yoğun

AGENTS.md, agents.md projesi tarafından “kodlama aracılarını yönlendirmek için basit, açık bir format” olarak tanımlanır. İşlevi operasyoneldir: test komutları, build adımları, lint kuralları, commit formatı.

Anthropic’in Claude Code bellek belgelerine göre CLAUDE.md, Claude Code için benzer bir talimat dosyasıdır. Mevcut bir AGENTS.md varsa CLAUDE.md içinde @AGENTS.md ile içe aktarılması önerilir.

Fakat bu dosyalara derin mimari gerekçe koymak iyi bir fikir değildir. Uzadıkça modelin dosyayı takip etmesi zorlaşır. Daha iyi yapı şudur:

README.md      -> İnsanlara giriş
AGENTS.md      -> Build/test/lint/commit talimatları
CLAUDE.md      -> @AGENTS.md + Claude’a özel kısa kurallar
DESIGN.md      -> Mimari niyet, değişmezler, kararlar
Enter fullscreen mode Exit fullscreen mode

AGENTS.md içinde DESIGN.md için kısa bir referans yeterlidir:

Mimari ve tasarım kuralları için `DESIGN.md` dosyasını okuyun.
Katman sınırlarını, değişmezleri veya API sözleşmesini etkileyen
değişikliklerden önce bu dosyayı kontrol edin.
Enter fullscreen mode Exit fullscreen mode

Claude Code tarafında:

@AGENTS.md
@DESIGN.md
Enter fullscreen mode Exit fullscreen mode

Bu dosyaların Claude bağlamıyla nasıl çalıştığına dair daha ayrıntılı bir örnek için Claude Code iş akışları yazısına bakabilirsiniz.

DESIGN.md’ye ne koymalı?

Bir DESIGN.md, aracının yalnızca kod okuyarak çıkaramayacağı bilgileri içermelidir.

Koyulması gereken başlıklar:

  • Sistem şekli: Katmanlar, modüller, bağımlılık yönleri
  • Değişmezler: Her zaman doğru kalması gereken kurallar
  • Ana kararlar ve gerekçeleri: Neden bu tasarım seçildi?
  • Reddedilen alternatifler: Aracının tekrar önermemesi gereken yollar
  • Veri ve domain kuralları: Para, zaman, ID, tenant, soft-delete vb.
  • API sözleşmesi: OpenAPI dosyasının konumu ve yetkisi
  • Yeni kodun yeri: Endpoint, use case, integration, middleware nereye eklenir?
  • Dokunulmaması gerekenler: Generated kod, legacy modüller, eski migration’lar
  • Çelişki durumunda davranış: Aracı ne yapmalı?

Örnek DESIGN.md şablonu

Aşağıdaki şablonu kopyalayıp kendi servisiniz için daraltabilirsiniz.

# DESIGN.md: Payments API Service

This file records architectural intent and the decisions behind it.
Read this before generating or modifying code. If a change conflicts
with a rule here, stop and flag it instead of working around it.

## System shape

Layered, dependencies point inward only:

  http (handlers, DTOs) -> app (use cases) -> domain (entities,
  invariants) <- infra (db, gateway clients)

- `domain/` has zero imports from `http/`, `app/`, or any framework.
- `infra/` implements interfaces declared in `domain/` or `app/`.
- `http/` never touches the database or the payment gateway directly.
  It calls a use case in `app/`.

## Invariants

- A ledger entry is immutable once written. Corrections are new
  compensating entries, never updates or deletes.
- Account balance is derived from ledger entries, not stored as a
  mutable field that code can set directly.
- Money is an integer count of minor units plus an ISO-4217 currency
  code. Never use float. Never mix currencies in one operation.
- Every call to an external payment gateway is idempotent, keyed by
  `idempotency_key`.
- Balances never go negative unless an explicit `OverdraftPolicy`
  authorizes it.

## Key decisions and rationale

- **Outbox pattern for gateway calls.**
  Handlers write an intent row in the same DB transaction as the
  business change. A worker calls the gateway later.
  Rationale: the gateway times out under load. Inline calls made
  latency and failure handling unowned.
  Do not call the gateway from a request handler.

- **Single write path per aggregate.**
  Only `Account.post_entry()` writes to the ledger.
  Rationale: a second write path caused balance drift.
  Add new behavior as aggregate methods, not new ad-hoc queries.

- **Event sourcing for the ledger only.**
  The rest of the system is CRUD.
  Rationale: money requires a perfect audit trail; full event sourcing
  elsewhere is unnecessary.

## Rejected alternatives

- ORM lazy-loading across aggregates. It caused N+1s and unclear
  transaction boundaries.
- Storing balance as a column updated in place.
- Pulling a generic `Money` library from the registry. Use
  `domain/money.py`.
- Synchronous merchant webhooks from the request thread. Use the
  notification queue.

## Data and domain rules

- All timestamps are UTC, stored as `timestamptz`, formatted RFC 3339
  at the edge.
- IDs are ULIDs generated in the app layer, never DB autoincrement.
- Soft delete is not used. Records are active or archived by an
  explicit use case.
- Every query is scoped by `tenant_id`. A repository method without
  tenant scope is a bug.

## API contract source of truth

- The OpenAPI 3.1 spec in `api/openapi.yaml` is authoritative.
- Request/response types are generated from the spec.
- Do not hand-edit generated types in `http/generated/`.
- New or changed endpoints:
  1. Update `api/openapi.yaml`
  2. Regenerate types
  3. Implement the use case and handler
- Error responses follow RFC 9457 `problem+json`.
  Use the shared `problem()` helper.

## Where new code goes

- New endpoint:
  - route: `http/routes/`
  - DTO: `http/dto/`
  - use case: `app/usecases/`
  - domain logic: `domain/`
- New external integration:
  - client: `infra/clients/`
  - interface: `app/ports/`
- Cross-cutting concern:
  - middleware: `http/middleware/`
  - never inline in handlers

## Out of scope / do not touch

- `http/generated/`: regenerated from OpenAPI
- `legacy/billing_v1/`: frozen, under migration
- `migrations/`: never edit an applied migration; add a new one

## When in doubt

If a requested change requires breaking a rule above, stop and say so.
Propose the smallest design-consistent alternative instead of silently
working around the rule.
Enter fullscreen mode Exit fullscreen mode

Son bölüm önemlidir. Aracıya yalnızca kuralı değil, kural çakıştığında ne yapacağını da söylemiş olursunuz.

Kodlama aracıları DESIGN.md’yi nasıl tüketir?

Aracıların özel bir DESIGN.md parser’ı yoktur. Dosyayı normal bir repo dosyası gibi okurlar ve bağlama eklerler.

Uygulanabilir kurulum:

1. Depo köküne DESIGN.md ekleyin

repo/
  README.md
  AGENTS.md
  CLAUDE.md
  DESIGN.md
  api/openapi.yaml
  src/
Enter fullscreen mode Exit fullscreen mode

2. AGENTS.md içinde referans verin

## Architecture

Before structural changes, read `DESIGN.md`.

Follow its layering rules, invariants, API contract rules, and
"when in doubt" instruction.
Enter fullscreen mode Exit fullscreen mode

3. Claude Code kullanıyorsanız CLAUDE.md içinde içe aktarın

@AGENTS.md
@DESIGN.md

Prefer design-consistent changes. If a request conflicts with
DESIGN.md, explain the conflict before editing code.
Enter fullscreen mode Exit fullscreen mode

4. Review sırasında dosyaya referans verin

Bir PR’da ihlal gördüğünüzde yorumu spesifik yazın:

Bu değişiklik DESIGN.md içindeki "http never touches the database
directly" kuralını ihlal ediyor. Handler yerine app/usecases altında
bir use case ekleyelim.
Enter fullscreen mode Exit fullscreen mode

Bu, aracıya net bir düzeltme hedefi verir.

Kendi aracı sistemlerini kuran ekipler de benzer geri bildirim döngüsüne dayanır. Bunun otonom akışlara nasıl bağlandığını kendi Claude Code’unuzu oluşturun yazısında görebilirsiniz.

Anti-pattern’lar

DESIGN.md kısa, karar yoğun ve güncel kalmalıdır. Aşağıdaki hatalardan kaçının.

1. Kodu yeniden anlatmak

Kötü:

`UserService` kullanıcıları yönetir.
Enter fullscreen mode Exit fullscreen mode

Bu bilgi zaten koddan okunabilir.

İyi:

User creation must go through `RegisterUser` use case because it
creates the audit record and default billing profile in one transaction.
Enter fullscreen mode Exit fullscreen mode

2. Eğitim dokümanına çevirmek

DESIGN.md içine uzun “özellik nasıl eklenir?” rehberleri koymayın. Bunlar CONTRIBUTING.md veya ekip içi dokümana aittir.

DESIGN.md şunları içermemelidir:

  • Uzun shell komutları
  • Kurulum adımları
  • IDE ayarları
  • Genel onboarding metni

3. Hedef mimariyi mevcut gerçeklik gibi yazmak

Kötü:

All writes go through use cases.
Enter fullscreen mode Exit fullscreen mode

Eğer legacy kod bunu yapmıyorsa bu yanıltıcıdır.

İyi:

Target: all writes go through use cases.
Current exception: `legacy/` bypasses this. Do not extend that pattern.
Enter fullscreen mode Exit fullscreen mode

4. Sahipsiz bırakmak

Bir sahibi yoksa dosya çürür. PR şablonuna kontrol ekleyin:

- [ ] Bu PR `DESIGN.md` içindeki bir kararı değiştiriyor mu?
- [ ] Değiştiriyorsa `DESIGN.md` aynı PR’da güncellendi mi?
Enter fullscreen mode Exit fullscreen mode

5. Kodla satır satır senkronize etmeye çalışmak

DESIGN.md, fonksiyon imzalarını veya dosya listesini takip etmek için değildir. Yılda birkaç kez değişen kararları belgeleyin:

  • Katman sınırları
  • Transaction modeli
  • API sözleşmesi
  • Veri bütünlüğü
  • Güvenlik değişmezleri

6. AGENTS.md ile çelişmek

Operasyonel kurallar AGENTS.md içinde, mimari kurallar DESIGN.md içinde kalmalıdır. Aynı kuralı iki yerde farklı şekilde yazmayın.

API ve arka uç kod tabanları için DESIGN.md

DESIGN.md en çok API ve backend servislerinde değer üretir. Çünkü bu sistemlerde hatalı tahminler pahalıdır:

  • Yanlış API sözleşmesi
  • Bozuk transaction sınırı
  • Eksik idempotency
  • Tutarsız hata modeli
  • Tenant izolasyonu hatası
  • Katman ihlali
  • Generated kodun elle değiştirilmesi

OpenAPI sözleşmesini yetkili kaynak yapın

DESIGN.md içinde açık yazın:

The OpenAPI spec in `api/openapi.yaml` is authoritative.
Generated types must not be edited by hand.
Endpoint changes start with the OpenAPI spec.
Enter fullscreen mode Exit fullscreen mode

Bu, aracının derlemeyi geçirmek için generated type dosyasını elle değiştirmesini engeller.

Eğer sözleşmeyi önce Apidog içinde tasarlayıp OpenAPI olarak depoya aktarıyorsanız, DESIGN.md doğrudan bu dosyayı işaret edebilir. Koddan önce sözleşme tasarlama yaklaşımı AI aracıları için API tasarlama yazısında daha ayrıntılı ele alınır.

Transaction sınırlarını belirtin

Örnek:

External calls must never happen inside a DB transaction.
Use the outbox table and background worker.
Enter fullscreen mode Exit fullscreen mode

Bu kural yazılı değilse, aracı genellikle en basit yolu seçer: handler içinde satır içi gateway çağrısı.

Idempotency kuralını değişmez yapın

Ödeme, sipariş ve provisioning endpoint’leri için kritik:

All POST endpoints that create money movement require an
`Idempotency-Key` header. Retries must not create duplicate charges.
Enter fullscreen mode Exit fullscreen mode

Hata modelini sabitleyin

All API errors use RFC 9457 `problem+json`.
Use the shared `problem()` helper.
Do not invent endpoint-specific error envelopes.
Enter fullscreen mode Exit fullscreen mode

Tenant kapsamını güvenlik değişmezi yapın

Every repository query must be scoped by `tenant_id`.
A repository method without tenant scope is a security bug.
Enter fullscreen mode Exit fullscreen mode

Versiyonlama kurallarını yazın

Renaming or removing a response field is a breaking change.
Breaking changes require a new major API version.
Minor versions may only add optional fields.
Enter fullscreen mode Exit fullscreen mode

Bu kurallar aracıların “küçük refactor” adı altında istemci kırmasını engeller.

Aracının yazdığı API’yi sözleşmeye karşı test etmek istiyorsanız, Apidog’u indirin. Önce API tasarımını oluşturabilir, DESIGN.md içinde işaret edeceğiniz OpenAPI çıktısını alabilir ve oluşturulan endpoint’lerin sözleşmeyle uyumunu test edebilirsiniz.

Uygulama planı

Mevcut bir depoya DESIGN.md eklemek için küçük başlayın.

Adım 1: En sık bozulan 5 kuralı yazın

Örneğin:

## Invariants

- HTTP handlers never access the database directly.
- All writes go through app use cases.
- OpenAPI spec in `api/openapi.yaml` is authoritative.
- Generated files under `http/generated/` are never hand-edited.
- Every query is scoped by `tenant_id`.
Enter fullscreen mode Exit fullscreen mode

Adım 2: Her kuralın gerekçesini ekleyin

Rationale: direct DB access from handlers previously bypassed audit
logging and tenant checks.
Enter fullscreen mode Exit fullscreen mode

Adım 3: AGENTS.md ve CLAUDE.md’den referans verin

Read `DESIGN.md` before changing architecture, API contracts,
transactions, generated code, or domain rules.
Enter fullscreen mode Exit fullscreen mode

Adım 4: PR şablonuna kontrol ekleyin

## Design impact

- [ ] This PR changes architecture, API contract, transaction behavior,
      domain invariants, or generated code rules.
- [ ] If yes, `DESIGN.md` was reviewed and updated.
Enter fullscreen mode Exit fullscreen mode

Adım 5: İlk ay sadece ihlal yakalayın

Başlangıçta dosyayı mükemmelleştirmeye çalışmayın. Review sırasında her tekrar eden aracı hatasını DESIGN.md kuralına dönüştürün.

Sonuç

  • DESIGN.md, kodunuzun neden böyle tasarlandığını kaydeder.
  • AGENTS.md ve CLAUDE.md yerine geçmez; onları tamamlar.
  • Kuralları kısa, test edilebilir ve mutlak ifadelerle yazın.
  • API ve backend servislerinde özellikle değerlidir: OpenAPI sözleşmesi, transaction sınırları, idempotency, tenant izolasyonu ve hata modeli gibi görünmez kuralları açık hale getirir.
  • PR sürecine bağlanmazsa çürür.
  • En büyük backend kazanımı, OpenAPI dosyasını yetkili kaynak ilan etmektir.
  • Önce sözleşmeyi tasarlamak, sonra aracıya o sözleşmeye göre kod yazdırmak daha güvenilir sonuç verir. Bunun için Apidog’u indirin.

Sıkça Sorulan Sorular

DESIGN.md, AGENTS.md gibi resmi bir standart mıdır?

Hayır. AGENTS.md, Linux Vakfı’nın Agentic AI Vakfı tarafından denetlenen tanımlı ve yaygın bir formattır. DESIGN.md ise ARCHITECTURE.md ve ADR’lere benzeyen bir topluluk konvansiyonudur. Standarttan çok uygulanabilir bir kalıp olarak düşünün.

AGENTS.md veya CLAUDE.md varsa DESIGN.md’ye ihtiyaç var mı?

Mimarinizde açık olmayan kısıtlar varsa evet. AGENTS.md ve CLAUDE.md kısa ve operasyonel kalmalıdır. Derin mimari gerekçe DESIGN.md içinde durmalı ve bu dosyalardan referans alınmalıdır. Operasyonel dosya için AGENTS.md dosyaları nasıl yazılır yazısına bakabilirsiniz.

DESIGN.md, ARCHITECTURE.md’den nasıl farklıdır?

Fark çoğunlukla hedef kitle ve yazım tarzıdır. ARCHITECTURE.md genellikle insan katkıda bulunanlara yönelik daha geniş bir mimari haritadır. DESIGN.md, kodlama aracılarını da hedeflediği için daha bildirimsel, daha kısa ve değişmez odaklı yazılır.

DESIGN.md ne kadar uzun olmalı?

Aracıların sık yanlış yaptığı kararları kapsayacak kadar uzun, her satırın değer taşıyacağı kadar kısa olmalı. İki ila dört sayfalık net kurallar, on beş sayfalık mimari anlatıdan daha kullanışlıdır.

Aracının DESIGN.md’yi okumasını nasıl sağlarım?

Aracının başlangıçta yüklediği dosyalardan referans verin.

Claude Code için:

@DESIGN.md
Enter fullscreen mode Exit fullscreen mode

AGENTS.md için:

Read `DESIGN.md` before structural or API contract changes.
Enter fullscreen mode Exit fullscreen mode

Tüm içeriği kısa talimat dosyalarına kopyalamayın; referans verin.

Aracı DESIGN.md’ye her zaman uyacak mı?

Hayır. Bu dosyalar zorunlu kural motoru değildir; modele verilen bağlamdır. Bu yüzden kuralları net yazın, çelişki durumunda ne yapılacağını belirtin ve review sürecinde ihlalleri DESIGN.md maddesine referansla düzeltin.

DESIGN.md API sözleşme sorunlarına gerçekten yardımcı olur mu?

Evet. En değerli kullanım, OpenAPI dosyasını yetkili kaynak ilan etmektir. Böylece aracı şema icat etmek veya generated type dosyalarını elle düzenlemek yerine sözleşmeye uyar. Bu sözleşmeyi önce Apidog gibi bir araçta tasarlamak, DESIGN.md için net bir hedef oluşturur.

DESIGN.md depoda nerede bulunmalı?

Genellikle depo kökünde:

README.md
AGENTS.md
CLAUDE.md
DESIGN.md
Enter fullscreen mode Exit fullscreen mode

Monorepo kullanıyorsanız kökte sistem genelindeki kararları, paketlerde ise yerel mimari kuralları tutabilirsiniz.

Top comments (0)