- MacOS Big Sur or later
- Latest version of
docker
anddocker-compose
installed on system
- Clone this repo:
git clone git@github.com:kevin-coelho/audioshake-project.git
- Build the project
docker-compose build
- Create an env file in the project root:
.env.docker.development
(seesample.env
) - Start the database
docker-compose up -d postgres
- Migrate the database
docker-compose run migrate
- Start the API
docker-compose up api
- Ensure the api is running
- Visit
localhost:4001/docs
- Build the project
docker-compose build
- Create an env file in the project root
.env.docker.test
(seesample.env
) - Start the test database
docker-compose up -d postgres-test
- Migrate the test database
docker-compose run migrate-test
- Run tests
docker-compose run test
- Run integration tests
docker-compose run integration
- Instead of using plural names, I used singular namings in REST endpoints to reflect database-naming best practices. Database tables also use singular namings.
- The
sort
paramater was renamed toearliestFirst
andlatestFirst
options to reflect a more client-friendly and user-friendly naming.asc
anddesc
is not always clear when working withdate
types. - Some models have additional fields to make them more extensible (such as
createdAt
andupdatedAt
fields)
- Dockerfile in the project root. For deployment on infra, simply build the project and run. It is possible to run the entire project on a single machine using docker-compose. For real production environments, separate db and docker image in an image registry is recommended (such as ECR).
- Project is structured as a node.js/typescript mono-repo.
apps/server
represents a single "app" or "service", in this case a REST API. The project is structured this way to allow more apps to be added such as a React UI / client, or different back-end microservices
- Postgres database
- Express / Typescript / Objection.js / knex.js / AWS SDK
- Test framework with: mocha, sinon, chai
- API documentation with swagger (autogenerated from source code and
.swagger.yaml
files). Inline swagger documentation with jsdoc is also supported/** @openapi ... start docs here */
- File upload is handled using node streams via
busboy
andaws sdk
. Dev build handled20-50MB
files with no problems. - Assets and posts are assigned unique ids by the back end. For assets, the id is a UUID v5 hash of the asset's bucket, key, and a unique uuidv4. This is to ensure that the system can support assets with identical filenames
- Posts are all assigned unique uuidv4 from the back end. Identical posts are supported.
- API endpoints all have param / query / request validation using
joi
andcelebrate
libs.
- enforced with
eslint
andprettier
- Lint and format can be done with docker:
docker-compose run lint
,docker-compose run format
- Inside
server/src
, different modules are organized as importable "packages". This is for code cleanliness, separation of concerns, and also to make good utilization ofTypeDI
injection / containerization. - Teams with expertise in different systems (such as s3 or postgres) can each work on modules separately and expose common functionality externally
- Migration to workspaces (such as with npm or pnpm) is easier with this type of organization (simply add a
package.json
to each package's folder)
- See
packages/config
. Environment variables are loaded usingdotenv
and validated usingjoi
. This ensures that app startup does not have bugs with bad or missing environment variables (config errors will block startup) - In docker setup, some vars are provided by
docker-compose.yaml
and others are provided with environment files. In a production setup, all env vars should be provided by the shell environment to the running docker image.