1. Courses
  2. Architecture
  3. Software and Solution Architecture
  4. Stop 4

40 minAdvanced

Integration and data ownership

When every team can write every table, one column change breaks three apps. This lesson gives you a method to name one owner for each kind of data, pick an API call, an event or a batch feed for each connection, and write contracts that let teams change without breaking each other.

By the end you can

  • Build a data ownership map with exactly one writer for each kind of data
  • Choose an API call, an event or a bulk feed for a connection, and say what each one couples
  • Decide between thin event notifications and events that carry state, with a staleness budget
  • Tell compatible event schema changes from breaking ones, and ship a breaking one safely
  • Enforce ownership in PostgreSQL with schemas, roles and a published read-only view

The everyday picture

Picture a small company that runs on one shared spreadsheet. Sales, the warehouse and finance all type into it. One day the warehouse renames the column "Qty" to "Units" and moves it two places to the right. Finance's formulas now add up the wrong numbers, and sales sends a customer a quote based on yesterday's stock. Nobody did anything wrong in their own eyes. The sheet had no owner and no promise about its layout.

The usual fix is that each team keeps its own sheet. Only the warehouse types in the stock sheet. When finance needs stock numbers, it has two choices. It can phone the warehouse and ask, which gives a fresh answer but only works when someone picks up. Or it can receive a copy every hour in an agreed layout, which is always there but a little old. The agreed layout is a promise: the warehouse may rearrange its own sheet as it likes, as long as the copy it sends keeps the same columns.

That is this lesson in small: one owner for each kind of data, a choice between asking and receiving copies, and a contract for what is sent.

One owner for each kind of data

Mangrove's back office is one PostgreSQL database that buyers, store managers, finance and the Partner app team all change. In Choosing an architecture style you saw the result: monthly releases, because any change can touch anything. The root of that coupling is data. When four teams write the price table, none of them can change it alone.

To break this knot, give every kind of data one , owned by one module or service and one team. Only the owner writes it. Everyone else reads it through the owner's API, its events or a published read-only view, and asks the owner when they need a change. The owner can then change its tables on its own schedule, because nobody depends on them directly. Bounded contexts, from Monolith, modular monolith, microservices, tell you where the module lines go; the ownership map tells you who may write what.

You build the map in four steps.

  1. List the data at business level, not table by table: article (a product), price, stock, goods received note (GRN), app order, partner shop, partner order, invoice, sale.
  2. Find every writer today. Search the code for inserts and updates. If each app connects with its own database user, pg_stat_statements shows which user runs which statements, which catches the scripts nobody remembers.
  3. Pick the owner: the team whose business decision creates or changes the data. Buyers decide prices, so the pricing module owns price. Deliveries and sales change stock, but the rules for stock live in inventory, so inventory owns it.
  4. Replace every other writer. Either the writer sends a command to the owner's API ("set this promotion price"), or the owner listens to the writer's event (POS publishes sale.completed, inventory lowers stock).

Two writers that both seem right usually mean the data is really two things. The article row holds the name and pack size, which buyers set, and the shelf location, which each store sets. Split it: buying owns the article, store operations owns shelf locations, and both refer to the same article id.

Before: one shared database Buyers Store app Finance Partner API writes price, stock, grn, order: anyone writes One column change breaks three other teams After: one owner per kind of data Pricing owns price table Inventory owns stock, grn price.changed event, async API call reserve Partner API local price copy Store app on scanners Each table has one writer; others ask or listen
The same data, two shapes. Before, four teams write the shared tables, so every change needs everyone's agreement. After, each kind of data has one owner. The Partner API keeps its own copy of prices from events, and the Store app asks inventory through its API when it needs a decision.

Quick check

Finance and the Partner app team both update partner_shop.credit_limit today. Which ownership decision is best?

Loading the rest of the lesson…