nestcore

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 30, 2026 License: AGPL-3.0 Imports: 0 Imported by: 0

README

nestcore

Shared infrastructure module for the Nest household-appliance apps (Nestova, Nestorage): configuration, database access, HTTP serving, rendering, caching, crypto, metrics — platform concerns only. No domain code lives here — anything that references a consumer's domain model (household, item, bin, etc.) belongs in that app's own repo, not nestcore.

The package layout is flat and non-internal (config/, db/, httpserver/, render/, qrcode/, ...) rather than nested under internal/. Go forbids importing another module's internal/ packages, so anything nestcore needs to expose to Nestova or Nestorage has to live outside internal/ from the start.

Development

Prerequisites

Everything else (lefthook, conform) is pinned in go.mod via Go tool directives, so no global install is needed — invoke it with go tool <name>. golangci-lint is the exception: its maintainers advise against go install, so it is installed as a pinned binary instead.

Common tasks
make build      # type-check the module (a library emits no binary artifact)
make test       # run tests with the race detector + coverage profile
make cover      # print a per-function coverage summary
make lint       # run static analysis (golangci-lint)
make fmt        # format Go sources (gofumpt + goimports via golangci-lint)
make hooks      # install the Lefthook Git hooks
make tidy       # prune and verify module dependencies
make help       # list all targets
Linting (golangci-lint)

Install the pinned v2.11.4 release from the golangci-lint releases page rather than go install (the project's own recommendation — it risks building against an untested Go version or dependency set). CI installs the same version via golangci/golangci-lint-action; keep both in sync with GOLANGCI_LINT_VERSION in the Makefile.

Testing

make test runs the default suite with the race detector — hermetic, no database required. db/... additionally has database-gated tests behind the NESTCORE_TEST_DATABASE_URL environment variable; run make test-gated to include that coverage. The role that variable's DSN authenticates as needs the CREATEDB privilege — the gated harness creates a database per package on demand. CI runs make test-gated too, against a postgres:16-alpine service container. See docs/testing.md for the container recipe, the isolation model, and how a consuming application wires its own dbtest.Harness.

Configuration

config loads and validates runtime configuration from environment variables, one sub-config at a time (see the package doc for the loader / validator pattern). Every variable below is read exclusively from the environment; an optional .env file is honored in development only, via LoadDotenv, and never overrides a variable the real environment already set.

An application composes its own root configuration from these sub-configs and adds whatever is specific to its own domain — see config.go's AppEnv, ValidateAppEnv, and LoadDotenv for the pieces a composition needs beyond the sub-configs themselves.

Variable Sub-config Default
APP_ENV dev (dev|test|prod)
PORT Server 8080
TRUSTED_PROXIES Server 127.0.0.0/8,::1/128
SERVER_REQUEST_TIMEOUT Server 120s (floor 15s)
PUBLIC_BASE_URL Server empty (derive from the request)
DATABASE_URL DB none — required, no development fallback
DB_MAX_CONNS DB 0 (let the pool decide; 10 when DB_PROVIDER=supabase and unset)
DB_CONNECT_TIMEOUT DB 5s
DB_PROVIDER DB postgres (postgres|supabase)
DB_POOL_MODE DB session (session|transaction)
DB_SSL_ROOT_CERT DB empty
MIGRATE_DATABASE_URL DB empty (reuse DATABASE_URL)
SESSION_SECRET Session config.DevSessionSecret (dev-only; rejected in prod)
SESSION_LIFETIME Session 12h
SESSION_COOKIE_SECURE Session auto (auto|true|false)
ENCRYPTION_KEY Crypto config.DevEncryptionKey (dev-only; rejected in prod)
TLS_CERT_FILE / TLS_KEY_FILE TLS empty — both or neither
HSTS_ENABLED HSTS false
HSTS_MAX_AGE HSTS config.DefaultHSTSMaxAge (~180d) when enabled and unset
HSTS_INCLUDE_SUBDOMAINS HSTS false
HSTS_PRELOAD HSTS false (requires includeSubDomains + max-age >= 1y)
S3_ENDPOINT S3 empty (real AWS S3)
S3_REGION S3 empty
S3_BUCKET S3 empty
S3_ACCESS_KEY_ID / S3_SECRET_ACCESS_KEY S3 empty — both or neither (else the default AWS credential chain)
S3_USE_PATH_STYLE S3 false
S3_PRESIGN_TTL S3 15m
NOTIFY_SMS_ENABLED SMS false
SMS_ORIGINATION_IDENTITY SMS empty — required when enabled
SMS_REGION SMS empty — required when enabled
SMS_ACCESS_KEY_ID / SMS_SECRET_ACCESS_KEY SMS empty — both or neither
SMS_RETRY_MAX_ATTEMPTS SMS 3
NOTIFY_EMAIL_ENABLED Email false
SES_FROM_ADDRESS Email empty — required when enabled
SES_REGION Email empty — required when enabled
SES_ACCESS_KEY_ID / SES_SECRET_ACCESS_KEY Email empty — both or neither
CACHE_DIR Cache ./.localdata/cache

S3Config.Validate is caller-gated rather than self-gating on an Enabled field: nestcore has no storage-backend selector of its own, so a consuming application calls LoadS3/S3Config.Validate only when its own selector opted into S3. SMSConfig and EmailConfig self-gate on their own Enabled field instead, since that field travels with the type.

License

AGPL-3.0, matching both consumers (Nestova, Nestorage).

Documentation

Overview

Package nestcore is the shared infrastructure module behind Nestova and Nestorage. It holds platform concerns only — configuration, database access, HTTP serving, rendering, caching, crypto, metrics — and never domain code.

Directories

Path Synopsis
Package bootstrap handles first-run detection and persistence of the runtime configuration that must exist before the database does.
Package bootstrap handles first-run detection and persistence of the runtime configuration that must exist before the database does.
Package cache provides a small Cache port for data that is derived, re-computable, or externally sourced — an external API response, a normalized/aggregated read that is expensive to recompute but never the sole source of truth for it.
Package cache provides a small Cache port for data that is derived, re-computable, or externally sourced — an external API response, a normalized/aggregated read that is expensive to recompute but never the sole source of truth for it.
Package config loads and validates runtime configuration from the environment, one sub-config at a time.
Package config loads and validates runtime configuration from the environment, one sub-config at a time.
Package crypto provides password hashing and verification using the argon2id algorithm.
Package crypto provides password hashing and verification using the argon2id algorithm.
cryptotest
Package cryptotest provides test-only helpers for the crypto package, following the convention of the standard library's httptest.
Package cryptotest provides test-only helpers for the crypto package, following the convention of the standard library's httptest.
db
Package db provides Postgres connectivity for the application: a pooled connection built from configuration and a health check used for readiness.
Package db provides Postgres connectivity for the application: a pooled connection built from configuration and a health check used for readiness.
dbtest
Package dbtest provides the shared harness for database-gated tests.
Package dbtest provides the shared harness for database-gated tests.
migrate
Package migrate runs database schema migrations with goose over the pgx stdlib driver (a database/sql handle, distinct from an application's pgxpool).
Package migrate runs database schema migrations with goose over the pgx stdlib driver (a database/sql handle, distinct from an application's pgxpool).
Package httpserver wires the HTTP transport: the router, the core middleware chain, and the server lifecycle.
Package httpserver wires the HTTP transport: the router, the core middleware chain, and the server lifecycle.
middleware
Package middleware provides composable net/http middleware for the request backbone: request IDs, structured logging, panic recovery, and per-request timeouts.
Package middleware provides composable net/http middleware for the request backbone: request IDs, structured logging, panic recovery, and per-request timeouts.
identity
adapter
Package adapter contains the identity bounded context's outbound adapters: pgx-backed implementations of the ports declared in identity/domain, run against the schema identity/migrate owns.
Package adapter contains the identity bounded context's outbound adapters: pgx-backed implementations of the ports declared in identity/domain, run against the schema identity/migrate owns.
app
Package app contains the identity context's application services.
Package app contains the identity context's application services.
domain
Package domain holds the identity bounded context's entities, value objects, and ports (interfaces): Household, Member with the unified owner/adult/child Role vocabulary, and Credential — the password half of a member's login.
Package domain holds the identity bounded context's entities, value objects, and ports (interfaces): Household, Member with the unified owner/adult/child Role vocabulary, and Credential — the password half of a member's login.
migrate
Package migrate owns nestcore's identity schema: household, member (with its unified owner/adult/child role vocabulary and IDENTITY-level active flag), the MFA/recovery-code/WebAuthn credential tables, and the shared sessions table that gives Nestova and Nestorage one login (epic NSTR-112).
Package migrate owns nestcore's identity schema: household, member (with its unified owner/adult/child role vocabulary and IDENTITY-level active flag), the MFA/recovery-code/WebAuthn credential tables, and the shared sessions table that gives Nestova and Nestorage one login (epic NSTR-112).
Package metrics owns the caller's Prometheus instrumentation: the registry (with the standard process/runtime collectors), the HTTP request metrics observed by the middleware layer, and the background scheduler tick metrics recorded through the TickRecorder port.
Package metrics owns the caller's Prometheus instrumentation: the registry (with the standard process/runtime collectors), the HTTP request metrics observed by the middleware layer, and the background scheduler tick metrics recorded through the TickRecorder port.
Package qrcode is a thin platform seam over a QR-encoding library, mirroring the render package: it renders a QR code entirely server-side and returns it as a self-contained "data:image/png;base64,..." URI, so callers (Templ components) embed it directly in an <img src> with no client-side QR JS and no extra HTTP round trip to fetch the image.
Package qrcode is a thin platform seam over a QR-encoding library, mirroring the render package: it renders a QR code entirely server-side and returns it as a self-contained "data:image/png;base64,..." URI, so callers (Templ components) embed it directly in an <img src> with no client-side QR JS and no extra HTTP round trip to fetch the image.
Package render is the HTTP rendering seam for templ components.
Package render is the HTTP rendering seam for templ components.
Package totp is a thin platform seam over github.com/pquerna/otp (RFC 6238 TOTP), mirroring the qrcode and crypto packages: it isolates the third-party dependency behind a small, stateless surface so the caller's application layer depends on its own minimal interface rather than the library directly, keeping that layer's tests hermetic and the library swappable.
Package totp is a thin platform seam over github.com/pquerna/otp (RFC 6238 TOTP), mirroring the qrcode and crypto packages: it isolates the third-party dependency behind a small, stateless surface so the caller's application layer depends on its own minimal interface rather than the library directly, keeping that layer's tests hermetic and the library swappable.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL