Customer profiles: the name, phone and address attached to an account, and the minimal public view of them.
- Owns: the
user_profilesrow for a given user — first and last name, phone, address — and the public display-name projection derived from it. - Does not own: identity. Credentials, username and email uniqueness, the
authoritative
userstable and token issuance all belong toauth-service. The profile references a user id across that boundary with no foreign key.
| Area | Technology |
|---|---|
| Runtime | Go 1.27 |
| Transports | HTTP only — no gRPC server, no client, no worker |
| Data | PostgreSQL — one table, user_profiles |
| Platform libraries | authmw, dbx, httpx, logger/zapx, migratex, obsx |
- Canonical contract:
homelab/docs/api/user.md - Shared conventions:
homelab/docs/api/api.md - Surfaces: a public read of one profile plus a JWT-protected read and update
of your own profile. There is no create route — profiles arrive just-in-time
from the verified token (see Gotchas). HTTP
:8080also carries/healthand/ready.
Routes, payloads and error codes live in the contract, so there is one place to change when they change.
Prefer the homelab local-stack — the private routes need a signed token, so auth-service has to be running.
Standalone you need PostgreSQL reachable through the DB_* variables:
go run cmd/main.go migrate # apply schema migrations
go run cmd/main.go seed # demo profiles — development only, refuses production
go run cmd/main.go # serve HTTP :8080The commands CI runs, so a green local run means a green pipeline:
go build ./...
go test -race ./...
go test -tags=integration ./internal/core/repository/... # needs Docker (testcontainers)
golangci-lint runMIT