Skip to content

Cijin/shave

Repository files navigation

2

Table of Contents

  1. Getting started
  2. Set env
  3. Running dev environment
  4. Migrations
    1. Create new migration
    2. Migrating down
    3. Viewing current migration version
  5. Directory structure 1 Views 2. Pkg
  6. Versioning
    1. Creating new versions
    2. Viewing version info
  7. Production
  8. Using the right final image

Getting started

Ensure the following dev-dependencies are installed:

  1. Ensure Go version 1.22.3 or later is installed. You can find installation/upgrade instructions here
  2. Install sqlc, it is the tool used to generate database boilerplate from queries. NOTE: Sqlc is not an ORM.
  3. Install templ, it generates the typed go templates, which is what the UI is. Make sure templ version matches the one installed in go.mod
  4. Install tailwindcss, NOTE: this step can be skipped by creating a new make file instruction to use npx instead.
  5. Install air, this ensures hot reloading of .go file changes, useful when running dev env. NOTE: Air is already configured (check ./air.toml). You only need to install air

Set env

  1. Rename/copy env.example in the root to .env
  2. Get values from developer / AWS parameter store as above
  3. For connecting to local database
  4. Connecting to RDS on AWS, get the values from the parameter store as above

Running dev environment

  1. Start the database by running docker compose up, use the -d flag to run it as a daemon
  2. Run make dev, this will run all the project dependencies in watch mode

Migrations

  • Ensure goose is installed
  • Ensure DB is up and running

Create new migration

  1. Inside ./internal/sql/schema, create a new migration file, in the format: <XXXX>_<useful_migration_name>.sql
  2. Run make db-up

Migrating down

Run make db-down. This will migrate down the second latest migration version

Viewing current migration version

The server logs will show the current migration version

Directory structure

Most of the files and folders are self-explanatory. I'll only go through the ones, that might not be obvious.

Views

The UI is built with franken-ui, which is an HTML only UI kit, perfect for this use case. It uses tailwind-css to style elements. There are a bunch of pre-defined tailwind definitions which begin with uk-, so look for these first, only write tailwindcss when absolutely neccessary.

For making ajax requests to the server htmx is used.

All js interactions are handled using alpine. It also provides a set of useful UI components. I've paid for components, you can use my credentials if needed.

This is where all the templ files reside. This package is further divided into components, , and layouts.

view/
    layouts/ : Contains layout definitions and other dependencies to make the HTML look and run the way it should. Fonts, css, js, htmx, etc.
    <models>/ : Create a folder for model pages, an example would be cases, which would have an index page, edit and delete page 
    components/ : Any reusable piece of HTML, especially ones that have js or css rules that might need to be consistent

Pkg

All services that make the server function are defined here. Any new ones should be defined here as and when needed.

pkg/
    data/ : all the models which will be shared between UI and handlers are defined here, makes it easy to seemlessly return HTML in response to requests
    handlers/ : All route handler and their definitions. Each model has their own handler file, and defines all CRUD and types here
    middleware/ : Self explanatory

Versioning

There is an internal/version package that handles the current version. The Version variable is updated during build time in production. In a dev setting, it will use the default value of dev.

Creating new versions

To create a new version, use git tag <x.x.x>. Use semantic versioning. You don't need to create a new tag everytime you push a new version. This is handled by the Dockerfile. Only create new tags for major updates.

When creating a new build using the make prod command without a new tag. This is what the version info will look like: <latest-tag>-<commits-since-latest-tag>-<commit-sha>

Viewing version info

  1. Server logs
  2. UI Footer

Production

When making production builds, always use the make prod command. DO NOT invoke the docker build command manually. This ensures, the build tag and server versions match. This will make it easier to handle managing containers much more easier.

Final image

Since we go-libsql requires CGO, unless the final image contains the neccessary glibc binaries, the final binary will not run. You can check this by running ldd <go-binary>. The latest golang:1.23-bookworm image seems to contain all the neccessary files. Hence, why I've chosen that.