DEV Community

Cover image for Backend/Domain foundation
LkSvn
LkSvn

Posted on • Edited on

Backend/Domain foundation

Today I continued my TypeScript learning project after a short break.

Instead of jumping into React right away, I decided to keep working on the backend/domain side of the Candidate Tracker project.

The main lesson today:

  • TypeScript is not just useful for components and props.
  • It also helps clarify ownership, data flow, and service boundaries.

Some examples from today:

  • using Omit and Partial to define create/update inputs
  • deciding which fields the caller can change and which fields the service owns
  • using generics for reusable helpers like findById and filterByProperty
  • typing async repository functions with Promise<AsyncResult<T>>
  • using Promise.all for independent data loading
  • splitting async loading into stages when later data depends on earlier results

One useful distinction:

  • Services express behavior.
  • Repositories decide where data comes from.

That separation should make the next steps cleaner: adding tests first, then replacing seed data with a real database later.

I’m intentionally delaying the frontend a bit.

Not because React is less important, but because I want the domain and data flow to be understandable before putting UI on top.

Next step: tests.

Top comments (3)

Collapse
 
publiflow profile image
PubliFlow

Separating your domain logic from the UI framework early on is a solid architectural choice that pays off massively later. When you keep your TypeScript business logic completely decoupled from React, unit testing becomes trivial since you do not have to mock DOM or component lifecycle methods. Have you considered using the repository pattern for your data access layer to further abstract the database queries from your domain models? It adds a bit of initial boilerplate but makes swapping out data sources down the line incredibly smooth.

Collapse
 
lksvn profile image
LkSvn

Thanks! Yes, that’s actually the direction I’m taking. The domain/services don’t depend on React or a concrete data source, and repository functions currently sit between the business logic and the seed data.

That also gives me a natural seam for unit tests before introducing a real database.
When I add PostgreSQL/Prisma, I plan to keep the repository abstraction focused on domain operations rather than exposing generic database queries everywhere. I agree that it introduces some boilerplate, so I’m trying to add only the abstractions the application actually needs rather than implementing the pattern mechanically.

Swapping databases isn’t my main expectation—the bigger benefit for me is keeping persistence concerns out of the domain and making dependencies explicit.

Collapse
 
publiflow profile image
PubliFlow

Using repositories as a seam for unit testing before introducing a real database is a solid move, especially since you are keeping the abstraction strictly tied to domain operations. When you eventually swap in Prisma, the temptation to let generated Prisma types leak into your domain layer will be high, so defining explicit repository interfaces now will save you major refactoring headaches later.