Vendor pinned prettier/format toolchain from prompts scaffold (closes #203)
Check / check (pull_request) Skipped

Replace the unpinned `npx prettier --tab-width 4` in `script/fmt` with the
canonical toolchain vendored from `sneak/prompts`: `.prettierrc` (tabWidth 4,
proseWrap always), pinned `package.json` + `yarn.lock` (prettier 3.8.1), and a
`.prettierignore` that unions the scaffold entries with the repo's `*.min.js`
line. `script/bootstrap` now installs a pinned node/yarn via a hash-verified
nvm release archive (never curl-pipe-sh), so prettier stops being an unpinned
host tool. `script/fmt` runs the pinned prettier via `.prettierrc` over
`static/js/*.js` and `**/*.md`, keeping gofmt/goimports. All existing markdown
is reflowed to house style; `static/js/alpine.min.js` stays byte-identical.

Model: opus-4-8
This commit is contained in:
2026-09-22 12:22:04 +00:00
parent f2e4be5eed
commit c943ccc5dd
9 changed files with 277 additions and 136 deletions
+37 -31
View File
@@ -1,6 +1,8 @@
# Go HTTP Server Conventions
This document defines the architectural patterns, design decisions, and conventions for building Go HTTP servers. All new projects must follow these standards.
This document defines the architectural patterns, design decisions, and
conventions for building Go HTTP servers. All new projects must follow these
standards.
## Table of Contents
@@ -25,18 +27,18 @@ This document defines the architectural patterns, design decisions, and conventi
These libraries are **mandatory** for all new projects:
| Purpose | Library | Import Path |
|---------|---------|-------------|
| Dependency Injection | Uber fx | `go.uber.org/fx` |
| HTTP Router | go-chi | `github.com/go-chi/chi` |
| Logging | slog (stdlib) | `log/slog` |
| Configuration | Viper | `github.com/spf13/viper` |
| Environment Loading | godotenv | `github.com/joho/godotenv/autoload` |
| CORS | go-chi/cors | `github.com/go-chi/cors` |
| Error Reporting | Sentry | `github.com/getsentry/sentry-go` |
| Metrics | Prometheus | `github.com/prometheus/client_golang` |
| Metrics Middleware | go-http-metrics | `github.com/slok/go-http-metrics` |
| Basic Auth | basicauth-go | `github.com/99designs/basicauth-go` |
| Purpose | Library | Import Path |
| -------------------- | --------------- | ------------------------------------- |
| Dependency Injection | Uber fx | `go.uber.org/fx` |
| HTTP Router | go-chi | `github.com/go-chi/chi` |
| Logging | slog (stdlib) | `log/slog` |
| Configuration | Viper | `github.com/spf13/viper` |
| Environment Loading | godotenv | `github.com/joho/godotenv/autoload` |
| CORS | go-chi/cors | `github.com/go-chi/cors` |
| Error Reporting | Sentry | `github.com/getsentry/sentry-go` |
| Metrics | Prometheus | `github.com/prometheus/client_golang` |
| Metrics Middleware | go-http-metrics | `github.com/slok/go-http-metrics` |
| Basic Auth | basicauth-go | `github.com/99designs/basicauth-go` |
---
@@ -85,7 +87,8 @@ project-root/
### Key Principles
- **`cmd/{appname}/`**: Only the entry point. Minimal logic, just bootstrapping.
- **`internal/`**: All application packages. Not importable by external projects.
- **`internal/`**: All application packages. Not importable by external
projects.
- **One package per concern**: config, database, handlers, middleware, etc.
- **Flat handler files**: One file per handler or logical group of handlers.
@@ -190,7 +193,8 @@ Providers are resolved automatically by fx, but conceptually follow this order:
2. `logger.New` - Logger (depends on Globals)
3. `config.New` - Configuration (depends on Globals, Logger)
4. `database.New` - Database (depends on Logger, Config)
5. `healthcheck.New` - Health check (depends on Globals, Config, Logger, Database)
5. `healthcheck.New` - Health check (depends on Globals, Config, Logger,
Database)
6. `middleware.New` - Middleware (depends on Logger, Globals, Config)
7. `handlers.New` - Handlers (depends on Logger, Globals, Database, Healthcheck)
8. `server.New` - Server (depends on all above)
@@ -453,7 +457,8 @@ func New(lc fx.Lifecycle, params HandlersParams) (*Handlers, error) {
### Closure-Based Handler Pattern
All handlers return `http.HandlerFunc` using the closure pattern. This allows initialization logic to run once when the handler is created:
All handlers return `http.HandlerFunc` using the closure pattern. This allows
initialization logic to run once when the handler is created:
```go
// internal/handlers/index.go
@@ -510,7 +515,8 @@ func (s *Handlers) decodeJSON(w http.ResponseWriter, r *http.Request, v interfac
### Handler Naming Convention
- `HandleIndex()` - Main page
- `HandleLoginGET()` / `HandleLoginPOST()` - Form handlers with HTTP method suffix
- `HandleLoginGET()` / `HandleLoginPOST()` - Form handlers with HTTP method
suffix
- `HandleNow()` - API endpoints
- `HandleHealthCheck()` - System endpoints
@@ -733,7 +739,8 @@ func New(lc fx.Lifecycle, params ConfigParams) (*Config, error) {
1. **Environment variables** (highest priority via `AutomaticEnv()`)
2. **`.env` file** (loaded via `godotenv/autoload` import)
3. **Config files**: `/etc/{appname}/{appname}.yaml`, `~/.config/{appname}/{appname}.yaml`
3. **Config files**: `/etc/{appname}/{appname}.yaml`,
`~/.config/{appname}/{appname}.yaml`
4. **Defaults** (lowest priority)
### Environment Loading
@@ -1005,6 +1012,7 @@ var Static embed.FS
```
Directory structure:
```
static/
├── static.go
@@ -1045,15 +1053,13 @@ Templates use Go's template composition:
```html
<!-- index.html -->
{{ template "htmlheader.html" . }}
{{ template "navbar.html" . }}
{{ template "htmlheader.html" . }} {{ template "navbar.html" . }}
<main>
<!-- Page content -->
</main>
{{ template "pagefooter.html" . }}
{{ template "htmlfooter.html" . }}
{{ template "pagefooter.html" . }} {{ template "htmlfooter.html" . }}
```
### Static Asset References
@@ -1214,12 +1220,12 @@ if viper.GetString("METRICS_USERNAME") != "" {
### Environment Variables Summary
| Variable | Description | Default |
|----------|-------------|---------|
| `PORT` | HTTP listen port | 8080 |
| `DEBUG` | Enable debug logging | false |
| `DBURL` | Database connection URL | "" |
| `SENTRY_DSN` | Sentry DSN for error reporting | "" |
| `MAINTENANCE_MODE` | Enable maintenance mode | false |
| `METRICS_USERNAME` | Basic auth username for /metrics | "" |
| `METRICS_PASSWORD` | Basic auth password for /metrics | "" |
| Variable | Description | Default |
| ------------------ | -------------------------------- | ------- |
| `PORT` | HTTP listen port | 8080 |
| `DEBUG` | Enable debug logging | false |
| `DBURL` | Database connection URL | "" |
| `SENTRY_DSN` | Sentry DSN for error reporting | "" |
| `MAINTENANCE_MODE` | Enable maintenance mode | false |
| `METRICS_USERNAME` | Basic auth username for /metrics | "" |
| `METRICS_PASSWORD` | Basic auth password for /metrics | "" |