Database, APIs, Auth, Logs and Tests in a Codebase

2.Pipes, Doors, Locks, Cameras and Alarms

A

In this chapter

We'll learn how to find the main systems inside a codebase — database access and migrations, API routes, authentication, logging and tests — explained as finding a house's plumbing, doors, locks, cameras and smoke alarms.

12–14 min

The Problem in Real Life

Anna's next sticky note says: "Where is the DB access?" The live counter needs one number — tickets sold so far for an event — and she wants to know how this old code talks to the database before she touches anything.

John shows her the most useful tool for the job: the editor's search across all files. "In an unfamiliar codebase, search is your torch. You know what things are called — query, router, jwt, logger, test. Search for them."

A

I don't need to read the whole house. I need to find the pipes.

Anna

Guessing Where Things Are vs. Searching for Their Fingerprints

Every project is organised differently

The same systems hide in different folders and files in every codebase.

Easy to break the wrong thing

Changing code without knowing how auth or the database works can open a security hole.

Is there a safety net?

Before changing anything, you need to know which tests exist — and which don't.

Database, APIs, Authentication, Logging and Tests in a Codebase

The house systems analogy: every house has the same hidden systems: plumbing (water in and out), doors (ways in), locks (who may enter), security cameras (a record of what happened) and smoke alarms (warnings before disaster). Every web backend has the same five: the database, the API routes, authentication, logging and tests. Each one leaves recognisable fingerprints you can search for.

  • Database — the plumbing: search for the database library from package.json (pg, mysql2, prisma, sequelize, mongoose) and for query(, SELECT, INSERT. Here, backend/db/index.js creates one shared connection pool (Act 13) and exports a query function; every database call goes through it. The migrations folder (db/migrations/) is the history of the schema — read the files in order and you see every table being created and changed (Act 13). There's also db/seed.js, which fills a local database with fake events and orders.
  • APIs — the doors: search for how routes are defined: router.get(, app.post( in Express; @app.route in Flask; @GetMapping in Spring. Here, backend/routes/ has events.js and sales.js, and server.js mounts them under /api. Anna lists every endpoint in her notes in two minutes — that's the API's real documentation, written by the code itself.
  • Authentication — the locks: search for jwt, auth, session, passport, middleware. Here, backend/middleware/auth.js reads a JWT from the Authorization header (Act 22), checks its signature with AUTH_SECRET, and puts the organiser's ID on req.user. Every route in sales.js uses it. Important for her change: the counter must only show an organiser their own events (authorization, Act 22).
  • Logging — the cameras: search for logger, console.log, winston, pino, morgan. Here, middleware/logger.js logs each request with its method, URL, status and time (Act 17). Knowing the log format means she'll know how to find her own requests later.
  • Tests — the smoke alarms: look for tests/, __tests__/, files ending in .test.js or _test.py, and the test script in package.json. Here: backend/tests/sales.test.js with three tests — one marked as skipped (.skip), with a comment: // TODO fix after export change. She runs them: two pass. The safety net exists, but it has a hole.
Table — What to search for
SystemHouse versionSearch forFound in organiser-dashboard
DatabasePlumbingpg, prisma, query(, SELECTbackend/db/index.js, db/migrations/
API routesDoorsrouter.get(, app.post(backend/routes/events.js, sales.js
AuthenticationLocksjwt, auth, session, middlewarebackend/middleware/auth.js
LoggingCameraslogger, console.log, morganbackend/middleware/logger.js
TestsSmoke alarms.test.js files, a tests folder, the test scriptbackend/tests/sales.test.js (1 skipped)
Searching for fingerprints from the terminal
grep -rn "router\.\(get\|post\|put\|delete\)" backend/routes # every endpoint
grep -rn "db.query" backend # every database call
grep -rn "process.env" backend config # every setting read
grep -rn "\.skip\|TODO" backend/tests # holes in the safety net

Your editor's "search in all files" does the same with a click — use whichever is faster for you.

The auth middleware, as found
// backend/middleware/auth.js
module.exports = function requireOrganiser(req, res, next) {
const token = (req.headers.authorization || "").replace("Bearer ", "");
try {
const payload = jwt.verify(token, process.env.AUTH_SECRET);
req.user = { organiserId: payload.sub };
next();
} catch {
res.status(401).json({ error: "unauthorized" });
}
};

Anna's notes, after an hour: "DB: db/index.js (pg pool) — all queries via db.query. Schema: 7 migrations; orders has event_id, status, quantity. API: 6 endpoints under /api, listed. Auth: JWT middleware → req.user.organiserId; sales queries filter by organiser. Logging: request logger, no request IDs. Tests: 3 (1 skipped, 2 pass) — only for sales." Five lines that would have taken Mark ten minutes to write in a README. She keeps them; they'll become exactly that.

Key Takeaway

Every backend has the same hidden systems, like a house: the database (plumbing), API routes (doors), authentication (locks), logging (cameras) and tests (smoke alarms). Find each by searching for its fingerprints — the database library and query calls, router definitions, jwt/auth/middleware, logger, and test files ending in .test.js — then read migrations for the schema, list every endpoint, note how authorization is enforced, and run the tests to see how strong the safety net is.

Why This Matters

When you change code you didn't write, the dangerous mistakes come from not knowing how the hidden systems work — bypassing authorization, writing a query that skips the shared pool, or changing code with no tests. Knowing where to look for each system, and how to find them by search, makes you safe and fast in any codebase.

Anna knows how the app works when it runs. But how does it get built and deployed? Three files at the root — Dockerfile, docker-compose.yml and a CI workflow — hold the answer, and one of them has a surprise.

Next