Files
walkies/CLAUDE.md

3.3 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commands

A Taskfile.yml is provided — run task to list all tasks. Key ones:

task build          # build frontend + Go binary
task go:run         # build frontend then start server on :8080
task web:dev        # frontend hot-reload dev server on :3000
task go:test        # run all Go tests
task go:test:verbose
task go:lint        # go vet
task web:test       # frontend tests
task docker:up      # docker-compose up --build
task clean          # remove build artifacts

For a single Go package test: go test ./internal/volunteer/...

Architecture

Go Backend

Domain-based packaging under internal/ — each domain owns its models, store (DB queries), and HTTP handler in a single package:

Package Responsibility
internal/volunteer Volunteer CRUD; also owns /auth/login and /auth/register handlers
internal/schedule Shift scheduling
internal/timeoff Time-off requests and admin review
internal/checkin Check-in / check-out and history
internal/notification Per-volunteer notifications
internal/auth JWT issuance (auth.Service) and HashPassword
internal/db MySQL open + one-shot schema migration (db.Migrate)
internal/respond respond.JSON / respond.Error helpers
internal/server Wires all handlers into a chi router; serves static files at /
internal/server/middleware Authenticate (JWT) and RequireAdmin middleware; ClaimsFromContext

cmd/server/main.go opens the DB, runs migrations, calls server.New, and starts http.ListenAndServe.

All API routes are prefixed /api/v1. The Go binary serves the compiled React app from STATIC_DIR (default ./web/dist) for all non-API routes.

React Frontend

Standard CRA layout in web/src/:

  • api.ts — typed fetch wrapper; reads JWT from localStorage, prefixes BASE = '/api/v1'
  • auth.tsxAuthProvider context; decodes the JWT payload to expose role and volunteerID
  • pages/ — one file per route (Dashboard, Schedules, TimeOff, Volunteers, Login)
  • App.tsxBrowserRouter with a ProtectedLayout that redirects to /login when no token is present; admin-only nav links gated on role === 'admin'

Data Storage

MySQL 8.0 via github.com/go-sql-driver/mysql. Schema is defined inline in internal/db/schema.go and applied via CREATE TABLE IF NOT EXISTS on every startup. No migration framework — additive changes are safe; destructive changes require manual handling.

Auth

HS256 JWT signed with JWT_SECRET. Token payload: { volunteer_id, role, exp }. Role is either volunteer or admin. The RequireAdmin middleware enforces admin-only routes server-side.

Environment Variables

Variable Default Description
DB_HOST localhost MySQL host
DB_PORT 3306 MySQL port
DB_USER root MySQL username
DB_PASSWORD `` MySQL password
DB_NAME walkies MySQL database name
JWT_SECRET change-me-in-production HMAC signing key
STATIC_DIR ./web/dist Path to compiled React app
PORT 8080 HTTP listen port