<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>software &#8211; Selman Tunc</title>
	<atom:link href="https://selmantunc.com.tr/category/software/feed/" rel="self" type="application/rss+xml" />
	<link>https://selmantunc.com.tr</link>
	<description></description>
	<lastBuildDate>Wed, 01 Jul 2026 06:44:05 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://selmantunc.com.tr/wp-content/uploads/2023/07/cropped-tumblr_inline_oglumuMbgO1tyldvk_540-150x150-1-32x32.jpg</url>
	<title>software &#8211; Selman Tunc</title>
	<link>https://selmantunc.com.tr</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Diziler ve para kazanmak</title>
		<link>https://selmantunc.com.tr/software/diziler-ve-para-kazanmak/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Wed, 01 Jul 2026 06:44:05 +0000</pubDate>
				<category><![CDATA[software]]></category>
		<guid isPermaLink="false">https://selmantunc.com.tr/?p=3568</guid>

					<description><![CDATA[The text in the image highlights the rapid disruption of traditional streaming by microdrama / vertical short drama apps. Market intelligence reports from Sensor Tower and Omdia reveal explosive growth&#8230;]]></description>
										<content:encoded><![CDATA[<p>The text in the image highlights the rapid disruption of traditional streaming by microdrama / vertical short drama apps. Market intelligence reports from <a href="https://sensortower.com/blog/state-of-short-drama-apps-2025">Sensor Tower</a> and <a href="https://omdia.tech.informa.com/pr/2026/feb/microdramas-overtake-streamers-on-mobile-engagement-says-omdia">Omdia</a> reveal explosive growth metrics across 2025 and heading into 2026: [1, 2, 3] </p>
<h2>💰 Explosive Financial Growth</h2>
<ul>
<li>
</li>
<li>$2.98 Billion Revenue: Global in-app purchase revenue generated by short drama apps across 2025.</li>
<li>115% Year-Over-Year Increase: The third-fastest growth rate of any app category tracked by Sensor Tower. [2, 4] </li>
<li>
</li>
</ul>
<h2>⏱️ Overtaking Mobile Engagement</h2>
<p>Data from Q4 2025 shows that daily usage of short drama leaders like ReelShort beats premium long-form streaming platforms on mobile devices in the U.S.: [2, 5] </p>
<ul>
<li>
</li>
<li>ReelShort: 35.7 minutes per day per user.</li>
<li>Amazon Prime Video: 26.9 minutes per day.</li>
<li>Netflix Mobile: 24.8 minutes per day.</li>
<li>Disney+: 23.0 minutes per day. [2, 3] </li>
<li>
</li>
</ul>
<h2>📥 Surging App Downloads</h2>
<ul>
<li>
</li>
<li>733 Million Downloads: Total global installs driven by microdrama apps in Q4 2025 alone.</li>
<li>658 Million Downloads: Total global installs for traditional long-form streaming platforms in the same timeframe. [2] </li>
<li>
</li>
</ul>
<p>The underlying analysis published by platforms like <a href="https://filmustage.com/blog/short-drama-apps-compared-reelshort-vs-dramabox-in-2026/">Filmustage</a> notes that these numbers anchor production and pitching decisions for creators in 2026. Major legacy Hollywood entrants are actively building mobile-first vertical strategies to tap into this highly addictive, micro-payment-driven business model. [2, 6]
If you&#8217;d like, I can:</p>
<ul>
<li>
</li>
<li>Explain the monetization models used by these apps</li>
<li>Provide details on the top dominating apps in this space</li>
<li>Break down the typical genres and formats of microdramas</li>
<li>
</li>
</ul>
<p>[1] <a href="https://finance.yahoo.com/news/microdramas-overtake-streamers-mobile-engagement-061100325.html">https://finance.yahoo.com</a>
[2] <a href="https://filmustage.com/blog/short-drama-apps-compared-reelshort-vs-dramabox-in-2026/">https://filmustage.com</a>
[3] <a href="https://omdia.tech.informa.com/pr/2026/feb/microdramas-overtake-streamers-on-mobile-engagement-says-omdia">https://omdia.tech.informa.com</a>
[4] <a href="https://www.media-marketing.com/en/news/microdrama-apps-overtake-streamers-on-mobile/">https://www.media-marketing.com</a>
[5] <a href="https://deadline.com/2026/02/microdrama-more-time-cellphones-streaming-services-omdia-1236732921/">https://deadline.com</a>
[6] <a href="https://www.youtube.com/watch?v=vsQHJUzaYqg&amp;t=3">https://www.youtube.com</a></p>
<p>Evet, bu veriler kesinlikle doğrudur ve bu sektörde gerçekten bu kadar büyük kazançlar bulunmaktadır. [1, 2]
Görselde yer alan istatistikler, mobil pazar analiz şirketleri <a href="https://sensortower.com/blog/state-of-short-drama-apps-2025">Sensor Tower</a> ve <a href="https://omdia.tech.informa.com/pr/2026/feb/microdramas-overtake-streamers-on-mobile-engagement-says-omdia">Omdia</a> tarafından yayınlanan resmi raporlara dayanmaktadır. Hatta güncel küresel pazar payı verileri incelendiğinde, bu dikey kısa dizi (microdrama) sektörünün toplam büyüklüğü (Çin içi pazar dahil) 11 milyar doları aşmış durumdadır. [1, 2, 3, 4]
Bu kadar yüksek kazançların oluşmasının ardında yatan temel faktörler şunlardır:</p>
<h2>🪙 Pahalı ve Agresif Para Kazanma Modeli</h2>
<ul>
<li>
</li>
<li>Bölüm Başına Ödeme: Netflix gibi platformlara ayda sabit bir ücret ödersiniz. Short drama uygulamalarında (ReelShort, DramaBox vb.) ise ilk 5-10 bölüm ücretsizdir. Sonraki her bir dakikalık bölümü izlemek için &#8220;jeton&#8221; (coin) satın almanız gerekir. [1] </li>
<li>Tuzak Kurgular: Diziler tam en heyecanlı yerinde (cliffhanger) bittiği için kullanıcılar fark etmeden ardı ardına jeton harcar. Bir dizinin tamamını (ortalama 60-90 bölüm) bitirmek bazen 50 ila 100 dolar arasında bir maliyete ulaşabilir. Bu da sinema biletinden veya aylık Netflix aboneliğinden çok daha pahalıdır.</li>
<li>
</li>
</ul>
<h2>🎬 Düşük Maliyet, Yüksek Kâr Marjı</h2>
<ul>
<li>
</li>
<li>Ucuz Prodüksiyon: Hollywood yapımları milyonlarca dolar harcarken, bu dikey diziler Los Angeles veya Doğu Avrupa&#8217;da, amatör ya da yarı profesyonel oyuncularla, telefonların dikey formatına uygun olarak 150.000 &#8211; 250.000 gibi çok düşük bütçelerle, sadece birkaç günde çekilir.</li>
<li>Hızlı Geri Dönüş: Yatırılan bütçe, agresif sosyal medya reklamları sayesinde birkaç hafta içinde katlanarak geri kazanılır. [1, 5] </li>
<li>
</li>
</ul>
<h2>📈 Devlerin Rekabeti (2026 Trendi)</h2>
<p>Pazardaki bu devasa para akışı nedeniyle, 2026 yılı itibarıyla Disney (Disney Accelerator programı üzerinden), Amazon ve TikTok (Pine Drama) gibi dev şirketler de kendi dikey kısa dizi formatlarını ve yatırımlarını devreye sokarak bu milyar dolarlık pastadan pay almaya başlamıştır. [1, 5]
Kısacası, insanların mobil cihazlardaki kısalan dikkat sürelerini ve &#8220;merak&#8221; duygusunu paraya çeviren bu sistem, şu an uygulama dünyasının en çok kazandıran iş modellerinden biridir. [2, 6] </p>
<p>[1] <a href="https://filmustage.com/blog/short-drama-apps-compared-reelshort-vs-dramabox-in-2026/">https://filmustage.com</a>
[2] <a href="https://www.media-marketing.com/en/news/microdrama-apps-overtake-streamers-on-mobile/">https://www.media-marketing.com</a>
[3] <a href="https://deadline.com/2026/02/microdrama-more-time-cellphones-streaming-services-omdia-1236732921/">https://deadline.com</a>
[4] <a href="https://www.mediapost.com/publications/article/413505/microdramas-drove-in-app-revenue-of-11b-worldwide.html">https://www.mediapost.com</a>
[5] <a href="https://www.linkedin.com/posts/da-hoang-635186199_the-short-drama-apps-report-activity-7475810580654739456--rCf">https://www.linkedin.com</a>
[6] <a href="https://asoworld.com/blog/mobile-app-insights-13-short-drama-apps-crack-google-play-s-top-50-grossing/">https://asoworld.com</a></p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>menu design</title>
		<link>https://selmantunc.com.tr/software/menu-design/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Tue, 30 Jun 2026 05:51:04 +0000</pubDate>
				<category><![CDATA[software]]></category>
		<guid isPermaLink="false">https://selmantunc.com.tr/?p=3564</guid>

					<description><![CDATA[WordPress benzeri, iç içe geçebilen (nested) menüler yapmak için en temiz yöntem SortableJS kütüphanesini kullanmaktır. jQuery bağımlılığı yoktur (Vanilla JS ile çalışır) ancak jQuery ile de kolayca entegre olur. 1.&#8230;]]></description>
										<content:encoded><![CDATA[<p>WordPress benzeri, iç içe geçebilen (nested) menüler yapmak için en temiz yöntem <strong>SortableJS</strong> kütüphanesini kullanmaktır. jQuery bağımlılığı yoktur (Vanilla JS ile çalışır) ancak jQuery ile de kolayca entegre olur.</p>
<h3>1. Frontend: SortableJS ile Menü Yönetimi</h3>
<p>Önce CDN üzerinden gerekli kütüphaneyi HTML&#8217;ine ekle:</p>
<pre><code class="lang-html language-html html">&lt;script src=&quot;https://raw.githack.com/SortableJS/Sortable/master/Sortable.js&quot;&gt;&lt;/script&gt;
</code></pre>
<h4>HTML Yapısı:</h4>
<pre><code class="lang-html language-html html">&lt;ul id=&quot;menu-list&quot; class=&quot;menu-container&quot;&gt;
    &lt;li data-id=&quot;1&quot;&gt;Anasayfa&lt;/li&gt;
    &lt;li data-id=&quot;2&quot;&gt;Hakkımızda
        &lt;ul class=&quot;nested-menu&quot;&gt;
            &lt;li data-id=&quot;3&quot;&gt;Ekibimiz&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li data-id=&quot;4&quot;&gt;İletişim&lt;/li&gt;
&lt;/ul&gt;

&lt;button id=&quot;save-menu&quot;&gt;Men&uuml;y&uuml; Kaydet&lt;/button&gt;
</code></pre>
<h4>JavaScript:</h4>
<pre><code class="lang-javascript language-javascript javascript">new Sortable(document.getElementById('menu-list'), {
    group: 'nested',
    animation: 150,
    fallbackOnBody: true,
    swapThreshold: 0.65
});

document.getElementById('save-menu').addEventListener('click', () =&gt; {
    // T&uuml;m listeyi serialize et ve Go backend'e g&ouml;nder
    const data = getOrder(document.getElementById('menu-list'));
    fetch('/api/menu/save', {
        method: 'POST',
        body: JSON.stringify(data),
        headers: {'Content-Type': 'application/json'}
    });
});
</code></pre>
<hr />
<h3>2. Backend: Go (Fiber) Skeleton</h3>
<p>Veritabanında menüleri <code>id</code>, <code>parent_id</code> ve <code>order</code> sütunları ile tutman yeterlidir. Go tarafında gelen veriyi karşılayacak ve kaydedecek yapıyı kuralım.</p>
<h4>Model (GORM):</h4>
<pre><code class="lang-go language-go go">type MenuItem struct {
    ID       uint   `json:&quot;id&quot;`
    ParentID uint   `json:&quot;parent_id&quot;`
    Title    string `json:&quot;title&quot;`
    Order    int    `json:&quot;order&quot;`
}
</code></pre>
<h4>API Handler (Fiber):</h4>
<pre><code class="lang-go language-go go">package main

import (
    &quot;github.com/gofiber/fiber/v2&quot;
)

func main() {
    app := fiber.New()

    app.Post(&quot;/api/menu/save&quot;, func(c *fiber.Ctx) error {
        var menuItems []MenuItem
        if err := c.BodyParser(&amp;menuItems); err != nil {
            return c.Status(400).JSON(fiber.Map{&quot;error&quot;: &quot;Ge&ccedil;ersiz veri&quot;})
        }

        // Veritabanı işlemi:
        // 1. Transaction başlat (db.Begin())
        // 2. Mevcut men&uuml;y&uuml; temizle veya update et
        // 3. Gelen yeni sıralamayı d&ouml;ng&uuml;yle veritabanına işle

        return c.JSON(fiber.Map{&quot;status&quot;: &quot;success&quot;})
    })

    app.Listen(&quot;:3000&quot;)
}
</code></pre>
<h3>Kritik İpuçları:</h3>
<ol>
<li><strong>Serialization:</strong> <code>SortableJS</code> ile iç içe listeleri çekerken <code>nested</code> yapıyı korumak için <code>sortable.toArray()</code> yerine her <code>li</code> elemanının verisini (id ve parent) manuel olarak bir <code>map</code> içinde toplamanı öneririm.</li>
<li><strong>Veritabanı:</strong> PostgreSQL kullanıyorsan, menüleri getirmek için <code>WITH RECURSIVE</code> sorgusunu bir &#8220;view&#8221; olarak tanımlarsan, Go tarafından menüyü çekmek tek bir satır sürer.</li>
<li><strong>Güvenlik:</strong> Menü kaydetme endpoint&#8217;ine mutlaka bir <code>Auth Middleware</code> ekle ki herkes menüleri değiştiremesin.</li>
</ol>
<p>Bu skeleton üzerinden ilerleyerek, <code>sortable.toArray()</code> fonksiyonunun döndürdüğü veriyi <code>JSON</code> olarak backend&#8217;e nasıl parse edeceğin konusunda bir örneğe ihtiyaç duyarsan detaylandırabilirim. Hangi veritabanı kütüphanesini (GORM, sqlx vb.) kullanıyorsun?</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The Domain Concept for Hexagonal Architecture in Go (Golang)</title>
		<link>https://selmantunc.com.tr/golang/the-domain-concept-for-hexagonal-architecture-in-go-golang/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Mon, 13 Apr 2026 04:19:43 +0000</pubDate>
				<category><![CDATA[english]]></category>
		<category><![CDATA[golang]]></category>
		<category><![CDATA[software]]></category>
		<guid isPermaLink="false">https://selmantunc.com.tr/?p=3541</guid>

					<description><![CDATA[Here is the English version of the Go (Golang) Hexagonal Architecture example, with the same structure and explanations. 📁 Folder Structure hexagonal-go/ ├── go.mod ├── cmd/ │ └── api/ │&#8230;]]></description>
										<content:encoded><![CDATA[<p>Here is the <strong>English version</strong> of the Go (Golang) Hexagonal Architecture example, with the same structure and explanations.</p>
<hr />
<h1>📁 Folder Structure</h1>
<pre><code class="lang-text language-text text">hexagonal-go/
├── go.mod
├── cmd/
│   └── api/
│       └── main.go
└── internal/
    ├── domain/
    │   └── order/
    │       ├── money.go
    │       ├── order.go
    │       ├── order_id.go
    │       ├── order_status.go
    │       └── repository.go
    ├── application/
    │   └── order_service.go
    └── adapters/
        ├── http/
        │   └── order_handler.go
        └── persistence/
            └── memory/
                └── order_repository.go</code></pre>
<hr />
<h1>1) <code>go.mod</code></h1>
<pre><code class="lang-go language-go go">module example.com/hexagonal-go

go 1.22</code></pre>
<hr />
<h1>2) Domain Layer</h1>
<h3><code>internal/domain/order/order_id.go</code></h3>
<pre><code class="lang-go language-go go">package order

type OrderID string</code></pre>
<h3><code>internal/domain/order/order_status.go</code></h3>
<pre><code class="lang-go language-go go">package order

type OrderStatus string

const (
    OrderStatusCreated   OrderStatus = &quot;CREATED&quot;
    OrderStatusCompleted OrderStatus = &quot;COMPLETED&quot;
)</code></pre>
<h3><code>internal/domain/order/money.go</code></h3>
<pre><code class="lang-go language-go go">package order

import &quot;fmt&quot;

type Money struct {
    Cents int64
}

func NewMoney(cents int64) (Money, error) {
    if cents &lt; 0 {
        return Money{}, fmt.Errorf(&quot;money cannot be negative&quot;)
    }
    return Money{Cents: cents}, nil
}

func (m Money) Add(other Money) Money {
    return Money{Cents: m.Cents + other.Cents}
}</code></pre>
<h3><code>internal/domain/order/order.go</code></h3>
<pre><code class="lang-go language-go go">package order

import &quot;fmt&quot;

type OrderItem struct {
    ProductID string
    Quantity  int
    UnitPrice Money
}

type Order struct {
    id     OrderID
    items  []OrderItem
    status OrderStatus
}

func NewOrder(id OrderID) *Order {
    return &amp;Order{
        id:     id,
        items:  make([]OrderItem, 0),
        status: OrderStatusCreated,
    }
}

func (o *Order) ID() OrderID {
    return o.id
}

func (o *Order) Status() OrderStatus {
    return o.status
}

func (o *Order) Items() []OrderItem {
    copied := make([]OrderItem, len(o.items))
    copy(copied, o.items)
    return copied
}

func (o *Order) AddItem(productID string, quantity int, unitPrice Money) error {
    if o.status != OrderStatusCreated {
        return fmt.Errorf(&quot;order cannot be modified after completion&quot;)
    }
    if productID == &quot;&quot; {
        return fmt.Errorf(&quot;product id cannot be empty&quot;)
    }
    if quantity &lt;= 0 {
        return fmt.Errorf(&quot;quantity must be greater than zero&quot;)
    }

    o.items = append(o.items, OrderItem{
        ProductID: productID,
        Quantity:  quantity,
        UnitPrice: unitPrice,
    })

    return nil
}

func (o *Order) Complete() error {
    if len(o.items) == 0 {
        return fmt.Errorf(&quot;order must have at least one item&quot;)
    }
    o.status = OrderStatusCompleted
    return nil
}

func (o *Order) Total() Money {
    total := Money{Cents: 0}
    for _, item := range o.items {
        total = total.Add(Money{Cents: item.UnitPrice.Cents * int64(item.Quantity)})
    }
    return total
}</code></pre>
<h3><code>internal/domain/order/repository.go</code></h3>
<pre><code class="lang-go language-go go">package order

import &quot;context&quot;

type Repository interface {
    Save(ctx context.Context, order *Order) error
    FindByID(ctx context.Context, id OrderID) (*Order, error)
}</code></pre>
<hr />
<h1>3) Application Layer</h1>
<h3><code>internal/application/order_service.go</code></h3>
<pre><code class="lang-go language-go go">package application

import (
    &quot;context&quot;
    &quot;fmt&quot;
    &quot;time&quot;

    &quot;example.com/hexagonal-go/internal/domain/order&quot;
)

type OrderService struct {
    repo order.Repository
}

func NewOrderService(repo order.Repository) *OrderService {
    return &amp;OrderService{repo: repo}
}

func (s *OrderService) CreateOrder(ctx context.Context) (*order.Order, error) {
    id := order.OrderID(fmt.Sprintf(&quot;ord_%d&quot;, time.Now().UnixNano()))
    newOrder := order.NewOrder(id)

    if err := s.repo.Save(ctx, newOrder); err != nil {
        return nil, err
    }

    return newOrder, nil
}

func (s *OrderService) AddItem(ctx context.Context, orderID order.OrderID, productID string, quantity int, priceCents int64) (*order.Order, error) {
    o, err := s.repo.FindByID(ctx, orderID)
    if err != nil {
        return nil, err
    }

    price, err := order.NewMoney(priceCents)
    if err != nil {
        return nil, err
    }

    if err := o.AddItem(productID, quantity, price); err != nil {
        return nil, err
    }

    if err := s.repo.Save(ctx, o); err != nil {
        return nil, err
    }

    return o, nil
}

func (s *OrderService) CompleteOrder(ctx context.Context, orderID order.OrderID) (*order.Order, error) {
    o, err := s.repo.FindByID(ctx, orderID)
    if err != nil {
        return nil, err
    }

    if err := o.Complete(); err != nil {
        return nil, err
    }

    if err := s.repo.Save(ctx, o); err != nil {
        return nil, err
    }

    return o, nil
}

func (s *OrderService) GetOrder(ctx context.Context, orderID order.OrderID) (*order.Order, error) {
    return s.repo.FindByID(ctx, orderID)
}</code></pre>
<hr />
<h1>4) Persistence Adapter (In-Memory)</h1>
<h3><code>internal/adapters/persistence/memory/order_repository.go</code></h3>
<pre><code class="lang-go language-go go">package memory

import (
    &quot;context&quot;
    &quot;fmt&quot;
    &quot;sync&quot;

    &quot;example.com/hexagonal-go/internal/domain/order&quot;
)

type OrderRepository struct {
    mu     sync.RWMutex
    orders map[order.OrderID]*order.Order
}

func NewOrderRepository() *OrderRepository {
    return &amp;OrderRepository{
        orders: make(map[order.OrderID]*order.Order),
    }
}

func (r *OrderRepository) Save(ctx context.Context, o *order.Order) error {
    r.mu.Lock()
    defer r.mu.Unlock()

    r.orders[o.ID()] = o
    return nil
}

func (r *OrderRepository) FindByID(ctx context.Context, id order.OrderID) (*order.Order, error) {
    r.mu.RLock()
    defer r.mu.RUnlock()

    o, ok := r.orders[id]
    if !ok {
        return nil, fmt.Errorf(&quot;order not found: %s&quot;, id)
    }

    return o, nil
}</code></pre>
<hr />
<h1>5) HTTP Adapter</h1>
<h3><code>internal/adapters/http/order_handler.go</code></h3>
<pre><code class="lang-go language-go go">package httpadapter

import (
    &quot;encoding/json&quot;
    &quot;net/http&quot;
    &quot;strings&quot;

    &quot;example.com/hexagonal-go/internal/application&quot;
    &quot;example.com/hexagonal-go/internal/domain/order&quot;
)

type OrderHandler struct {
    service *application.OrderService
}

func NewOrderHandler(service *application.OrderService) *OrderHandler {
    return &amp;OrderHandler{service: service}
}

func (h *OrderHandler) RegisterRoutes(mux *http.ServeMux) {
    mux.HandleFunc(&quot;POST /orders&quot;, h.createOrder)
    mux.HandleFunc(&quot;GET /orders/&quot;, h.getOrder)
    mux.HandleFunc(&quot;POST /orders/{id}/items&quot;, h.addItem)
    mux.HandleFunc(&quot;POST /orders/{id}/complete&quot;, h.completeOrder)
}

func (h *OrderHandler) createOrder(w http.ResponseWriter, r *http.Request) {
    o, err := h.service.CreateOrder(r.Context())
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    respondJSON(w, http.StatusCreated, map[string]any{
        &quot;id&quot;:     o.ID(),
        &quot;status&quot;: o.Status(),
        &quot;total&quot;:  o.Total().Cents,
    })
}

func (h *OrderHandler) getOrder(w http.ResponseWriter, r *http.Request) {
    id := extractID(r.URL.Path)
    o, err := h.service.GetOrder(r.Context(), order.OrderID(id))
    if err != nil {
        http.Error(w, err.Error(), http.StatusNotFound)
        return
    }

    respondJSON(w, http.StatusOK, map[string]any{
        &quot;id&quot;:     o.ID(),
        &quot;status&quot;: o.Status(),
        &quot;items&quot;:  o.Items(),
        &quot;total&quot;:  o.Total().Cents,
    })
}

func (h *OrderHandler) addItem(w http.ResponseWriter, r *http.Request) {
    id := extractID(r.URL.Path)

    var req struct {
        ProductID string `json:&quot;product_id&quot;`
        Quantity  int    `json:&quot;quantity&quot;`
        PriceCents int64  `json:&quot;price_cents&quot;`
    }

    if err := json.NewDecoder(r.Body).Decode(&amp;req); err != nil {
        http.Error(w, &quot;invalid json&quot;, http.StatusBadRequest)
        return
    }

    o, err := h.service.AddItem(r.Context(), order.OrderID(id), req.ProductID, req.Quantity, req.PriceCents)
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }

    respondJSON(w, http.StatusOK, map[string]any{
        &quot;id&quot;:     o.ID(),
        &quot;status&quot;: o.Status(),
        &quot;total&quot;:  o.Total().Cents,
    })
}

func (h *OrderHandler) completeOrder(w http.ResponseWriter, r *http.Request) {
    id := extractID(r.URL.Path)
    o, err := h.service.CompleteOrder(r.Context(), order.OrderID(id))
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }

    respondJSON(w, http.StatusOK, map[string]any{
        &quot;id&quot;:     o.ID(),
        &quot;status&quot;: o.Status(),
        &quot;total&quot;:  o.Total().Cents,
    })
}

func extractID(path string) string {
    parts := strings.Split(strings.Trim(path, &quot;/&quot;), &quot;/&quot;)
    if len(parts) &gt;= 2 {
        return parts[1]
    }
    return &quot;&quot;
}

func respondJSON(w http.ResponseWriter, status int, payload any) {
    w.Header().Set(&quot;Content-Type&quot;, &quot;application/json&quot;)
    w.WriteHeader(status)
    _ = json.NewEncoder(w).Encode(payload)
}</code></pre>
<hr />
<h1>6) Application Entry Point</h1>
<h3><code>cmd/api/main.go</code></h3>
<pre><code class="lang-go language-go go">package main

import (
    &quot;log&quot;
    &quot;net/http&quot;

    httpadapter &quot;example.com/hexagonal-go/internal/adapters/http&quot;
    &quot;example.com/hexagonal-go/internal/adapters/persistence/memory&quot;
    &quot;example.com/hexagonal-go/internal/application&quot;
)

func main() {
    repo := memory.NewOrderRepository()
    service := application.NewOrderService(repo)
    handler := httpadapter.NewOrderHandler(service)

    mux := http.NewServeMux()
    handler.RegisterRoutes(mux)

    log.Println(&quot;server started on :8080&quot;)
    if err := http.ListenAndServe(&quot;:8080&quot;, mux); err != nil {
        log.Fatal(err)
    }
}</code></pre>
<hr />
<h1>7) How It Works</h1>
<ul>
<li><strong>HTTP adapter</strong> receives the request</li>
<li><strong>Application service</strong> executes the use case</li>
<li><strong>Domain</strong> applies business rules</li>
<li><strong>Repository (port)</strong> is defined in the domain</li>
<li><strong>Adapter (memory)</strong> implements it</li>
</ul>
<p>👉 The domain layer:</p>
<ul>
<li>does NOT know <code>net/http</code></li>
<li>does NOT know databases</li>
<li>does NOT know frameworks</li>
</ul>
<hr />
<h1>8) Simple Test Example</h1>
<h3><code>internal/domain/order/order_test.go</code></h3>
<pre><code class="lang-go language-go go">package order

import &quot;testing&quot;

func TestOrderCompleteWithoutItems(t *testing.T) {
    o := NewOrder(&quot;1&quot;)

    if err := o.Complete(); err == nil {
        t.Fatal(&quot;expected error when completing empty order&quot;)
    }
}

func TestOrderTotal(t *testing.T) {
    o := NewOrder(&quot;1&quot;)
    price, _ := NewMoney(500)

    if err := o.AddItem(&quot;p1&quot;, 2, price); err != nil {
        t.Fatal(err)
    }

    if o.Total().Cents != 1000 {
        t.Fatalf(&quot;expected 1000, got %d&quot;, o.Total().Cents)
    }
}</code></pre>
<hr />
<h1>9) Run the Project</h1>
<pre><code class="lang-bash language-bash bash">go run ./cmd/api</code></pre>
<p>Example requests:</p>
<pre><code class="lang-bash language-bash bash">curl -X POST localhost:8080/orders</code></pre>
<pre><code class="lang-bash language-bash bash">curl -X POST localhost:8080/orders/ord_xxx/items \
  -H 'Content-Type: application/json' \
  -d '{&quot;product_id&quot;:&quot;p1&quot;,&quot;quantity&quot;:2,&quot;price_cents&quot;:500}'</code></pre>
<pre><code class="lang-bash language-bash bash">curl -X POST localhost:8080/orders/ord_xxx/complete</code></pre>
<hr />]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Hexagonal Mimari için domain kavrami  Go (Golang)</title>
		<link>https://selmantunc.com.tr/software/hexagonal-mimari-icin-domain-kavrami-go-golang/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Mon, 13 Apr 2026 04:18:24 +0000</pubDate>
				<category><![CDATA[software]]></category>
		<guid isPermaLink="false">https://selmantunc.com.tr/?p=3538</guid>

					<description><![CDATA[Klasör yapısı hexagonal-go/ ├── go.mod ├── cmd/ │ └── api/ │ └── main.go └── internal/ ├── domain/ │ └── order/ │ ├── money.go │ ├── order.go │ ├── order_id.go │&#8230;]]></description>
										<content:encoded><![CDATA[<h2>Klasör yapısı</h2>
<pre><code class="lang-text language-text text">hexagonal-go/
├── go.mod
├── cmd/
│   └── api/
│       └── main.go
└── internal/
    ├── domain/
    │   └── order/
    │       ├── money.go
    │       ├── order.go
    │       ├── order_id.go
    │       ├── order_status.go
    │       └── repository.go
    ├── application/
    │   └── order_service.go
    └── adapters/
        ├── http/
        │   └── order_handler.go
        └── persistence/
            └── memory/
                └── order_repository.go</code></pre>
<hr />
<h2>1) <code>go.mod</code></h2>
<pre><code class="lang-go language-go go">module example.com/hexagonal-go

go 1.22</code></pre>
<hr />
<h2>2) Domain katmanı</h2>
<h3><code>internal/domain/order/order_id.go</code></h3>
<pre><code class="lang-go language-go go">package order

type OrderID string</code></pre>
<h3><code>internal/domain/order/order_status.go</code></h3>
<pre><code class="lang-go language-go go">package order

type OrderStatus string

const (
    OrderStatusCreated   OrderStatus = &quot;CREATED&quot;
    OrderStatusCompleted OrderStatus = &quot;COMPLETED&quot;
)</code></pre>
<h3><code>internal/domain/order/money.go</code></h3>
<pre><code class="lang-go language-go go">package order

import &quot;fmt&quot;

type Money struct {
    Cents int64
}

func NewMoney(cents int64) (Money, error) {
    if cents &lt; 0 {
        return Money{}, fmt.Errorf(&quot;money cannot be negative&quot;)
    }
    return Money{Cents: cents}, nil
}

func (m Money) Add(other Money) Money {
    return Money{Cents: m.Cents + other.Cents}
}</code></pre>
<h3><code>internal/domain/order/order.go</code></h3>
<pre><code class="lang-go language-go go">package order

import &quot;fmt&quot;

type OrderItem struct {
    ProductID string
    Quantity  int
    UnitPrice Money
}

type Order struct {
    id     OrderID
    items  []OrderItem
    status OrderStatus
}

func NewOrder(id OrderID) *Order {
    return &amp;Order{
        id:     id,
        items:  make([]OrderItem, 0),
        status: OrderStatusCreated,
    }
}

func (o *Order) ID() OrderID {
    return o.id
}

func (o *Order) Status() OrderStatus {
    return o.status
}

func (o *Order) Items() []OrderItem {
    copied := make([]OrderItem, len(o.items))
    copy(copied, o.items)
    return copied
}

func (o *Order) AddItem(productID string, quantity int, unitPrice Money) error {
    if o.status != OrderStatusCreated {
        return fmt.Errorf(&quot;order cannot be modified after completion&quot;)
    }
    if productID == &quot;&quot; {
        return fmt.Errorf(&quot;product id cannot be empty&quot;)
    }
    if quantity &lt;= 0 {
        return fmt.Errorf(&quot;quantity must be greater than zero&quot;)
    }

    o.items = append(o.items, OrderItem{
        ProductID: productID,
        Quantity:  quantity,
        UnitPrice: unitPrice,
    })

    return nil
}

func (o *Order) Complete() error {
    if len(o.items) == 0 {
        return fmt.Errorf(&quot;order must have at least one item&quot;)
    }
    o.status = OrderStatusCompleted
    return nil
}

func (o *Order) Total() Money {
    total := Money{Cents: 0}
    for _, item := range o.items {
        total = total.Add(Money{Cents: item.UnitPrice.Cents * int64(item.Quantity)})
    }
    return total
}</code></pre>
<h3><code>internal/domain/order/repository.go</code></h3>
<pre><code class="lang-go language-go go">package order

import &quot;context&quot;

type Repository interface {
    Save(ctx context.Context, order *Order) error
    FindByID(ctx context.Context, id OrderID) (*Order, error)
}</code></pre>
<hr />
<h2>3) Application katmanı</h2>
<h3><code>internal/application/order_service.go</code></h3>
<pre><code class="lang-go language-go go">package application

import (
    &quot;context&quot;
    &quot;fmt&quot;
    &quot;time&quot;

    &quot;example.com/hexagonal-go/internal/domain/order&quot;
)

type OrderService struct {
    repo order.Repository
}

func NewOrderService(repo order.Repository) *OrderService {
    return &amp;OrderService{repo: repo}
}

func (s *OrderService) CreateOrder(ctx context.Context) (*order.Order, error) {
    id := order.OrderID(fmt.Sprintf(&quot;ord_%d&quot;, time.Now().UnixNano()))
    newOrder := order.NewOrder(id)

    if err := s.repo.Save(ctx, newOrder); err != nil {
        return nil, err
    }

    return newOrder, nil
}

func (s *OrderService) AddItem(ctx context.Context, orderID order.OrderID, productID string, quantity int, priceCents int64) (*order.Order, error) {
    o, err := s.repo.FindByID(ctx, orderID)
    if err != nil {
        return nil, err
    }

    price, err := order.NewMoney(priceCents)
    if err != nil {
        return nil, err
    }

    if err := o.AddItem(productID, quantity, price); err != nil {
        return nil, err
    }

    if err := s.repo.Save(ctx, o); err != nil {
        return nil, err
    }

    return o, nil
}

func (s *OrderService) CompleteOrder(ctx context.Context, orderID order.OrderID) (*order.Order, error) {
    o, err := s.repo.FindByID(ctx, orderID)
    if err != nil {
        return nil, err
    }

    if err := o.Complete(); err != nil {
        return nil, err
    }

    if err := s.repo.Save(ctx, o); err != nil {
        return nil, err
    }

    return o, nil
}

func (s *OrderService) GetOrder(ctx context.Context, orderID order.OrderID) (*order.Order, error) {
    return s.repo.FindByID(ctx, orderID)
}</code></pre>
<hr />
<h2>4) Persistence adapter (in-memory)</h2>
<h3><code>internal/adapters/persistence/memory/order_repository.go</code></h3>
<pre><code class="lang-go language-go go">package memory

import (
    &quot;context&quot;
    &quot;fmt&quot;
    &quot;sync&quot;

    &quot;example.com/hexagonal-go/internal/domain/order&quot;
)

type OrderRepository struct {
    mu     sync.RWMutex
    orders map[order.OrderID]*order.Order
}

func NewOrderRepository() *OrderRepository {
    return &amp;OrderRepository{
        orders: make(map[order.OrderID]*order.Order),
    }
}

func (r *OrderRepository) Save(ctx context.Context, o *order.Order) error {
    r.mu.Lock()
    defer r.mu.Unlock()

    r.orders[o.ID()] = o
    return nil
}

func (r *OrderRepository) FindByID(ctx context.Context, id order.OrderID) (*order.Order, error) {
    r.mu.RLock()
    defer r.mu.RUnlock()

    o, ok := r.orders[id]
    if !ok {
        return nil, fmt.Errorf(&quot;order not found: %s&quot;, id)
    }

    return o, nil
}</code></pre>
<hr />
<h2>5) HTTP adapter</h2>
<h3><code>internal/adapters/http/order_handler.go</code></h3>
<pre><code class="lang-go language-go go">package httpadapter

import (
    &quot;encoding/json&quot;
    &quot;net/http&quot;
    &quot;strings&quot;

    &quot;example.com/hexagonal-go/internal/application&quot;
    &quot;example.com/hexagonal-go/internal/domain/order&quot;
)

type OrderHandler struct {
    service *application.OrderService
}

func NewOrderHandler(service *application.OrderService) *OrderHandler {
    return &amp;OrderHandler{service: service}
}

func (h *OrderHandler) RegisterRoutes(mux *http.ServeMux) {
    mux.HandleFunc(&quot;POST /orders&quot;, h.createOrder)
    mux.HandleFunc(&quot;GET /orders/&quot;, h.getOrder)
    mux.HandleFunc(&quot;POST /orders/{id}/items&quot;, h.addItem)
    mux.HandleFunc(&quot;POST /orders/{id}/complete&quot;, h.completeOrder)
}

func (h *OrderHandler) createOrder(w http.ResponseWriter, r *http.Request) {
    o, err := h.service.CreateOrder(r.Context())
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    respondJSON(w, http.StatusCreated, map[string]any{
        &quot;id&quot;:     o.ID(),
        &quot;status&quot;: o.Status(),
        &quot;total&quot;:  o.Total().Cents,
    })
}

func (h *OrderHandler) getOrder(w http.ResponseWriter, r *http.Request) {
    id := extractID(r.URL.Path)
    o, err := h.service.GetOrder(r.Context(), order.OrderID(id))
    if err != nil {
        http.Error(w, err.Error(), http.StatusNotFound)
        return
    }

    respondJSON(w, http.StatusOK, map[string]any{
        &quot;id&quot;:     o.ID(),
        &quot;status&quot;: o.Status(),
        &quot;items&quot;:  o.Items(),
        &quot;total&quot;:  o.Total().Cents,
    })
}

func (h *OrderHandler) addItem(w http.ResponseWriter, r *http.Request) {
    id := extractID(r.URL.Path)

    var req struct {
        ProductID string `json:&quot;product_id&quot;`
        Quantity  int    `json:&quot;quantity&quot;`
        PriceCents int64  `json:&quot;price_cents&quot;`
    }

    if err := json.NewDecoder(r.Body).Decode(&amp;req); err != nil {
        http.Error(w, &quot;invalid json&quot;, http.StatusBadRequest)
        return
    }

    o, err := h.service.AddItem(r.Context(), order.OrderID(id), req.ProductID, req.Quantity, req.PriceCents)
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }

    respondJSON(w, http.StatusOK, map[string]any{
        &quot;id&quot;:     o.ID(),
        &quot;status&quot;: o.Status(),
        &quot;total&quot;:  o.Total().Cents,
    })
}

func (h *OrderHandler) completeOrder(w http.ResponseWriter, r *http.Request) {
    id := extractID(r.URL.Path)
    o, err := h.service.CompleteOrder(r.Context(), order.OrderID(id))
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }

    respondJSON(w, http.StatusOK, map[string]any{
        &quot;id&quot;:     o.ID(),
        &quot;status&quot;: o.Status(),
        &quot;total&quot;:  o.Total().Cents,
    })
}

func extractID(path string) string {
    parts := strings.Split(strings.Trim(path, &quot;/&quot;), &quot;/&quot;)
    if len(parts) &gt;= 2 {
        return parts[1]
    }
    return &quot;&quot;
}

func respondJSON(w http.ResponseWriter, status int, payload any) {
    w.Header().Set(&quot;Content-Type&quot;, &quot;application/json&quot;)
    w.WriteHeader(status)
    _ = json.NewEncoder(w).Encode(payload)
}</code></pre>
<hr />
<h2>6) Uygulama başlangıcı</h2>
<h3><code>cmd/api/main.go</code></h3>
<pre><code class="lang-go language-go go">package main

import (
    &quot;log&quot;
    &quot;net/http&quot;

    httpadapter &quot;example.com/hexagonal-go/internal/adapters/http&quot;
    &quot;example.com/hexagonal-go/internal/adapters/persistence/memory&quot;
    &quot;example.com/hexagonal-go/internal/application&quot;
)

func main() {
    repo := memory.NewOrderRepository()
    service := application.NewOrderService(repo)
    handler := httpadapter.NewOrderHandler(service)

    mux := http.NewServeMux()
    handler.RegisterRoutes(mux)

    log.Println(&quot;server started on :8080&quot;)
    if err := http.ListenAndServe(&quot;:8080&quot;, mux); err != nil {
        log.Fatal(err)
    }
}</code></pre>
<hr />
<h2>7) Akış nasıl çalışıyor?</h2>
<ul>
<li><strong>HTTP adapter</strong> isteği alır.</li>
<li><strong>Application service</strong> use-case’i yürütür.</li>
<li><strong>Domain</strong> iş kurallarını uygular.</li>
<li><strong>Repository port</strong> domain tarafından tanımlanır.</li>
<li><strong>Memory adapter</strong> bu portu implement eder.</li>
</ul>
<p>Bu yapı sayesinde domain katmanı:</p>
<ul>
<li><code>net/http</code> bilmez,</li>
<li>database bilmez,</li>
<li>framework bilmez.</li>
</ul>
<hr />
<h2>8) Kısa test örneği</h2>
<h3><code>internal/domain/order/order_test.go</code></h3>
<pre><code class="lang-go language-go go">package order

import &quot;testing&quot;

func TestOrderCompleteWithoutItems(t *testing.T) {
    o := NewOrder(&quot;1&quot;)

    if err := o.Complete(); err == nil {
        t.Fatal(&quot;expected error when completing empty order&quot;)
    }
}

func TestOrderTotal(t *testing.T) {
    o := NewOrder(&quot;1&quot;)
    price, _ := NewMoney(500)

    if err := o.AddItem(&quot;p1&quot;, 2, price); err != nil {
        t.Fatal(err)
    }

    if o.Total().Cents != 1000 {
        t.Fatalf(&quot;expected 1000, got %d&quot;, o.Total().Cents)
    }
}</code></pre>
<hr />
<h2>9) Çalıştırma</h2>
<pre><code class="lang-bash language-bash bash">go run ./cmd/api</code></pre>
<p>Örnek istek:</p>
<pre><code class="lang-bash language-bash bash">curl -X POST localhost:8080/orders</code></pre>
<pre><code class="lang-bash language-bash bash">curl -X POST localhost:8080/orders/ord_xxx/items \
  -H 'Content-Type: application/json' \
  -d '{&quot;product_id&quot;:&quot;p1&quot;,&quot;quantity&quot;:2,&quot;price_cents&quot;:500}'</code></pre>
<pre><code class="lang-bash language-bash bash">curl -X POST localhost:8080/orders/ord_xxx/complete</code></pre>
<hr />]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Chrome Security and Passive Mode Risks</title>
		<link>https://selmantunc.com.tr/software/chrome-security-and-passive-mode-risks/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Thu, 05 Mar 2026 07:06:24 +0000</pubDate>
				<category><![CDATA[software]]></category>
		<guid isPermaLink="false">https://selmantunc.com.tr/?p=3527</guid>

					<description><![CDATA[No, technically, a completely disabled (deactivated) Chrome extension cannot steal new information or monitor your current browsing activity. When an extension is disabled, it is not loaded into the browser&#8217;s&#8230;]]></description>
										<content:encoded><![CDATA[<p>No, technically, a completely <strong>disabled</strong> (deactivated) Chrome extension cannot steal new information or monitor your current browsing activity. When an extension is disabled, it is not loaded into the browser&#8217;s memory and its background processes are terminated. <a href="https://support.google.com/chrome/thread/11119336/can-chrome-extensions-affect-computer-performance-even-if-they-are-turned-off?hl=en">support.google</a></p>
<p>However, there are two critical security nuances to consider:</p>
<h3>Residual Risks in Open Tabs</h3>
<p>If a malicious extension was active and you disabled it while having several tabs open, its &#8220;content scripts&#8221; might still be running in those specific pages until they are refreshed. <a href="https://stackoverflow.com/questions/69368249/what-data-is-accessible-to-a-disabled-chrome-extension">stackoverflow</a></p>
<ul>
<li>These scripts could potentially leak data through indirect methods like hidden images or CSS if the site&#8217;s Content Security Policy (CSP) is weak. <a href="https://stackoverflow.com/questions/69368249/what-data-is-accessible-to-a-disabled-chrome-extension">stackoverflow</a></li>
<li><strong>Solution:</strong> You must refresh all open tabs or restart your browser after disabling an extension to ensure all its scripts are fully cleared. <a href="https://stackoverflow.com/questions/69368249/what-data-is-accessible-to-a-disabled-chrome-extension">stackoverflow</a></li>
</ul>
<h3>Previously Stolen Data</h3>
<p>Disabling an extension only stops <strong>future</strong> data collection; it does not &#8220;undo&#8221; what was already stolen while the extension was active. <a href="https://www.youtube.com/watch?v=Rhxz_i8rDcM">youtube</a></p>
<ul>
<li>If a malicious extension captured your passwords, session cookies, or personal data while it was enabled, that information is likely already stored on the attacker&#8217;s server (C2 server). <a href="https://www.linkedin.com/pulse/warning-malicious-chrome-extensions-steal-your-gtrae">linkedin</a></li>
<li>Attackers often use stolen session tokens to maintain access to your accounts even after the extension is deleted. <a href="https://thehackernews.com/2026/02/malicious-chrome-extensions-caught.html">thehackernews</a></li>
</ul>
<h3>Extension Status Comparison</h3>
<p>The following table illustrates the capabilities of an extension based on its state:</p>
<table>
<thead>
<tr>
<th style="text-align: left">Status</th>
<th style="text-align: left">Web Page Access</th>
<th style="text-align: left">Real-time Data Leak</th>
<th style="text-align: left">Historical Data Risk</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left"><strong>Enabled</strong></td>
<td style="text-align: left">Full Access  <a href="https://www.reddit.com/r/chrome/comments/1ckcd1s/can_chrome_extensions_scrape_my_pages_and_steal/">reddit</a></td>
<td style="text-align: left">High  <a href="https://www.youtube.com/watch?v=Rhxz_i8rDcM">youtube</a></td>
<td style="text-align: left">Continuous Access</td>
</tr>
<tr>
<td style="text-align: left"><strong>Disabled</strong></td>
<td style="text-align: left">Blocked  <a href="https://support.google.com/chrome/thread/11119336/can-chrome-extensions-affect-computer-performance-even-if-they-are-turned-off?hl=en">support.google</a></td>
<td style="text-align: left">Very Low (Residual)</td>
<td style="text-align: left">Stored on External Server</td>
</tr>
<tr>
<td style="text-align: left"><strong>Removed</strong></td>
<td style="text-align: left">Impossible</td>
<td style="text-align: left">Impossible</td>
<td style="text-align: left">Stored on External Server</td>
</tr>
</tbody>
</table>
<p>If you suspect an extension is malicious, simply disabling it is not enough. You should <strong>remove</strong> it entirely, clear your browser cookies, and change your passwords for sensitive accounts. <a href="https://support.google.com/chrome/thread/306226825/chrome-extensions-might-steal-passwords?hl=en">support.google</a></p>
<p>Which specific extension are you concerned about?</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Google Chrome&#8217;da bir eklentiyi tamamen devre dışı (deactive) birakinca bilgi calabilir mi?</title>
		<link>https://selmantunc.com.tr/software/google-chromeda-bir-eklentiyi-tamamen-devre-disi-deactive-birakinca-bilgi-calabilir-mi/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Thu, 05 Mar 2026 07:05:31 +0000</pubDate>
				<category><![CDATA[software]]></category>
		<guid isPermaLink="false">https://selmantunc.com.tr/?p=3525</guid>

					<description><![CDATA[Hayır, Google Chrome&#8217;da bir eklentiyi tamamen devre dışı (deactive) bırakmak, o eklentinin yeni veri toplamasını veya çalmasını teknik olarak engeller. Eklenti pasif durumdayken tarayıcı belleğine yüklenmez ve web sayfalarındaki trafiğinize&#8230;]]></description>
										<content:encoded><![CDATA[<p>Hayır, Google Chrome&#8217;da bir eklentiyi tamamen devre dışı (deactive) bırakmak, o eklentinin yeni veri toplamasını veya çalmasını teknik olarak engeller. Eklenti pasif durumdayken tarayıcı belleğine yüklenmez ve web sayfalarındaki trafiğinize müdahale edemez. <a href="https://support.google.com/chrome/thread/11119336/can-chrome-extensions-affect-computer-performance-even-if-they-are-turned-off?hl=en">support.google</a></p>
<p>Ancak güvenlik açısından dikkat edilmesi gereken iki önemli istisna bulunmaktadır:</p>
<h3>Aktif Sekmelerdeki Kalıntı Riskler</h3>
<p>Bir eklentiyi devre dışı bıraktığınız an, o sırada açık olan sekmelerde halihazırda enjekte edilmiş olan &#8220;içerik betikleri&#8221; (content scripts) çalışmaya devam edebilir. <a href="https://stackoverflow.com/questions/69368249/what-data-is-accessible-to-a-disabled-chrome-extension">stackoverflow</a></p>
<ul>
<li>Bu betikler eklenti merkezine veri gönderemez ancak sitenin kendi güvenlik politikası (CSP) zayıfsa, verileri gizli görseller veya CSS üzerinden dışarı sızdırmaya çalışabilir. <a href="https://stackoverflow.com/questions/69368249/what-data-is-accessible-to-a-disabled-chrome-extension">stackoverflow</a></li>
<li><strong>Çözüm:</strong> Eklentiyi kapattıktan sonra açık olan tüm sekmeleri yenilemek (Refresh) bu riski tamamen ortadan kaldırır. <a href="https://stackoverflow.com/questions/69368249/what-data-is-accessible-to-a-disabled-chrome-extension">stackoverflow</a></li>
</ul>
<h3>Geçmişte Toplanan Veriler</h3>
<p>Eklentinin devre dışı bırakılması sadece gelecekteki veri akışını keser.</p>
<ul>
<li>Eğer eklenti aktif olduğu süre boyunca şifrelerinizi, çerezlerinizi (cookies) veya kişisel verilerinizi uzak bir sunucuya (C2 server) gönderdiyse, bu veriler saldırganın elinde kalmaya devam eder. <a href="https://www.youtube.com/watch?v=Rhxz_i8rDcM">youtube</a></li>
<li>Kötü niyetli eklentiler genellikle oturum jetonlarını (session tokens) çalarak, siz eklentiyi silseniz bile hesaplarınıza erişim sağlamaya devam edebilir. <a href="https://www.linkedin.com/pulse/warning-malicious-chrome-extensions-steal-your-gtrae">linkedin</a></li>
</ul>
<h3>Güvenli Kullanım Tablosu</h3>
<p>Eklenti durumuna göre yetki ve risk dağılımı şu şekildedir:</p>
<table>
<thead>
<tr>
<th style="text-align: left">Durum</th>
<th style="text-align: left">Web Sayfası Okuma</th>
<th style="text-align: left">Veri Sızdırma</th>
<th style="text-align: left">Geçmiş Veri Erişimi</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left"><strong>Aktif</strong></td>
<td style="text-align: left">Tam Yetki  <a href="https://www.reddit.com/r/chrome/comments/1ckcd1s/can_chrome_extensions_scrape_my_pages_and_steal/">reddit</a></td>
<td style="text-align: left">Mümkün  <a href="https://www.youtube.com/watch?v=Rhxz_i8rDcM">youtube</a></td>
<td style="text-align: left">Sürekli Erişim</td>
</tr>
<tr>
<td style="text-align: left"><strong>Devre Dışı</strong></td>
<td style="text-align: left">Engellenir  <a href="https://support.google.com/chrome/thread/11119336/can-chrome-extensions-affect-computer-performance-even-if-they-are-turned-off?hl=en">support.google</a></td>
<td style="text-align: left">Çok Düşük (Kalıntı Betik)</td>
<td style="text-align: left">Saldırganın Sunucusunda Saklı</td>
</tr>
<tr>
<td style="text-align: left"><strong>Kaldırılmış</strong></td>
<td style="text-align: left">İmkansız</td>
<td style="text-align: left">İmkansız</td>
<td style="text-align: left">Saldırganın Sunucusunda Saklı</td>
</tr>
</tbody>
</table>
<p>Şüphelendiğiniz bir eklenti varsa sadece devre dışı bırakmak yerine doğrudan <strong>kaldırmanız</strong> ve ardından tarayıcı çerezlerini temizleyerek şifrelerinizi değiştirmeniz en güvenli yoldur. <a href="https://thehackernews.com/2026/02/malicious-chrome-extensions-caught.html">thehackernews</a></p>
<p>Hangi eklenti hakkında bu endişeyi taşıyorsunuz?</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Türkiye dil eğitiminde neden geride kalıyor</title>
		<link>https://selmantunc.com.tr/software/turkiye-dil-egitiminde-neden-geride-kaliyor/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Fri, 27 Feb 2026 10:30:45 +0000</pubDate>
				<category><![CDATA[software]]></category>
		<guid isPermaLink="false">https://selmantunc.com.tr/?p=3508</guid>

					<description><![CDATA[Türkiye, EF İngilizce Yeterlilik Endeksi&#8217;nde 2025&#8217;te 123 ülke arasında 71. sırada (488 puanla düşük seviye) ve Avrupa&#8217;da sondan ikinci konumda kalıyor; bu gerileme eğitim sistemindeki kronik sorunlardan kaynaklanıyor. youtube Eğitim&#8230;]]></description>
										<content:encoded><![CDATA[<p>Türkiye, EF İngilizce Yeterlilik Endeksi&#8217;nde 2025&#8217;te 123 ülke arasında 71. sırada (488 puanla düşük seviye) ve Avrupa&#8217;da sondan ikinci konumda kalıyor; bu gerileme eğitim sistemindeki kronik sorunlardan kaynaklanıyor.  <a href="https://www.youtube.com/watch?v=aC4AnOifMvQ">youtube</a></p>
<h2>Eğitim Sistemi Sorunları</h2>
<p>Yıllarca İngilizce dersi alınmasına rağmen konuşma becerisi düşük çünkü sistem ezber ve gramer odaklı; sınav baskısı (test-tost arasında sıkışma) üretken becerileri (konuşma-yazma) engelliyor.  <a href="https://www.youtube.com/watch?v=aC4AnOifMvQ">youtube</a>
Hazırlık sınıflarının kaldırılması ve kalitesiz materyaller/hocalar yeterliliği düşürüyor; 1000 saat ders sonrası %90 konuşamama oranı görülüyor.  <a href="https://tepav.org.tr/en/blog/s/4381">tepav.org</a></p>
<h2>Diğer Etkenler</h2>
<p>Sınıf ortamında yeterli maruziyet ve pratik eksikliği var; gençlerde pandemi sonrası toparlanma yok, 40+ yaşta ise gerileme belirgin.  <a href="https://tr.investing.com/news/general-news/ef-ingilizce-yeterlilik-endeksine-gore-turkiye-123-ulke-arasnda-71inci-srada-yer-ald-3646116">tr.investing</a>
Psikolojik nedenler (motivasyon kaybı) ve ana dilde eğitim tartışmaları İngilizceyi gölgeliyor; TOEFL skorları Sudan&#8217;la aynı seviyede.  <a href="https://tepav.org.tr/en/blog/s/4381">tepav.org</a></p>
<table>
<thead>
<tr>
<th>Sorun Alanı</th>
<th>Açıklama</th>
<th>Kaynak</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sınav Baskısı</td>
<td>Konuşma yerine test odaklı</td>
<td><a href="https://www.youtube.com/watch?v=aC4AnOifMvQ">youtube</a></td>
</tr>
<tr>
<td>Kalitesiz Eğitim</td>
<td>Kötü hocalar/kitaplar</td>
<td><a href="https://www.youtube.com/watch?v=42XXdrK8dlM">youtube</a></td>
</tr>
<tr>
<td>Pratik Eksikliği</td>
<td>Maruziyet yetersiz</td>
<td><a href="https://www.youtube.com/watch?v=aC4AnOifMvQ">youtube</a></td>
</tr>
<tr>
<td>Politika Değişiklikleri</td>
<td>Hazırlık sınıfları kalktı</td>
<td><a href="https://tepav.org.tr/en/blog/s/4381">tepav.org</a></td>
</tr>
</tbody>
</table>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>n8n compares Zapier and Make: which one is more advantageous for medium-sized businesses in the long run?</title>
		<link>https://selmantunc.com.tr/software/n8n-compares-zapier-and-make-which-one-is-more-advantageous-for-medium-sized-businesses-in-the-long-run/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Sun, 22 Feb 2026 02:59:07 +0000</pubDate>
				<category><![CDATA[software]]></category>
		<guid isPermaLink="false">https://selmantunc.com.tr/?p=3502</guid>

					<description><![CDATA[For a medium‑sized business, n8n (especially self‑hosted) is usually best long‑term if you have technical people, while Make is often the best balance for mixed or non‑technical teams, and Zapier&#8230;]]></description>
										<content:encoded><![CDATA[<p>For a medium‑sized business, <strong>n8n (especially self‑hosted) is usually best long‑term if you have technical people</strong>, while <strong>Make is often the best balance for mixed or non‑technical teams</strong>, and Zapier tends to be the most expensive and restrictive at scale.  Zapier is excellent for quick wins and very simple setups, but its task‑based pricing and limited workflow flexibility often make it the weakest long‑term choice once volume and complexity grow. <a href="https://www.digidop.com/blog/n8n-vs-make-vs-zapier">digidop</a></p>
<h2>High‑level summary</h2>
<p>For a growing, medium‑sized business that expects to automate more and more over time:</p>
<ul>
<li><strong>Choose n8n</strong> if you have developers/DevOps, care about data control, and want the lowest long‑term total cost of ownership.</li>
<li><strong>Choose Make</strong> if you want powerful visual workflows and good pricing but prefer not to run your own infrastructure.</li>
<li><strong>Use Zapier sparingly</strong> for very simple, low‑volume automations or where its huge app catalog is a hard requirement.  </li>
</ul>
<p><a href="https://parseur.com/blog/zapier-n8n-make">parseur</a></p>
<hr />
<h2>Quick comparison table</h2>
<table>
<thead>
<tr>
<th>Criterion</th>
<th>Zapier</th>
<th>Make</th>
<th>n8n</th>
</tr>
</thead>
<tbody>
<tr>
<td>Pricing model</td>
<td>Task‑based: each step/action is a task, including filters/formatters; complex flows become very expensive.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>Operation/credit‑based: each module/action spends credits; cheaper than Zapier for most real‑world scenarios, but still consumption‑based.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>Execution‑based: one workflow run = one execution, regardless of steps; shines for complex and AI‑heavy flows.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
</tr>
<tr>
<td>Typical cost (≈10k ops/month)</td>
<td>10k tasks/month can easily push you into 200+ USD/month territory.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>10k operations/month is around 9–11 USD/month on entry plans.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>Self‑host: software is free; a VPS for many SMB workloads is ≈20 USD/month. Cloud: ≈60 USD/month for 10k executions.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
</tr>
<tr>
<td>Self‑hosting</td>
<td>Not available, 100% SaaS.  <a href="https://parseur.com/blog/zapier-n8n-make">parseur</a></td>
<td>Not available, 100% SaaS.  <a href="https://parseur.com/blog/zapier-n8n-make">parseur</a></td>
<td>Fully supported; open‑source/fair‑code with Docker, Kubernetes, etc.  <a href="https://summarizemeeting.com/en/comparison/automation-platforms">summarizemeeting</a></td>
</tr>
<tr>
<td>Integrations</td>
<td>≈6–8k+ apps, largest library on the market.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>≈1.5–2k integrations; fewer than Zapier but generally deeper connectors.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>≈1k native nodes, but can talk to any public API via HTTP/custom code.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
</tr>
<tr>
<td>Ease of use</td>
<td>Easiest: linear trigger‑action model, templates, very low learning curve for business users.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>Visual canvas with branches, routers, error routes; more powerful, moderate learning curve.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>Node‑based, closer to dev tool; requires setup and at least some coding comfort.  <a href="https://summarizemeeting.com/en/comparison/automation-platforms">summarizemeeting</a></td>
</tr>
<tr>
<td>Ideal audience</td>
<td>Non‑technical teams with simple, low‑volume automations.  <a href="https://parseur.com/blog/zapier-n8n-make">parseur</a></td>
<td>Power users, operations/marketing teams, and SMBs needing complex flows without infra management.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>Technical teams, data‑sensitive orgs, and high‑volume/AI‑heavy use cases.  <a href="https://summarizemeeting.com/en/comparison/automation-platforms">summarizemeeting</a></td>
</tr>
</tbody>
</table>
<hr />
<h2>Cost and scalability over the long term</h2>
<p>Zapier counts <strong>every step as a task</strong>, including filters, formatters, and branches, so any non‑trivial workflow multiplies your task usage.  That makes it very predictable but also very expensive once you hit thousands or tens of thousands of records per month; many reviews show Zapier becoming the costliest of the three at medium–high scale. <a href="https://lumberjack.so/n8n-vs-zapier-vs-make-the-honest-2026-comparison/">lumberjack</a></p>
<p>Make’s operation‑based billing is significantly more forgiving. The free tier gives 1,000 operations, and around 9–10 USD/month buys you 10,000 operations, often 40–60% cheaper than a comparable Zapier workload.  However, it is still consumption‑based: badly designed or very chatty workflows (especially with AI modules) can burn through credits faster than expected. <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></p>
<p>With n8n, self‑hosting removes per‑task licensing altogether: you pay for infrastructure only, and execution‑based counting (in cloud plans) means a 5‑step flow and a 200‑step AI agent can both cost “1 execution” if they run once.  At medium and high complexity, this often translates into <strong>order‑of‑magnitude</strong> savings versus Zapier and clear savings versus Make, especially if you’re comfortable tuning your own server. <a href="https://xcloud.host/n8n-vs-make-vs-zapier-which-automation-tool-should-you-choose/">xcloud</a></p>
<hr />
<h2>Technical flexibility, self‑hosting, and data control</h2>
<p>Zapier and Make are pure SaaS: you get vendor‑managed security, uptime, and scaling, but your data must flow through their cloud and remain within their compliance boundaries.  For many SMBs this is fine; for regulated industries, strict data‑residency requirements, or customers who require on‑prem options, this can be a blocker. <a href="https://summarizemeeting.com/en/comparison/automation-platforms">summarizemeeting</a></p>
<p>n8n’s biggest differentiator is <strong>self‑hosting</strong>: you can run it on your own infrastructure (or a dedicated VPS), keep data within your own network/VPC, and control latency, retention, and throughput limits yourself.  That makes it very attractive for medium‑sized companies that either already run containers/servers or are willing to invest in that capability, because you are no longer locked into a vendor’s rate limits and roadmaps. <a href="https://contabo.com/blog/n8n-vs-zapier-vs-make-an-in-depth-comparison/">contabo</a></p>
<hr />
<h2>Integrations and UX</h2>
<p>Zapier has the <strong>widest app catalog</strong>, so for very niche SaaS tools it often “just works” without custom HTTP work.  Its linear trigger‑→‑action model and library of templates let marketing, sales, and ops teams build simple flows (like “when a new lead is created, send a Slack message and add to a sheet”) with almost no guidance. <a href="https://www.digidop.com/blog/n8n-vs-make-vs-zapier">digidop</a></p>
<p>Make’s canvas‑style editor is much better for <strong>visually complex</strong> flows: you can see branches, error paths, and parallel routes on a single diagram, which is extremely useful for medium‑sized businesses with tangled processes.  Connectors often expose deeper object fields than the Zapier equivalents, and built‑in transformers make it easy to massage data without code. <a href="https://lumberjack.so/n8n-vs-zapier-vs-make-the-honest-2026-comparison/">lumberjack</a></p>
<p>n8n’s editor also uses a node‑based graph, but leans more toward a <strong>developer‑friendly tool</strong>: custom JavaScript, HTTP nodes, and advanced logic are standard, and you can extend it with your own nodes or packages.  The trade‑off is that non‑technical users generally need some enablement; n8n is superb as a central automation “platform” owned by engineering, less so as a self‑service toy for every department. <a href="https://www.reddit.com/r/SaaS/comments/1r3op4c/the_brutal_truth_about_n8n_vs_zapier_vs_make_vs/">reddit</a></p>
<hr />
<h2>AI and advanced automation</h2>
<p>Zapier focuses on <strong>making AI easy</strong>, not deep: natural‑language automation builders and simple ChatGPT/OpenAI steps that any user can drop into flows.  This works well for simple classification or content‑generation tasks but offers limited control over advanced agent‑style patterns. <a href="https://parseur.com/blog/zapier-n8n-make">parseur</a></p>
<p>Make gives you strong AI connectors (OpenAI and others) and lets you wire them into complex routes and transformations; however, AI modules consume operations, which can push bills up for heavy usage. <a href="https://thinkpeak.ai/make-com-pricing-hidden-costs-2026/">thinkpeak</a></p>
<p>n8n currently leads on <strong>technical AI depth</strong>: LangChain nodes, support for multiple LLM providers, and the ability to compose RAG pipelines and agents directly in workflows.  Combined with execution‑based pricing and self‑hosting, this makes n8n particularly attractive for medium‑sized companies planning to run serious AI workloads (document QA, routing, enrichment, ticket triage, etc.) through automation. <a href="https://blog.n8n.io/best-ai-workflow-automation-tools/">blog.n8n</a></p>
<hr />
<h2>Practical guidance for medium‑sized businesses</h2>
<ul>
<li>
<p><strong>If you have real dev/DevOps capacity and automation is strategic</strong><br />
Use <strong>n8n as your core automation layer</strong>, preferably self‑hosted. You get long‑term cost control, strong AI capabilities, and full data sovereignty, at the price of some infra and governance work. <a href="https://xcloud.host/n8n-vs-make-vs-zapier-which-automation-tool-should-you-choose/">xcloud</a></p>
</li>
<li>
<p><strong>If your technical capacity is limited but business teams want complex workflows</strong><br />
<strong>Make</strong> is usually the sweet spot: far cheaper and more powerful than Zapier for medium‑complexity flows, but still SaaS and relatively easy to onboard power users onto. <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></p>
</li>
<li>
<p><strong>If you mainly need a few simple automations and ultra‑fast non‑technical adoption</strong><br />
<strong>Zapier</strong> can still be the right choice, especially in the early stage or for isolated use cases—just be aware that if volume and complexity grow, migration to Make or n8n is a likely future step. <a href="https://www.digidop.com/blog/n8n-vs-make-vs-zapier">digidop</a></p>
</li>
</ul>
<p>Given your background (strong engineering, comfortable with Docker and backends), for any company you build or advise, a <strong>hybrid of “n8n as the backbone + Make for certain visual/no‑code friendly flows”</strong> will almost always give the best long‑term mix of cost, control, and usability. <a href="https://summarizemeeting.com/en/comparison/automation-platforms">summarizemeeting</a></p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>n8n ile Zapier ve Make karşılaştırması: hangisi orta ölçekli işletmeler için uzun vadede daha avantajlı</title>
		<link>https://selmantunc.com.tr/software/n8n-ile-zapier-ve-make-karsilastirmasi-hangisi-orta-olcekli-isletmeler-icin-uzun-vadede-daha-avantajli/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Sun, 22 Feb 2026 02:58:19 +0000</pubDate>
				<category><![CDATA[software]]></category>
		<guid isPermaLink="false">https://selmantunc.com.tr/?p=3499</guid>

					<description><![CDATA[Orta ölçekli, uzun vadede büyüyecek bir işletme için genellikle teknik ekibiniz varsa n8n (özellikle self‑host), teknik olmayan ekiplerin de yoğun kullanacağı senaryolarda ise Make, Zapier’e göre daha avantajlıdır. Zapier kısa&#8230;]]></description>
										<content:encoded><![CDATA[<p>Orta ölçekli, uzun vadede büyüyecek bir işletme için genellikle <strong>teknik ekibiniz varsa n8n (özellikle self‑host)</strong>, teknik olmayan ekiplerin de yoğun kullanacağı senaryolarda ise <strong>Make</strong>, Zapier’e göre daha avantajlıdır.  Zapier kısa vadede en kolay başlayan araç olsa da, görev (task) bazlı fiyatlandırma ve sınırlı akış esnekliği nedeniyle orta–uzun vadede genellikle en pahalı ve en kısıtlayıcı seçenek hâline gelir. <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></p>
<h2>Temel tablo özeti</h2>
<table>
<thead>
<tr>
<th>Kriter</th>
<th>Zapier</th>
<th>Make</th>
<th>n8n</th>
</tr>
</thead>
<tbody>
<tr>
<td>Fiyatlama modeli</td>
<td>Task bazlı: her adım bir task sayılır, karmaşık akışlar çok hızlı pahalılaşır.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>Operation/credit bazlı: her modül/aksiyon kredi yer; başlangıçta ucuz, karmaşık senaryoda kredi tüketimi artar.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>Execution bazlı: bir workflow çalışması tek execution; çok adımlı/AI ağırlıklı akışlarda ciddi tasarruf sağlar.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
</tr>
<tr>
<td>Tipik maliyet (10k işlem/ay)</td>
<td>10k task için 200+ $/ay seviyesine çıkabiliyor.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>10k operasyon için Core planda yaklaşık 10.59 $/ay civarı.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>Self‑host: yazılım ücretsiz, barındırma ~20 $/ay; cloud’da 10k execution için ~60 $/ay.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
</tr>
<tr>
<td>Self‑hosting</td>
<td>Yok, tamamen SaaS.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>Yok, tamamen SaaS.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>Var, açık kaynak “fair‑code” ve self‑host seçeneğiyle tam veri kontrolü.  <a href="https://summarizemeeting.com/en/comparison/automation-platforms">summarizemeeting</a></td>
</tr>
<tr>
<td>Entegrasyon sayısı</td>
<td>~8.700+ app ile en geniş katalog.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>~2.900+ entegrasyon, güçlü görsel API builder.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>~1.100+ hazır node; HTTP ile diğer API’lere açılabilir.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
</tr>
<tr>
<td>Kullanım kolaylığı</td>
<td>En basit arayüz, trigger–action lineer model; iş birimleri için çok rahat.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>Canvas tipi görsel builder; güçlü ama öğrenme eğrisi daha yüksek.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>Node tabanlı, teknik ekipler için mantıklı; kurulum ve temel kod bilgisi gerektirir.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
</tr>
<tr>
<td>En iyi kitle</td>
<td>Basit otomasyonlar, düşük hacimli küçük ekipler.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>Orta–karmaşık süreçler, teknik olmayan ama meraklı ekipler, iyi fiyat/performans isteyen KOBİ’ler.  <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></td>
<td>Geliştirici/DevOps olan, veri gizliliği ve uzun vadeli maliyet kontrolü isteyen takımlar.  <a href="https://summarizemeeting.com/en/comparison/automation-platforms">summarizemeeting</a></td>
</tr>
</tbody>
</table>
<h2>Maliyet ve ölçeklenebilirlik</h2>
<p>Zapier, her adımı ayrı “task” olarak fiyatladığı için (filtreler, formatter’lar, dallanmalar dahil) karmaşık iş akışlarında ve binlerce işlem/ay seviyesinde maliyet çok hızlı yukarı tırmanıyor.  10.000 task/ay civarında dahi, Zapier’in toplam maliyeti 200 $/ay ve üzeri seviyelere çıkabildiği belirtiliyor. <a href="https://stackby.com/blog/zapier-alternatives-pricing/">stackby</a></p>
<p>Make, operasyon/credit bazlı modeliyle başlangıçta oldukça ucuz: 10.000 operasyon için Core plan ~10–11 $/ay bandında, bu da Zapier’e göre büyük avantaj.  Ancak 2026 itibarıyla kredi modeline geçiş, AI modülleri için ek kredi tüketimi ve “complexity billing” yüzünden kötü tasarlanmış senaryolar ölçek büyüdükçe beklenenden pahalı hâle gelebiliyor. <a href="https://thinkpeak.ai/make-com-pricing-hidden-costs-2026/">thinkpeak</a></p>
<p>n8n tarafında, self‑host kurulumda yazılım lisans bedeli yok; sadece sunucu masrafı (çoğu orta ölçekli senaryo için ~20 $/ay seviyesinde bir VPS yeterli) söz konusu ve execution bazlı model, 2 adımlık bir akışla 200 adımlık bir AI ajanını aynı “1 execution” olarak saydığı için yüksek karmaşıklıkta %90+ maliyet avantajı sağlayabildiği örneklerle anlatılıyor.  Cloud sürümünde 10.000 execution için ~60 $/ay civarı, hâlâ Zapier’den ucuz ama Make’in bazı planlarına göre daha pahalı; buna karşılık self‑host seçeneği sayesinde toplam sahip olma maliyeti, teknik ekibi olan işletmelerde uzun vadede en düşük olma eğiliminde. <a href="https://summarizemeeting.com/en/comparison/automation-platforms">summarizemeeting</a></p>
<h2>Teknik esneklik, self‑hosting ve veri kontrolü</h2>
<p>Zapier ve Make tamamen SaaS olduğundan, verileriniz onların altyapısından geçmek zorunda; buna karşılık SOC2/ISO gibi sertifikalarla güvenlik sunuyorlar ama veri egemenliği konusundaki son söz sizde değil.  n8n ise açık kaynak/fair‑code yapısı ve self‑hosting seçeneği ile, özellikle GDPR/HIPAA benzeri regülasyon hassasiyeti olan veya müşteri datasını ülkede tutmak isteyen işletmelere tam veri kontrolü veriyor. <a href="https://parseur.com/blog/zapier-n8n-make">parseur</a></p>
<p>Self‑host n8n senaryosunda; ölçeklendirme stratejilerini (kuyruk, worker sayısı, trigger sıklığı vs.) tamamen kendi SRE/DevOps yaklaşımınıza göre ayarlayabiliyor, gerektiğinde sadece altyapı büyüterek sınırsız workflow çalıştırabiliyorsunuz.  Buna karşılık, bu özgürlük operasyonel yük getiriyor: sunucu yönetimi, yedekleme, güncelleme ve izleme için ya içerde bir ekip ya da dışarıdan managed hizmet almak gerekiyor; bu da teknik kapasitesi zayıf işletmeler için dezavantaj. <a href="https://contabo.com/blog/n8n-vs-zapier-vs-make-an-in-depth-comparison/">contabo</a></p>
<h2>Entegrasyon kapsaması ve kullanım deneyimi</h2>
<p>Zapier, ~8.700+ uygulamayla en geniş entegrasyon kütüphanesine sahip ve özellikle niş SaaS ürünlerine bağlanmak gerektiğinde “en güvenli seçim” olabiliyor.  Arayüz, lineer “trigger–action” mantığında olduğu için pazarlama/operasyon gibi teknik olmayan ekiplerin bile birkaç saat içinde kendi otomasyonlarını kurabilmesini sağlıyor. <a href="https://neondigitalmedia.com/blogs/las-vegas-seo-digital-marketing-blog/n8n-vs-zapier-vs-make-comparison-2025">neondigitalmedia</a></p>
<p>Make, canvas tabanlı görsel builder’ı ve router, error route, paralel path gibi gelişmiş özellikleriyle daha karmaşık iş süreçlerini kullanıcıya çok net görselleştiriyor; bu da orta ölçekli işletmelerde “iş analisti + power user” profili için oldukça ideal.  n8n’in node tabanlı mimarisi de benzer şekilde gelişmiş dallanma, hata yönetimi ve custom code node’ları sunuyor; ancak kurulum ve temel JavaScript bilgisi gerektirdiğinden teknik olmayan son kullanıcılar için learning curve belirgin şekilde daha yüksek. <a href="https://summarizemeeting.com/en/comparison/automation-platforms">summarizemeeting</a></p>
<h2>AI ve ileri seviye otomasyon</h2>
<p>Zapier, AI tarafında daha çok “herkes için kolaylaştırma”yı hedefliyor; doğal dil ile otomasyon yaratma, ChatGPT entegrasyonu vb. var ama derin özelleştirme ve ajan mimarileri sınırlı.  Make, OpenAI/Anthropic modülleri ve AI destekli veri dönüşümleriyle orta seviye esneklik sunuyor; fakat AI modüllerinin kredi tüketimi toplam maliyeti yukarı çekebiliyor. <a href="https://thinkpeak.ai/make-com-pricing-hidden-costs-2026/">thinkpeak</a></p>
<p>n8n ise LangChain entegrasyonu, onlarca AI node’u ve farklı model sağlayıcılarıyla daha çok “teknik ekiplerin AI ajanları ve RAG tabanlı sistemler kurduğu” bir platform hâline gelmiş durumda.  Orta ölçekte ciddi AI iş yükü olan, örneğin ticket sınıflandırma, doküman bazlı soru‑cevap, müşteri etkileşim otomasyonu gibi senaryolarda, execution bazlı model ve self‑host imkânı maliyet/performans dengesini n8n lehine çeviriyor. <a href="https://nicksaraev.com/n8n-vs-make-2025/">nicksaraev</a></p>
<h2>Orta ölçekli işletmeler için pratik öneri</h2>
<ul>
<li>
<p><strong>Teknik ekibiniz (dev/DevOps) VAR ve otomasyon sizin için stratejik bir katman olacaksa:</strong><br />
Çekirdek otomasyon altyapısını <strong>n8n (özellikle self‑host)</strong> üzerine kurmak uzun vadede genellikle en avantajlı seçenek; hem maliyet hem de esneklik/veri egemenliği açısından. <a href="https://latenode.com/blog/platform-comparisons-alternatives/n8n-alternatives/n8n-vs-make-com-2025-complete-platform-comparison-pricing-analysis-for-workflow-automation">latenode</a></p>
</li>
<li>
<p><strong>Teknik ekibiniz sınırlı ama iş birimleri karmaşık akışlar istiyor, Zapier maliyeti gözünüze batmaya başladıysa:</strong><br />
Çoğu orta ölçekli işletme için <strong>Make</strong>, Zapier’e göre çok daha sürdürülebilir maliyet ve daha zengin workflow tasarım imkânı sunuyor; bakım yükü de n8n self‑host kadar ağır değil. <a href="https://parseur.com/blog/zapier-n8n-make">parseur</a></p>
</li>
<li>
<p><strong>Tamamen non‑technical, az sayıda basit otomasyon ve düşük hacim planlıyorsanız:</strong><br />
Küçük/başlangıç senaryosunda Zapier hâlâ “en hızlı sonuç veren”, iş birimlerinin en rahat adapte olduğu çözüm; ama orta vadede hacmin artacağı öngörülüyorsa, ilk günden Zapier’e kilitlenmek yerine Make veya n8n tarafını stratejik platform olarak düşünmek genelde daha sağlıklı. <a href="https://thatapicompany.com/zapier-pricing-breakdown-hidden-costs-that-shocked-our-clients/">thatapicompany</a></p>
</li>
</ul>
<p>Senin profilini (geliştirici geçmişin, Docker/sunucu yönetimine alışık olman vb.) düşününce, kendi şirketinde ya da danışmanlık vereceğin orta ölçekli firmalarda <strong>n8n + gerektiğinde Make kombinasyonu</strong> uzun vadede hem maliyet hem kontrol açısından büyük olasılıkla en mantıklı mimari olacaktır. <a href="https://nicksaraev.com/n8n-vs-make-2025/">nicksaraev</a></p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>n8n nedir</title>
		<link>https://selmantunc.com.tr/software/n8n-nedir/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Sun, 22 Feb 2026 02:57:34 +0000</pubDate>
				<category><![CDATA[software]]></category>
		<guid isPermaLink="false">https://selmantunc.com.tr/?p=3497</guid>

					<description><![CDATA[n8n, Alman şirketi n8n GmbH tarafından geliştirilen açık kaynaklı bir iş akışı otomasyon platformudur. Düşük kodlu (low-code) bir araç olarak, farklı uygulamaları node tabanlı görsel editörle birbirine bağlayarak otomasyonlar oluşturmayı&#8230;]]></description>
										<content:encoded><![CDATA[<p><strong>n8n</strong>, Alman şirketi n8n GmbH tarafından geliştirilen açık kaynaklı bir iş akışı otomasyon platformudur. Düşük kodlu (low-code) bir araç olarak, farklı uygulamaları node tabanlı görsel editörle birbirine bağlayarak otomasyonlar oluşturmayı sağlar. Hem self-hosted (kendi sunucunda) hem de bulut tabanlı olarak kullanılabilir ve 400&#8217;den fazla entegrasyon destekler. <a href="https://n8n.io">n8n</a></p>
<h2>Nasıl Kullanılır</h2>
<p>n8n&#8217;i kullanmak için öncelikle Docker ile yerel kurulum yapın veya resmi siteden (n8n.io) bulut hesabı oluşturun. Görsel arayüzde &#8220;node&#8221;ları sürükle-bırak ile ekleyin: tetikleyici (örneğin webhook veya zamanlama), işlem (HTTP istek, OpenAI entegrasyonu) ve çıktı node&#8217;larını bağlayın. JavaScript/Python kodu ekleyerek özelleştirin, workflow&#8217;u test edin ve aktif hale getirin; hata yönetimi için Error Trigger node&#8217;u kullanın. <a href="https://eksisozluk.com/n8n--7482910">eksisozluk</a></p>
<h2>Faydaları</h2>
<p>n8n, tekrar eden görevleri otomatikleştirerek zaman tasarrufu sağlar ve manuel hataları azaltır. Geniş entegrasyon kataloğu (Google Sheets, Slack, CRM&#8217;ler) ile veri senkronizasyonu ve AI ajanları oluşturmayı kolaylaştırır, self-hosted seçenekle veri güvenliği sunar. No-code/low-code yaklaşımıyla geliştiriciler ve citizen developer&#8217;lar için idealdir, kurumsal ölçekte RBAC ve audit log gibi özelliklerle verimliliği artırır. <a href="https://uretkenzeka.com/n8n-nasil-kullanilir-sifirdan-baslayarak-yapay-zeka-ajanlari-olusturma-rehberi/">uretkenzeka</a></p>]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
