Lesson 15 · Senior v2 architecture
Transactions, `database.Ext`, and cross-module writes
Why `database.Ext` is more than a signature detail, and how the repo composes writes safely across repositories and modules.
Your win: explain why `database.Ext` exists, how transaction injection works in v2, and why cross-module writes still go through repository interfaces instead of direct mutating sqlc calls.
The problem: one business action often means several writes
A useful write-side handler rarely updates only one thing. It may touch several tables, maybe even several module-owned repos, and still need to succeed or fail as one unit. That is where transaction-aware architecture matters.
Why `database.Ext` matters
The interface is not an incidental abstraction. It is what allows repo methods to accept either a pool or a tx handle through one signature. That is how `ExecInTx` or `ExecInTxV2` can thread one transaction through several writes without special-case repository APIs.
Eureka read/write rules + usecase conventions
The loaded CLAUDE and rules files are the highest-trust explanation of why the read/write split exists in this codebase.
→ internal/eureka/CLAUDE.md
→ .claude/rules/eureka-v2-conventions.md
Check yourself (from memory)
Q1. The main purpose of `database.Ext` is to…
Sources. Internal CLAUDE and rules docs.