Can CeylanVienna-based, globally curious.
Learn/Architecture

Catch data conflicts before code review, not after

Two features touching the same database table is a conflict waiting to happen. A feature registry and a mandatory conflict check forces the conversation before the code is written.

2026-04-18·2 min read·intermediate

The bug that's hard to see in review

Two developers (or two agents) implement features independently:

  • Feature A: user authentication — writes to the users table on signup
  • Feature B: profile completion — also writes to the users table on first login

Neither feature is wrong in isolation. Together, they create a race condition on first login — two writes to the same record, potentially overwriting each other.

This kind of conflict is hard to catch in code review because the reviewer sees each PR in isolation. The overlap only becomes visible when you know what both features do to shared resources.

A feature registry makes overlap visible

The solution is a machine-readable map of what each feature touches:

{
  "auth": {
    "tables": ["users", "sessions"],
    "routes": ["/api/auth/login", "/api/auth/signup"],
    "permissions": ["users:write"]
  },
  "profile-completion": {
    "tables": ["users", "profiles"],
    "routes": ["/api/profile/complete"],
    "permissions": ["users:write", "profiles:write"]
  }
}

Before implementing any new feature, a conflict checker scans this registry for overlapping scope — same table, same route, same permission.

Five outcomes, not just pass/fail

When a conflict is detected, the resolution isn't binary. There are five options:

Decision Meaning
EXTEND The overlap is compatible — both features can coexist without changes
MODIFY One feature needs to adjust its scope to avoid the overlap
REPLACE The two features should be merged into one
ISOLATE Separate the data — give each feature its own table
ABORT The new feature conflicts too deeply — do not proceed

Forcing an explicit decision for each conflict is the point. The goal isn't to prevent all overlap — it's to prevent unexamined overlap.

Why this works better than hoping code review catches it

Code review happens after the code is written. Changing the data model at that point is expensive — you're rewriting logic, not adjusting a plan.

A conflict check before implementation means the conversation happens at the cheapest possible moment: when nothing has been built yet.

The registry also serves as documentation. Six months later, when someone wants to add a new feature that touches users, they can see exactly what already writes there and why.

The lightweight version

You don't need a script to get most of the value. A simple features.md file listing each feature's tables and routes, reviewed before any new feature starts, gives you 80% of the benefit with zero tooling overhead.

The script matters when you have enough features that manual scanning becomes unreliable — typically somewhere above 15–20 features touching shared resources.

The principle underneath

Every shared resource in your system is a potential conflict point. Making those resources explicit — naming them, listing who touches them — turns invisible conflicts into visible ones. Visible conflicts get resolved. Invisible ones ship to production.

More like this, straight to your inbox.

I write about Architecture and a handful of other things I actually care about. No schedule, no filler — just when I have something worth saying.

More on Architecture

Soft deletes aren't just for audit trails — they're your sales pipeline

When you hard-delete a record, you lose the sales lead. Inactive records in a marketplace platform are your best prospects — enforce soft delete at the database role level, not in application code.

Sequential vs Parallel Execution: when faster is the wrong answer

The instinct is always to run things in parallel. Here's why that instinct can get you banned, blocked, or with corrupted data.

If this raised a question, I'd be happy to talk about it.

Find me →
← Back to Learn