Skip to content

ooaklee/ghatd

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

68 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ghat

GHAT(D)

GHAT(D) is an open-source, opinionated, and free full-stack web application foundation based on the Go programming language. Its name is an acronym that stands for Go, HTMX, Alpine.js, Tailwind, and DaisyUI, which originally formed the foundational stack. Over time, for improved usability, it has also been extended to support most Vite-compatible front-end stacks (tested with Vue). The aim is to make GHAT(D) a solid base for creating highly portable, scalable, and performant full-stack projects. Whether you need just a backend, a landing page, or even a blog (coming soon), you can still utilise GHAT(D) without committing to a hidden application container.

We recognise that everyone has unique needs, and ideally their solutions should not start with a messy foundation that requires cleaning up before building. To reduce cognitive load and make preparation easier, we have introduced "builder blocks" which we call Details. A Detail is an independent application that can function both within a GHAT(D) project and on its own. At present, we only support api, web, web-vite (WIP) typed Details.

Motivation

GHAT(D) is a hobby project I work on in my spare time. It is designed to provide a friendly starting point for people like me who are interested in Go, APIs, and web applications, and who want a consistent foundation and shared standards to build from. I hope GHAT(D) can serve as an ejectable base for many awesome projects and initiatives.

I also aim to use this project as a learning opportunity, to improve my understanding of and share my knowledge of lightweight frontend libraries, highly portable full-stack alternatives, and cost-effective infrastructure solutions for full-scale products.

As we develop this project, I want to also create tutorials/guides for those who want to integrate it with other technologies, such as rpc, graphql, websocket, and others.

I am a platform engineer by trade, so I do not promise perfect code by any stretch of the imagination (especially with the front end - so please support and contribute). Instead, I am aspiring to create a standardised project base that helps those curious (about Go, APIs, hobby projects, and web app development) to turn their ideas/ hobbies into tangible product(s) that they can demo and even ship.

This will be an exciting experience, and I look forward to building out this project with you all and sharing my progress and knowledge as it matures.

Core Packages

GHAT(D) offers modular packages that can be used both together and independently. Our goal is for each package to adhere to clean architecture principles, featuring comprehensive documentation and examples. We are committed to implementing these practices on both new and legacy package, especially those that are less extensible for other projects.

Authentication & Verification

A dual-channel verification system providing both magic link and human-readable code entry.

  • Access Manager - Complete authentication and authorisation with email-based verification, login, OAuth, and API token management
    • accessmanager - User creation, login, registration, email verification, OAuth, API token management
    • accessmanager/middleware - JWT, API token, rate-limiting, and hardened code-verification middleware
    • accessmanager/helpers - Context-transmission utilities and unique code generation
    • auth - JWT creation, validation, and metadata extraction
    • apitoken - API token lifecycle management

Email System

A complete email solution split into three composable packages for maximum flexibility and testability.

  • Email Manager - Complete email system with templating, sending, and audit logging
    • emailtemplater - Generate HTML email templates with variable substitution
    • emailprovider - Abstract email sending across providers (SparkPost, logging, custom)
    • emailmanager - High-level orchestration with audit integration

Billing System

A complete billing solution split into three composable packages for maximum flexibility and testability.

  • Billing Manager - Complete billing system with webhook processing, subscription management, and audit logging
    • paymentprovider - Abstract payment provider webhook verification and payload normalisation (Stripe, Lemon Squeezy, Ko-fi)
    • billing - Manage subscription and billing event data persistence with repository pattern
    • billingmanager - High-level orchestration with webhook processing and audit integration
  • Pricer - Source-of-truth pricing catalog with plans, feature entitlements, provider refs, Mongo migrations, and pricing-card E2E fixtures
    • pricer - Manage pricing plans, costs, features, and provider-linked catalog metadata

Additional Packages

  • Audit - Handles audit logging for compliance and debugging
  • Logger - Structured logging with middleware support
  • Notifier - Push notification registration, preferences, and delivery
  • Reminder - User-owned scheduled reminders with target-based lookups and execution tracking
  • Streaker - Generic idempotent streak completions, current/best stats, and history listing
  • Repository - MongoDB repository patterns and utilities
  • Server - Ejectable HTTP server lifecycle helper with graceful shutdown
  • Starter/v0 - Ejectable lazy composition layer for GHATD application wiring
  • Error Manifest - Cross-package error mapping and bundle composition
  • TBC

Note on Core Packages: This Core Package and sub-sections will be updated as more core packages are added and the refactoring work is completed on legacy packages. The goal is to ensure that each package includes a getting-started guide accompanied by working examples to help you integrate them into your projects.

Dual-Channel Verification

GHAT(D) supports a dual-channel verification flow for login and email verification — users receive both a magic link (with a JWT token) and an 8-character alphanumeric code in the same email.

How It Works

  1. Email delivery: Both login and verification emails contain a clickable magic link AND a human-readable 8-character code displayed in large monospaced font.
  2. Link flow (?t=<jwt-token>): User clicks the magic link → token is validated → user is authenticated.
  3. Code flow (?c=ABCD1234): User enters the code in the app or web interface ("I already have a session code") → code is resolved to its corresponding token via ephemeral storage → token is validated → user is authenticated.
  4. Code generation: Each code is globally unique (A-Z, 0-9), crypto-random, stored in ephemeral storage with a TTL matching the token expiry, and regenerated on collision.

Security Measures

Layer Mechanism
Code entropy 8-character A-Z/0-9 = ~2.8 trillion combinations
Collision resistance Ephemeral storage check with up to 5 retry attempts
Brute-force protection HardenedRateLimitProtection middleware tracks attempts per IP and per code within a configurable window (default: 5/hr per IP, 5/hr per code)
Auto-blocking IPs exceeding the threshold are temporarily blocked (default: 1 hour)
One-time use Codes and tokens are invalidated after successful verification
Time-bounded All codes and tokens have TTLs (default: 10 minutes for login/verification)
Refresh rotation tolerance Near-concurrent duplicate refreshes can reuse the winning rotation result instead of consuming the same refresh token twice
Login email cooldown Duplicate login email sends for the same active user/context are suppressed during a short cooldown window
Audit logging All verification attempts (pass and fail) and rate-limit blocks are logged for monitoring
Rate-limit response Blocked IPs receive HTTP 429 with EPH0-002 — no information leakage

Starting locally

Before getting started please make sure you have the correct version of Go installed or you can use asdf to install the pinned toolchain from .tool-versions. Minimum required Go version: 1.26.4.

# Add the plugin for Go
asdf plugin add golang

# Install the pinned version
asdf install

Use asdf exec when running maintenance commands so local validation uses the same Go toolchain as the repository:

asdf exec go test ./...
asdf exec go run golang.org/x/vuln/cmd/govulncheck@v1.3.0 ./...
asdf exec go mod tidy

Using the CLI (WIP)

To start using the CLI you can use the code:

go run cli/cli.go

You can then pass your desired cli command with:

go run cli/cli.go <desired-command>

TODO: Implementing the new command

We are currently implementing the new command, which will create a base folder for a new ghat(d) compatible file.

Example local command

go run cli/cli.go new -n "awesome-service" -w "github.com/ooaklee/ghatd-detail-web-demo-landing-dash-and-more,github.com/ooaklee/ghatd-detail-api-demo-endpoints"

Prerequisites

  • Detail repo for demo-endpoints
  • Detail repo for demo-dash

Success Criteria

  • The implementation will be considered successful once the user can run the command below and get an output directory with a working app (after running go mod tidy)
    • Once tidied, the user should be able to run go run cmd/server.go start-server in the output directory and access http://localhost:4000/.

Starting the server

To start the server you can use the code:

go run main.go start-server

However, for a better development expierence, please install the package reflex which will enable you to hot-reload by rerun a specified command on file change, and running the command:

reflex -r '\.(html|go|css|png|svg|ico|js|woff2|woff|ttf|eot)$' -s -- go run main.go start-server

More information on hot-reloading can be found below

Good to know

ASCI Art

All ASCI related code in this template was created using PatorJK

Curl Examples

  • Making GET resquest: curl -i -X GET "http://localhost:4000/v0/health/check"

How to stop file server showing directory listing?

Add a blank index.html file to the specific directory that you want to disable listings for. For example, the code below will create an index file which will stop the web app from showing and listing page.

touch internal/web/ui/static/index.html

Hot reloading

Install reflex

go install github.com/cespare/reflex@latest

You can find more information in the repo https://github.com/cespare/reflex

Once installed, run the server

reflex -r '\.(html|go|css|png|svg|ico|js|woff2|woff|ttf|eot)$' -s -- go run main.go start-server

How to build binaries

One of the benefits of using the GHATD stack is that it compiles everything into a single binary. This makes it highly portable and provides numerous deployment options.

CLI

To build a binary for the GHATDCLI for your desired system architecture, please follow the instructions below:

All commands should be executed from the root directory.

Mac OS (ARM64)
export BINARY_NAME=ghatdcli
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -a -installsuffix cgo -ldflags="-w -s" -o ./$BINARY_NAME cli/cli.go
Mac OS (AMD64)
export BINARY_NAME=ghatdcli
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -a -installsuffix cgo -ldflags="-w -s" -o ./$BINARY_NAME cli/cli.go
Linux (ARM64)
export BINARY_NAME=ghatdcli
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -a -installsuffix cgo -ldflags="-w -s" -o ./$BINARY_NAME cli/cli.go
Linux (AMD64)
export BINARY_NAME=ghatdcli
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo -ldflags="-w -s" -o ./$BINARY_NAME cli/cli.go

Web App

To build a binary for web app to your desired system architecture, please follow the instructions below:

All commands should be executed from the root directory.

Mac OS (ARM64)
export BINARY_NAME=ghatd
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -a -installsuffix cgo -ldflags="-w -s" -o ./$BINARY_NAME main.go
Mac OS (AMD64)
export BINARY_NAME=ghatd
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -a -installsuffix cgo -ldflags="-w -s" -o ./$BINARY_NAME main.go
Linux (ARM64)
export BINARY_NAME=ghatd
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -a -installsuffix cgo -ldflags="-w -s" -o ./$BINARY_NAME main.go
Linux (AMD64)
export BINARY_NAME=ghatd
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo -ldflags="-w -s" -o ./$BINARY_NAME main.go

License

This project is licensed under the MIT License.

About

All-in-one framework to quickly build full-stack Go (Golang) web applications

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages