Go · REST · CLI · REPL

A library backend,
built properly.

Authors, books with real per-title copy counts, borrowers, and transactional checkout/return — a small, layered Go service with real validation, JWT-protected writes, and full test coverage. No ORM, no magic.

HTTP · CLI · REPL handler → service (business rules) repository → SQLite
0Domain entities
0Interfaces: HTTP/CLI/REPL
0% test coverage
0Lint issues

Small on purpose, correct throughout

Every layer does exactly one job — nothing borrowed from a framework it doesn't need.

Real layering

handler → service → repository, each with its own tests. No handler ever touches SQL; no service ever touches the network.

JWT-protected writes

Every GET is public — a catalog is meant to be browsed. Every POST/PUT/DELETE requires a bearer token, checked by dedicated middleware.

Real copy counts

Books track total and available copies, not a single boolean — a race-safe `UPDATE ... WHERE available_copies > 0` guards every checkout.

Validated at the door

Request DTOs are separate from domain models and struct-tag validated — mass assignment into DB models is structurally impossible.

HTTP, CLI & REPL

The same binary is a server, a one-shot CLI, and an interactive shell — all three talk to the REST API the same way.

Tested at every layer

Real in-memory SQLite, not mocks — repository, service, and full HTTP-through-middleware handler tests, race-checked.

One binary, three ways in

No arguments runs the server. A subcommand makes it a CLI or REPL client of that same API.

HTTP server

go run ./cmd/api

CLI

go run ./cmd/api books list

REPL

go run ./cmd/api repl
library> books list

Standard library first

net/httpGo 1.22+ ServeMuxdatabase/sqlSQLitemodernc.org/sqliteJWTbcryptgo-playground/validatorlog/slogCobra CLIOpenAPI 3.0.3DockerDocker ComposeGitHub Actionsgolangci-lintTrivy