Documentation
Core Folder

The packages/core folder

The packages/core folder is a crucial component of the Blitzship monorepo architecture, serving as the central hub for all logic of your SaaS application.

This is the place where all the main business logic should be defined. Basically, this is where the money is! 💸

The core folder facilitates domain-driven design and helps maintain a clear separation of concerns.

Purpose

The core package is designed to be imported and used by other packages within the monorepo, such as the functions package, but also the backend part of your Next.js applications. It provides a centralized location for your business logic, as well as a place to define your business objects and their database access layer.

By structuring the core package in this way, we achieve a clear separation of concerns, improve code reusability, and maintain a scalable architecture for your SaaS application.

💡

A great example to understand how the core package integrates with the rest of the monorepo is by considering how Stripe Webhooks are handled.

  • In the infra/api.ts file we define what AWS infrastructure we need: An API Gateway and a Lambda function.
  • We point the Lambda function to a handler code that is defined in the packages/functions directory.
  • The packages/functions is not supposed to contain any business logic, it should only contain the code that receives the API request.
  • The lambda handlers, in turn, calls into functions defined in the packages/core package to perform the actual business logic (sending emails, creating users, provioning services etc.)

This is a very scalable way of structuring your code, as it allows you to separate the concerns of infrastructure, business logic and handlers and should guide you for years to come.

Folder Structure

/aws

This folder contains some pre-defined functions for interacting with some AWS services:

  • Storage bucket operations (presigned URLs for uploads and downloads)
  • Email sending functionality using AWS SES

/database

Houses the DynamoDB Database client and ElectroDB ORM Entities that will be stored in the DynamoDB database. This directory is the place where you define your business objects and their database access layer.

💡

DynamoDB (opens in a new tab) is a NoSQL database service provided by AWS. It offers several benefits:

  • Scalability: Can handle large amounts of data and traffic
  • Performance: Provides low-latency data access
  • Flexibility: Supports both document and key-value data models
  • Serverless: Eliminates the need for database management

ElectroDB Entities

We use ElectroDB to define and manage database entities. Conviniently, Blitzship already includes a fully set up example EmployeeEntity with attributes, indexes, and methods for interacting with employee data in DynamoDB.

ElectroDB entities allow us to:

  • Define clear data structures
  • Implement efficient querying patterns
  • Manage relationships between different data types
💡

ElectroDB (opens in a new tab) is an ORM tool that simplifies working with DynamoDB by providing a more intuitive and type-safe interface for defining and interacting with database entities.

/mutations

Mutations are operations that change the state of the database, as opposed to queries which only retrieve data. This directory centralizes all write operations on your business objects that are defined in the /database directory.

  • Data Modification: This is the place to implement logic that modifies the database state
  • Business Logic: This is the place to implement complex operations, data transformations, and validations
  • Side Effects: This is the place to handle additional tasks like permission checks, external API calls, or event triggers

Conviniently, Blitzship includes a some example mutations for the EmployeeEntity. Freely use them as a starting point for your own mutations.

/queries

As opposed to mutations, queries are read-only operations that fetch data without modifying the database state. This module centralizes all read operations on your business objects that are defined in the /database directory.

  • Data Retrieval: Implement complex data fetching, filtering, and transformations here
  • Business Logic: Enhance retrieved data with additional information or calculations here
  • No side Effects: Do not modify the database or application state

Conviniently, Blitzship includes a some example queries for the EmployeeEntity. Freely use them as a starting point for your own queries.

/trpc

Sets up tRPC routes for frontend-backend communication:

  • Defines type-safe procedures for various operations
  • Groups related procedures into subrouters (e.g., employeeRouter, userRouter)
  • Enables seamless, type-safe communication between frontend and backend

tRPC Routers

tRPC routers define type-safe API endpoints for frontend-backend communication. The main router includes subrouters for different entities (e.g., users, employees, storage etc.).

💡

TRPC (opens in a new tab) is a framework for building type-safe APIs. It provides several benefits:

  • Full type-safety across the front and the backend
  • Improved developer experience with autocomplete and IntelliSense
  • Reduced boilerplate code
  • Seamless integration with React and Next.js

/utils

Houses utility functions and helper modules:

  • Date and time conversions (e.g., epoch seconds)
  • Email address construction
  • TypeScript utility types