# Build Instructions

The build is fairly simple, and I intend to keep it that way. The project is split into two main parts: the backend and the frontend.

Making all of these parts work properly under linux/macOS is fairly simple, but Windows will require [WSL](https://learn.microsoft.com/en-us/windows/wsl/).

When working with these tools, keep in mind that make is sensitive to working directory. If you're in the wrong directory, make will not work as expected. Always make sure you're in the right directory when running make commands.

## Backend

For demo purposes, the backend uses sqlite3 as the database. The database is stored in the `backend` directory.

For future development, the database will be migrated to a more robust database such as PostgreSQL. This will require a few changes to the code, but the migration should be fairly simple. Practical difference for the programmer is the requirement of a running PostgreSQL server, for which a container can be used.

For initializing the database, simply navigate to the backend directory and run `make migrate`, which will create the database and the necessary tables.

To build and run the main server binary:

```bash
make build
make run
```

The server will be running on `localhost:8080`. This server does not hot reload, so you will need to restart the server after making changes.
Note that without the frontend, the server will **NOT BE SERVING ANY HTML AND RESPOND WITH 404**.

The server works by serving the frontend as static files and providing an API for the frontend to communicate with, but when running the server, the frontend is not built. To build it, refer to the [frontend section](#building-for-production).

If you ever wonder what the makefile does, you can always inspect it. It's quite simple and self-explanatory.

## Frontend

The frontend code might look very intimidating at first, but it's actually quite simple. The vast majority of the code is boilerplate and configuration.

The important parts resides in the `src` directory, which contains the actual React components and corresponding styles.

The frontend is built using Vite with React. Vite can initially seem like a convoluted mess of a build tool, but it's job essentially boils down to two things: bundling and hot reloading. The final output is static html, css, and javascript files that can be served by any web server.

First, you need to pull in the dependencies by running `npm install` in the frontend directory.
To spin up the development server, run `npm run dev`. This will start the development server on `localhost:3000`. Note that the backend server should be running for the frontend to work.

### Building for Production

To **build** the frontend, resulting in a static bundle, you need to navigate to the frontend directory and run `npm run build`. This will create a static bundle in the `frontend/dist` directory, which the server can serve. The `frontend/dist` will have to be moved/renamed to `backend/static` for the full application to work. These steps are automated when building the final release container.

## Release Builds

The release build for the backend is a simple binary that can be run on any machine. The release build for the frontend is a static bundle that can be served by any web server.

There are two ways to deploy the release build: as a standalone binary or as a container. The drawbacks of using a standalone binary is that it requires fiddling with the static files as well as matching it with a database on the host system. The drawbacks of using a container is that it requires Podman/Docker. The container is the recommended way to deploy the release build, and doing it this way, we can also deploy the database in a container.

### Container Deployment

We combine the frontend and backend into a single container using Podman/Docker. The `Containerfile` (also known as a Dockerfile) in the container directory is used to build the container. To see exactly how the container is built, refer to the `Containerfile`.

To build and reploy a release container with Podman, issue the `just start-release` command anywhere in the project directory. This will build the container and run it on `localhost:8080`. The container will be running in the background, and you can manage it with Podman see the podman documentation for more information.

### Standalone Binary Deployment

UNDER CONSTRUCTION
