go-modules

module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jun 28, 2026 License: MIT

README

go-modules

Shared platform library for Go services (Go 1.26, module github.com/tupicapp/go-modules). Reusable capabilities live under pkg; helpers that assume Tupic's clean architecture service layout live under clean. The dependency split is enforced by depguard in .golangci.yml, including tests.

Tree Role
pkg Reusable contracts, values, config loaders, and implementations (echo, nats, sqs, iam, gorm, gorm_outbox, postgres_migrator, logger, redis, s3, utility, ...)
clean Clean architecture helpers: application, interface, infrastructure, bootstrap, and reserved domain
events Cross-service integration-event wire contracts grouped by publishing service/domain
test Test doubles, named <capability>test
docs Shared package and service architecture documentation

docs/STRUCTURE.md is the canonical layer map — the full per-package breakdown, the contract/adapter split, and the absolute dependency rules live there; this table is just the orientation.

pkg/echo, pkg/nats, pkg/sentry, and pkg/config wrap same-named third-party packages that services may also import in the same files. Where both appear in one file, alias the upstream import (labecho, natslib); the wrapper keeps the clean name.

Service architecture docs

docs/ holds the reference architecture for every data intensive service built on this library — shared so it lives in one place instead of being copied into each repo:

Each service keeps only its own docs/DOMAIN.md and docs/SERVICE.md (flows, endpoints, deviations).

Auth architecture

Authentication (authentication) answers who is calling; authorization (authorization) answers may they do this. They meet in authorization.Actor.

HTTP request with "Authorization: Bearer <token>"
    │
    ▼
echo.AuthMiddleware ───────────────── marks admin routes for role hydration,
    │                                 continues anonymously on bad tokens
    ▼
authentication.Authenticator[U].Authenticate    U = the service's user entity
    │
    ├─ iam driver (production):       validate JWT against JWKS (RS256,
    │                                 issuer, expiry; refetch rate-limited)
    │                                   ├─ service-account token → service Actor, no user
    │                                   └─ user token → UserResolver[U] (service-owned
    │                                      find-or-provision) → user Actor + *U
    │
    └─ dummy driver (tests/local):    token is base64 JSON Actor
    │
    ▼
Actor + user stored in request context
    │
    ▼
http/middleware.RequireUser / RequireAdmin / RequireService   (route guards)
    │
    ▼
use case calls authorization.Authorizer.Authorize(actor, permissions...)
                                      (scope + permission policy: exact,
                                       admin-prefixed, or service wildcard)
What a service implements

Only its user resolver — everything else is shared:

// 1. The resolver: validated claims → the service's user entity.
type userResolver struct{ /* repo, clock, ... */ }

func (r *userResolver) Resolve(ctx context.Context, c *iam.Claims) (*myservice.User, error) {
    // find-or-provision; this is where per-service rules live
}

// 2. Wiring: one call.
authn, err := authentication.New(
    authentication.Config{Driver: cfg.Auth.Driver, IAM: iam.Config{
        Issuer: cfg.Auth.Issuer, JwksURL: cfg.Auth.JwksURL, ServiceName: "MyService",
    }},
    newUserResolver(...),
    repo.FindByID, // dummy-driver lookup
)

// 3. HTTP middleware: one struct.
echo.AuthMiddleware(echo.AuthConfig[myservice.User]{
    Authenticate:    authn.Authenticate,
    WithUser:        myservice.ContextWithUser,
    AdminPathPrefix: "/myservice/v1/admin",
})
Extending
  • Custom driver (API keys, another IdP): implement the one-method authentication.Authenticator[U] interface — or wrap a closure in authentication.Func[U] — and skip authentication.New. The middleware and guards only see the interface.
  • Function-only resolver: iam.UserResolverFunc[U] adapts a closure.
  • Test wiring: iam.WithHTTPClient injects an in-process round-tripper; iam.WithJWKSCooldown tunes (or disables) the JWKS refetch rate limit.
  • Permissions: fully qualified "<service>:<resource>.<action>" (e.g. "assets:assets.write"). The shared TokenAuthorizer matches the exact form, the admin:-prefixed form, and service wildcards (assets:*, admin:assets:*).

Consumption pattern

Services keep thin facade packages re-exporting shared contracts via type aliases (internal/domain/common, internal/application/port, …) so domain and application code never imports go-modules directly, plus one bootstrap/modules.go mapping service config to the narrow shared config types (logger_factory.Config, pkg/nats.Config, pkg/database.Config, ...).

Until the GitHub repo exists, services use replace github.com/tupicapp/go-modules => ../go-modules.

License

Released under the MIT License.

Directories

Path Synopsis
clean
application/port/domainevent
Package domainevent defines application ports for publishing and subscribing to clean-domain events.
Package domainevent defines application ports for publishing and subscribing to clean-domain events.
application/port/outbox
Package outbox re-exports the reusable outbox contract for clean services.
Package outbox re-exports the reusable outbox contract for clean services.
application/port/queue
Package queue defines the shared task-queue vocabulary: the Task contract, the default channel, and the channel→subject mapping.
Package queue defines the shared task-queue vocabulary: the Task contract, the default channel, and the channel→subject mapping.
application/service/activitylog
Package activitylog provides shared activity log application services.
Package activitylog provides shared activity log application services.
application/service/authorization
Package authorization re-exports the reusable authorization vocabulary for clean services.
Package authorization re-exports the reusable authorization vocabulary for clean services.
bootstrap
Package bootstrap provides shared application lifecycle logic and bootstrap helpers.
Package bootstrap provides shared application lifecycle logic and bootstrap helpers.
domain
Package domain is reserved for shared clean-domain helpers.
Package domain is reserved for shared clean-domain helpers.
domain/activitylog
Package activitylog defines the ActivityLog entity for tracking entity lifecycle events.
Package activitylog defines the ActivityLog entity for tracking entity lifecycle events.
infrastructure/authentication
Package authentication re-exports reusable authentication contracts for clean services.
Package authentication re-exports reusable authentication contracts for clean services.
infrastructure/migrator
Package migrator re-exports the reusable migrator contract for clean services.
Package migrator re-exports the reusable migrator contract for clean services.
infrastructure/migrator_factory
Package migrator_factory selects the migration driver from configuration.
Package migrator_factory selects the migration driver from configuration.
infrastructure/outbox_queue
Package outbox_queue implements the queue.Queue contract on top of the outbox: each task is stored as an outbox message whose subject carries the channel, so the relay ships it to the work-queue stream.
Package outbox_queue implements the queue.Queue contract on top of the outbox: each task is stored as an outbox message whose subject carries the channel, so the relay ships it to the work-queue stream.
interface/subscription/messaging
Package messaging re-exports the reusable inbound message contract for clean services.
Package messaging re-exports the reusable inbound message contract for clean services.
interface/subscription/objectstorage
Package objectstorage re-exports the reusable object-storage event contract for clean services.
Package objectstorage re-exports the reusable object-storage event contract for clean services.
events
assets
Package assets contains the public integration-event contracts owned by assets-core.
Package assets contains the public integration-event contracts owned by assets-core.
Package migrations embeds shared Tupic database migrations.
Package migrations embeds shared Tupic database migrations.
pkg
apperror
Package apperror defines the platform-wide application error type used to map domain and application failures to transport-level responses.
Package apperror defines the platform-wide application error type used to map domain and application failures to transport-level responses.
clock
Package clock provides the Clock contract to provide time with testability.
Package clock provides the Clock contract to provide time with testability.
config
Package config loads layered JSON configuration files with environment variable overrides into a service-defined config struct.
Package config loads layered JSON configuration files with environment variable overrides into a service-defined config struct.
database
Package database holds database connection configuration and lifecycle.
Package database holds database connection configuration and lifecycle.
echo
Package echo provides the shared Echo HTTP stack: instance assembly, apperror-aware error handling, request logging, Sentry integration, the HTTP server lifecycle, and actor guard middlewares.
Package echo provides the shared Echo HTTP stack: instance assembly, apperror-aware error handling, request logging, Sentry integration, the HTTP server lifecycle, and actor guard middlewares.
gorm_uow
Package gorm_uow provides the GORM implementation of the UnitOfWork contract, plus the context plumbing repositories use to join an ambient transaction.
Package gorm_uow provides the GORM implementation of the UnitOfWork contract, plus the context plumbing repositories use to join an ambient transaction.
iam
Package iam authenticates requests using IAM (Keycloak) service JWTs.
Package iam authenticates requests using IAM (Keycloak) service JWTs.
logger
Package logger provides the Logger contract.
Package logger provides the Logger contract.
messaging
Package messaging defines the transport-agnostic inbound message contract and router shared by subscription adapters (NATS, SQS, …).
Package messaging defines the transport-agnostic inbound message contract and router shared by subscription adapters (NATS, SQS, …).
migrator
Package contract defines the migration driver contract.
Package contract defines the migration driver contract.
nats
Package nats provides the NATS JetStream connection, subject routing, and event/queue subscribers shared by all Tupic services.
Package nats provides the NATS JetStream connection, subject routing, and event/queue subscribers shared by all Tupic services.
objectstorage
Package objectstorage defines the transport-agnostic object-storage event contract shared by storage-event adapters (SQS, SNS, EventBridge, …).
Package objectstorage defines the transport-agnostic object-storage event contract shared by storage-event adapters (SQS, SNS, EventBridge, …).
outbox
Package outbox implements the Transactional Outbox pattern: outbound messages are stored in the caller's DB transaction and a relay ships them to NATS asynchronously.
Package outbox implements the Transactional Outbox pattern: outbound messages are stored in the caller's DB transaction and a relay ships them to NATS asynchronously.
pagination
Package pagination defines shared cursor-pagination types.
Package pagination defines shared cursor-pagination types.
postgres_migrator
Package postgres_migrator implements the migration contract with golang-migrate.
Package postgres_migrator implements the migration contract with golang-migrate.
random
Package random provides a crypto/rand-backed implementation of the random.Random contract.
Package random provides a crypto/rand-backed implementation of the random.Random contract.
redis
Package redis provides a Redis client and lifecycle shared by Tupic services.
Package redis provides a Redis client and lifecycle shared by Tupic services.
s3
Package s3 implements the storage contract with AWS S3 (or a compatible API such as LocalStack/MinIO).
Package s3 implements the storage contract with AWS S3 (or a compatible API such as LocalStack/MinIO).
sentry
Package sentry initializes the Sentry SDK with a shutdown flush hook.
Package sentry initializes the Sentry SDK with a shutdown flush hook.
sqs
Package sqs is the SQS adapter for object-storage events: it polls an SQS queue fed by S3 bucket notifications, parses each message into an objectstorage.Event, and dispatches it through an objectstorage.Router.
Package sqs is the SQS adapter for object-storage events: it polls an SQS queue fed by S3 bucket notifications, parses each message into an objectstorage.Event, and dispatches it through an objectstorage.Router.
utility
Package utility provides general-purpose, dependency-free helper functions shared across Tupic services.
Package utility provides general-purpose, dependency-free helper functions shared across Tupic services.
validator
Package validator defines the Validator contract.
Package validator defines the Validator contract.
zap
test
stub/authenticationtest
Package authenticationtest provides a test-double authenticator that skips real IAM: it decodes the actor from the bearer token and resolves the user through a caller-supplied lookup, so the double carries no persistence dependency.
Package authenticationtest provides a test-double authenticator that skips real IAM: it decodes the actor from the bearer token and resolves the user through a caller-supplied lookup, so the double carries no persistence dependency.
stub/migratortest
Package migratortest provides recording test doubles for the migrator contract.
Package migratortest provides recording test doubles for the migrator contract.

Jump to

Keyboard shortcuts

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