The map: every technology and where it sits

Every technology in {{brand}} on one map: the six layers a request passes through, what each technology does and why it was chosen, one request traced end to end, the seam rule that keeps the parts apart, and how to read the rest of the course.

In short

{{brand}} is built from six layers. People work in clients: a web app, an installable app, a browser extension and a command line. Every request crosses the edge and reaches one .NET 10 API made of separate modules. The API keeps records in PostgreSQL and files in storage, and reaches outside services such as AI models, email and payments only through small adapters. Docker, Azure and Azure DevOps build, check and run it all.

After this lesson you can Name every technology in the stack and say what it is for. Trace one request from a click to the database and back. Defend each big choice against its alternatives, and explain the seam rule that keeps the parts apart.

Words you need

The six layers at a glance

Read the map from top to bottom. A request starts in a client, crosses the edge and is handled by the API. The API reads and writes data and calls outside services. The sixth layer, run and ship, holds everything that builds, checks and hosts the other five.

The direction rule For a request, calls go only down: the web app never touches the database, and a module never talks to an outside service directly; it asks a contract, and an adapter answers. Answers flow back up. The sixth layer is different: it does not handle requests, it builds, checks and hosts the other five. Modules also never call each other directly; they meet only through seams, described below.

Layer 1: Clients - where people work

Four clients reach the same API, and all of them speak HTTPS and JSON, so the server has one way in. The web app is a single-page application: the browser downloads the code once, and after that only data travels. Screens load in chunks, so a page downloads only the code it needs.

Why server state needs its own tool Data from the server is a copy that can go stale. A query library knows when each copy was fetched, refreshes it when needed and shares it between screens. Writing that by hand in a global store is where most frontend bugs come from.

Layer 2: The edge - the way in

The edge decides what may reach the application at all. Two parts sit outside the code - Cloudflare and nginx - and one sits inside it: the middleware pipeline of ASP.NET Core. Each one stops a different kind of bad traffic before any business code runs.

Why the same origin matters When the app and its API share one address, the browser sends the session cookie without cross-site rules. CORS can stay strict, and the page's Content Security Policy names one origin. One public entry point is also easier to protect. Real-time connections and streamed answers need the extra lines above: a proxy that buffers or drops the Upgrade header breaks them.

Layer 3: The API - where the rules live

The API is one ASP.NET Core application on .NET 10. It holds many product modules - Boards, Jobs, API Tester and the rest - and the platform parts every module needs: accounts, access and settings. Every request follows the same short path: endpoint, mediator, handler.

Layer 4: Data - where things are kept

Data has several homes, each chosen for what it holds. Records go to PostgreSQL, files to object storage, short-lived cached answers to memory or Redis, and the encryption keys behind saved secrets to a key ring.

Layer 5: Outside services - bought, not built

Some jobs are better bought than built: sending email, taking payments, running a large language model. Each one is reached through an adapter behind a contract, picked by configuration when the server starts. A module never knows which vendor answers.

Why plain HTTPS can be enough Many model servers accept the same chat completions format over HTTPS, so one client can talk to several of them; Anthropic uses its own messages format. Before you choose a vendor SDK over plain HTTP, read the vendor's documentation and weigh the extra dependency.

Layer 6: Run and ship - from a commit to a running service

The last layer turns source code into a running, watched service. Everything ships as Docker images - the same images on a laptop, in the hosted cloud and on a customer's own servers. One version number names both images of a release.

One request, end to end

Follow one real action: a person drags a card into the Done column of a board. On its way in it crosses the client, the edge, the API and the data layer, and on the way back it reaches other people's screens too.

The options in the market

Four decisions shape everything else: how many deployable pieces the system has, which platform the server is written on, which database keeps the records, and how screens learn that something changed. Here are the honest options for each.

What {{brand}} chose, and why

{{brand}} is built by a small team and offers many connected products in one place. A card follows a test, a failed test becomes a bug, tracked time lands where the work lives. That needs one transaction and fast in-process calls between parts, plus hard borders so the parts stay apart. A modular monolith gives both.

The rule behind every choice Pick the simplest thing that will still work when the product grows, and put a seam where it might have to change. One deployable, but modules that could move out. One database, but a schema per module. One cloud, but an adapter per vendor.

Seams: the one rule that holds it together

Modules never reference each other. Sometimes one part needs something from all the others: Home needs every module's urgent items, and the assistant needs facts from everywhere. Then it declares a contract in the shared kernel. Each module implements it, and dependency injection hands the consumer every implementation.

Events are seams too A module publishes a fact and any module may handle it. The publisher never knows who listens, so adding a listener never touches the publisher. Facts that must not be lost travel through the outbox: delivered right after the commit, retried with growing delays, and set aside for an operator if they keep failing.

Adapters: every vendor behind a contract

The same idea keeps vendors out of the modules. Each outside need is a contract in the shared kernel, each vendor is an adapter, and one setting picks the adapter when the server starts. A wrong or half-filled setting stops the server at startup, not a user's upload an hour later.

A stand-in for every contract Each contract has a local stand-in: email written to a folder, files on disk, a fake payment provider. A developer's machine and every test run then work without a single vendor account.

Health probes: the other half of failing fast A server should expose two probes. Live says the process is running; ready says it can serve people right now. A platform uses them to decide when to send traffic or restart a copy, and start-up checks that stop the boot on a blocking problem complete the picture.

Growing from one copy to many

Any modular monolith can scale horizontally: run several copies behind a proxy. First, state that lives inside one process has to move to a shared place, so every copy sees the same world.

The key you cannot lose Any key that encrypts stored data must live in a shared, backed-up place before you run a second copy, or before any redeploy that replaces a container's disk. Lose it, and what it encrypted stays unreadable for good. If the key is itself protected by a certificate, that certificate needs the same care.

How to read this course

Every later lesson zooms into one box of this map. Read them in sequence to follow how the product was built, or jump straight to the layer you need today. Each lesson sits under the layer it mostly belongs to.

Try it yourself

The goal: watch one request cross the edge, the API and the data layer on your own laptop. You need free tools only - Docker Desktop, the .NET SDK and a browser - and about thirty minutes.

Common mistakes

Interview questions

Related