Repository navigation
feat: Go foundation (server, database, services, JSON API, lint layering, CI, deploy, agent docs) - #1
Merged
Merged
Conversation
… repository Repository tests run against a real Postgres: one throwaway server, a migrated template database built once, and a per-test clone so tests run in parallel. The Better Auth user table comes from a stub until packages/auth lands. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… pinned tools Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… UserService Config is validated once at boot and reports every problem together. UserService enforces the not-self 403 rule and returns typed service errors that transports map to status codes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…endpoints Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…unt points serve binds 0.0.0.0:PORT, logs with slog, rejects cross-origin browser writes, and shuts down gracefully on SIGTERM. migrate runs the auth migrations (stubbed until packages/auth) and then the app migrations. In development a dev auth fake signs requests in as a seeded user. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…f script scripts/check-layering.sh drops a probe with a forbidden import into each guarded layer and fails unless depguard reports all of them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d race tests ci-ok is the single required check; merge_group is supported. actionlint gets its own tools module because its yaml dependency conflicts with golangci-lint's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, /healthz) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sqlc needs cgo; regenerating on every dev run would require a C toolchain on a fresh clone. make generate stays explicit and CI checks the diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Drafts run no jobs; marking ready for review runs CI. merge_group, push to main and workflow_dispatch always run everything. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Measurement done; workflow_dispatch works once ci.yml is on main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jayleaton
marked this pull request as ready for review
October 22, 2026 06:36
This was referenced Oct 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The Go successor to the Next.js template has no foundation yet. There is no server, no database layer, no layering enforcement, no CI and no agent docs, so
feat/authandfeat/web-uihave nothing to plug into.How
Same layers as the original, rebuilt in Go and enforced by lint:
server servebinds 0.0.0.0:PORT with slog logging, rejects cross-origin browser writes, and shuts down gracefully.server migrateruns auth migrations, then app migrations (goose_app).AppRoutes/APIRoutesandFeatureslive inapps/web/internal/config. There are no hardcoded origins.GET/PATCH/DELETE /api/core/v1/usersandPATCH /api/core/v1/users/{id}. Input types live invalidate; each handler is about five lines..golangci.yml.scripts/check-layering.shproves they still reject forbidden imports.railway.json(pre-deploy/server migrate, healthcheck/healthz), one CI workflow (path filters, generated-code diff, golangci-lint, race tests,ci-okas the single required check,merge_group, drafts skipped), plus AGENTS.md, CLAUDE.md, CONTEXT.md and README.md.Evidence
All numbers are from local runs.
make ci(build, generated-code diff, lint, layering proof, race tests)gojob 1m44s (build 23 s, tests 33 s)gojob 36 s, of which service container 10 s and setup-go cache restore 12 smake db-up && make migrate && make devserved/healthzand the users API with the dev auth fake.make lint testgave 0 issues and all packages passed.Decisions to revisit
UpdateUserSettings: the app may only changenameandimage, so anemailfield gets a 400. Email changes belong in the auth flows.image: nullclears the image. The original couldn't clear it once set.usertable: untilpackages/authlands,migratecreatesuserfrom a stub (packages/database/authstub). In development every request is signed in as a seeded dev user; outside development, protected routes return 401. A dev database migrated with the stub may needdocker compose down -vonce real auth lands.PORT(Railway sets it),TRUSTED_ORIGINSandFROM_EMAIL.tools/go.mod, not the rootgo.mod. actionlint has its owntools/actionlint/go.mod, because its yaml dependency clashes with golangci-lint's.make devandmake builddon't regenerate code. sqlc needs cgo, and the generated code is committed; CI checks it's up to date.ENTRYPOINTin the image, so Railway's/server migrateoverride can't be prefixed with a second/server.Wiring left for the merges
TODO(feat/auth)in the code):auth.Migrateinstead ofauthstub.Migrate, inapps/web/cmd/server(migrations) and inpackages/database/dbtest/app.go.packages/database/sqlc.yamlat../auth/migrations.*auth.Authasserver.Deps.Auth, plus a ~6-line function that turnsauth.UserFrominto anapi.CallerFrom.apps/web/internal/server/devauthandpackages/database/authstub.http.Handlerasserver.Deps.UI; it is mounted at/. Add templ as atoolin the rootgo.mod.make generateand CI already runtempl generateonceapps/web/uiexists.Merge Danger
Door: two-way. Nothing is deployed, and the branch only adds files.
Blast Radius: repo-wide. Every later branch builds on these layers, the lint rules and CI.
🤖 Generated with Claude Code