Full Code of Aristat/golang-example-app for AI

master f7be6c387f0e cached
106 files
354.4 KB
132.3k tokens
527 symbols
1 requests
Download .txt
Showing preview only (384K chars total). Download the full file or copy to clipboard to get everything.
Repository: Aristat/golang-example-app
Branch: master
Commit: f7be6c387f0e
Files: 106
Total size: 354.4 KB

Directory structure:
gitextract_na8wnxnj/

├── .circleci/
│   └── config.yml
├── .gitignore
├── Makefile
├── README.md
├── app/
│   ├── auth/
│   │   ├── middleware.go
│   │   └── provider.go
│   ├── casbin/
│   │   └── provider.go
│   ├── common/
│   │   ├── bcrypt.go
│   │   ├── constants.go
│   │   ├── graphql.go
│   │   └── jaeger.go
│   ├── config/
│   │   ├── injector.go
│   │   ├── provider.go
│   │   └── wire_gen.go
│   ├── context/
│   │   └── context.go
│   ├── dataloader/
│   │   ├── dataloader.go
│   │   └── productitemloader_gen.go
│   ├── db/
│   │   ├── db.go
│   │   ├── domain/
│   │   │   ├── product.go
│   │   │   ├── product_item.go
│   │   │   └── user.go
│   │   ├── injector.go
│   │   ├── provider.go
│   │   ├── repo/
│   │   │   ├── provider.go
│   │   │   ├── users.go
│   │   │   └── users_test.go
│   │   └── wire_gen.go
│   ├── entrypoint/
│   │   ├── entrypoint.go
│   │   ├── entrypoint_test.go
│   │   └── provider.go
│   ├── graphql/
│   │   ├── graphql.go
│   │   └── provider.go
│   ├── graphql_resolver/
│   │   ├── injector.go
│   │   ├── mock.go
│   │   ├── product.go
│   │   ├── product_test.go
│   │   ├── provider.go
│   │   ├── resolver.go
│   │   ├── resolver_gen.go
│   │   ├── user.go
│   │   ├── user_test.go
│   │   └── wire_gen.go
│   ├── grpc/
│   │   ├── connection.go
│   │   ├── manager.go
│   │   ├── pool.go
│   │   └── provider.go
│   ├── http/
│   │   ├── http.go
│   │   ├── injector.go
│   │   ├── logger.go
│   │   ├── provider.go
│   │   └── wire_gen.go
│   ├── http_routers/
│   │   └── products-router/
│   │       ├── injector.go
│   │       ├── manager.go
│   │       ├── provider.go
│   │       ├── router.go
│   │       ├── router_test.go
│   │       └── wire_gen.go
│   ├── logger/
│   │   ├── injector.go
│   │   ├── logger.go
│   │   ├── middleware.go
│   │   ├── mock.go
│   │   ├── provider.go
│   │   ├── wire_gen.go
│   │   └── zap.go
│   ├── provider/
│   │   └── provider.go
│   └── tracing/
│       ├── jaeger.go
│       └── provider.go
├── cmd/
│   ├── daemon/
│   │   └── daemon.go
│   ├── health-check-service/
│   │   └── health_check_service.go
│   ├── jwt/
│   │   ├── jwt.go
│   │   └── token.go
│   ├── migrate/
│   │   └── migrate.go
│   ├── product-service/
│   │   ├── nats_service.go
│   │   └── product_service.go
│   └── root.go
├── dbconfig.yml
├── docker/
│   └── app/
│       ├── Dockerfile
│       └── files/
│           └── docker/
│               └── bin/
│                   └── entrypoint.sh
├── docker-compose.yml
├── generated/
│   ├── graphql/
│   │   ├── generated.go
│   │   └── models_gen.go
│   └── resources/
│       └── proto/
│           ├── health_checks/
│           │   ├── health_checks.pb.go
│           │   └── health_checks_grpc.pb.go
│           └── products/
│               ├── products.pb.go
│               └── products_grpc.pb.go
├── go.mod
├── go.sum
├── gqlgen.yml
├── main.go
├── prototool.yaml
├── resources/
│   ├── casbin/
│   │   ├── model.conf
│   │   └── policy.csv
│   ├── configs/
│   │   ├── development.yaml
│   │   └── docker_development.yaml
│   ├── graphql/
│   │   ├── products.graphql
│   │   ├── root.graphql
│   │   └── user.graphql
│   ├── keys/
│   │   └── local/
│   │       ├── private_key.pem
│   │       └── public_key.pem
│   ├── migrations/
│   │   ├── 20181215164636-create_users.sql
│   │   └── 20181216210607-records.sql
│   ├── proto/
│   │   ├── health_checks/
│   │   │   └── health_checks.proto
│   │   └── products/
│   │       └── products.proto
│   └── templates/
│       └── helpers/
│           └── errors.html
└── scripts/
    ├── docker-compose-start.sh
    └── remove_docker_containers.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .circleci/config.yml
================================================
version: 2.1
jobs:
  test:
    docker:
      - image: cimg/go:1.17
    working_directory: ~/golang-example-app
    steps:
      - checkout
      - run:
          name: "Setup APP_WD"
          command: echo 'export APP_WD="$(cd ${CIRCLE_WORKING_DIRECTORY}; pwd)/resources"' >> $BASH_ENV
      - run:
          name: Fetch dependencies
          command: go mod download
      - run:
          name: Test
          command: go test ./...
  build:
    docker:
      - image: cimg/go:1.17
    working_directory: ~/golang-example-app
    steps:
      - checkout
      - run:
          name: Fetch dependencies
          command: go mod download
      - run:
          name: Building
          command: |
            VERSION=${CIRCLE_TAG}
            GOOS=linux GOARCH=amd64 go build -ldflags "-X main.Version=${VERSION}" -o bin/app-${VERSION}-linux-amd64 main.go
            GOOS=darwin GOARCH=amd64 go build -ldflags "-X main.Version=${VERSION}" -o bin/app-${VERSION}-darwin-amd64 main.go
      - persist_to_workspace:
          root: .
          paths:
            - bin
  publish-github-release:
    docker:
      - image: cibuilds/github:0.13
    steps:
      - attach_workspace:
          at: ~/golang-example-app
      - run:
          name: "Publish Release on GitHub"
          command: |
            VERSION=${CIRCLE_TAG}
            ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -delete ${VERSION} ~/golang-example-app/bin
workflows:
  version: 2
  main:
    jobs:
      - test
  release:
    jobs:
      - build:
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /^v\d+\.\d+\.\d+.*/
      - publish-github-release:
          requires:
            - build
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /^v\d+\.\d+\.\d+.*/


================================================
FILE: .gitignore
================================================
# Binaries for programs and plugins
*.exe
*.dll
*.so
*.dylib

# Test binary, build with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
.glide/

vendor/

.idea/
artifacts/

coverage.out

.DS_Store


================================================
FILE: Makefile
================================================
GO_DIR ?= $(shell pwd)
GO_PKG ?= $(shell go list -e -f "{{ .ImportPath }}")

GOOS ?= $(shell go env GOOS || echo linux)
GOARCH ?= $(shell go env GOARCH || echo amd64)
CGO_ENABLED ?= 0

DOCKER_IMAGE ?= unknown
TAG ?= unknown
CACHE_TAG ?= unknown_cache

DATABASE_URL ?= golang_example_development

REMOVE_CONTAINERS ?= OFF

define build_resources
 	find "$(GO_DIR)/resources" -maxdepth 1 -mindepth 1 -exec cp -R -f {} $(GO_DIR)/artifacts/${1} \;
endef

install: init ## install cli tools
	go get -v github.com/rubenv/sql-migrate/... ;\
    go get -u github.com/google/wire/cmd/wire ;\
    go get -u github.com/vektah/dataloaden ;

init: ## init packages
	mkdir -p artifacts ;\
    rm -rf artifacts/*

start: ## start daemon on development mode
	./artifacts/bin daemon -c ./artifacts/configs/development.yaml -d

dependencies: ## generate dependencies
	go mod download

gqlgen-generate: ## generate graphql resolver
	go run github.com/99designs/gqlgen

prototool-generate: ## generate proto file
	protoc --go_out=generated --go_opt=paths=source_relative --go-grpc_out=generated --go-grpc_opt=paths=source_relative resources/proto/products/products.proto
	protoc --go_out=generated --go_opt=paths=source_relative --go-grpc_out=generated --go-grpc_opt=paths=source_relative resources/proto/health_checks/health_checks.proto

build: init ## build binary file
	$(call build_resources) ;\
	GOOS=${GOOS} CGO_ENABLED=${CGO_ENABLED} GOARCH=${GOARCH} \
	go build -ldflags "-X $(GO_PKG)/cmd/version.appVersion=$(TAG)-$$(date -u +%Y%m%d%H%M)" -o "$(GO_DIR)/artifacts/bin" main.go

docker-image: ## build docker image
	REMOVE_CONTAINERS=${REMOVE_CONTAINERS} DOCKER_IMAGE=${DOCKER_IMAGE} ./scripts/remove_docker_containers.sh
	docker rmi ${DOCKER_IMAGE}:${TAG} -f || true ;\
	docker build --cache-from ${DOCKER_IMAGE}:${CACHE_TAG} -f "${GO_DIR}/docker/app/Dockerfile" -t ${DOCKER_IMAGE}:${TAG} ${GO_DIR}

test: ## test application with race
	go test -v ./...

coverage: ## test coverage
	go test -coverprofile=coverage.out ./...
	go tool cover -html coverage.out

createdb: ## create database
	createdb $(DATABASE_URL)

dropdb: ## drop database
	dropdb $(DATABASE_URL)

.PHONY: install init dependencies gqlgen-generate prototool-generate

help:
	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

.DEFAULT_GOAL := help


================================================
FILE: README.md
================================================
![golang logo](golang_logo.png)

# Golang Example Application

# Table of Contents

- [Overview](#overview)
- [Package list](#package-list)
- [Installing](#installing)
  * [Local environment](#local-environment)
  * [Docker environment](#docker-enviroment)
- [Run services](#run-services)
  * [Start in local](#start-in-local-machine)
  * [Start in docker](#start-in-docker)
- [Getting started](#getting-started)  
  * [Jaeger](#jaeger)
  * [Http with gRPC](#http-example-with-grpc)
  * [Graphql with gRPC](#graphql-example-with-grpc)
- [Deprecate version](#deprecated-version)  
- [Testing](#testing)

# Overview

This is an example golang application.
Commands list:
1. Daemon - main service
2. Product service - service that returns Product, an example of gRPC client/server interaction
3. Health check service - this service is needed to show how convenient to understand on which of the services an error occurred in jaeger
4. Migrate - commands for migration
5. JWT - commands for generate JWT token

# Package list

Packages which use in this example project

1. [sql-migrate](https://github.com/rubenv/sql-migrate) - SQL migrations
2. [wire](https://github.com/google/wire) - dependency Injection
3. [viper](https://github.com/spf13/viper) - environment configuration
4. [cobra](https://github.com/spf13/cobra) - create commands
5. [cast](https://github.com/spf13/cast) - easy casting from one type to another
6. [gorm](https://github.com/jinzhu/gorm) - database ORM
7. [zap](https://github.com/uber-go/zap) - logger
8. [mux](https://github.com/gorilla/mux) - http router
9. [nats-streaming](https://github.com/nats-io/stan.go) - NATS Streaming System
10. [gqlgen](https://github.com/99designs/gqlgen) - graphql server library
11. [protobuf](https://pkg.go.dev/google.golang.org/protobuf) - Google's data interchange format
12. [grpc](google.golang.org/grpc) - RPC framework
13. [opentelemetry](https://github.com/open-telemetry/opentelemetry-go) - OpenTelemetry
14. [jaeger](https://github.com/uber/jaeger-client-go) - Jaeger Bindings for Go OpenTelemetry API
15. [casbin](https://github.com/casbin/casbin) - Supports access control
16. [dataloaden](https://github.com/vektah/dataloaden) - DataLoader for graphql
17. [nats](https://github.com/nats-io/nats.go) - Golang client for NATS, the cloud native messaging system

# Installing

Install the Golang and GO environment

```$xslt
https://golang.org/doc/install
```

Install [Postgresql](https://www.postgresql.org/download) (if you want to run locally)

Clone repository

```$xslt
git clone git@github.com:Aristat/golang-example-app.git (go get)
```

## Local environment

Install Golang packages without modules

```$xslt
make install
```

Install database

```$xslt
make createdb
```

Sql migrations

```$xslt
sql-migrate up
```

Install Golang dependencies

```$xslt
make dependencies
```

Generate artifacts(binary files and configs)

```$xslt
make build
```

Packages for proto generator

```$xslt
https://grpc.io/docs/languages/go/quickstart/#prerequisites
```

Set APP_WD if you start to use html templates or path to ssh keys or run `make test`

```$xslt
export APP_WD=go_path to project_path/resources or project_path/artifacts
```

## Docker environment

Generate docker image

```$xslt
DOCKER_IMAGE=golang-example-app TAG=development make docker-image
```

# Run services

## Start in local machine

Up jaeger in docker-compose or disable Jaeger(and rebuild binary file) in `resources/configs/*.yaml`

```$xslt
docker-compose up jaeger
```

Start daemon (main service)

```$xslt
make start
```

or

```$xslt
./artifacts/bin daemon -c ./artifacts/configs/development.yaml -d
```

Start product service 

```$xslt
./artifacts/bin product-service -c ./artifacts/configs/development.yaml -d
```

Start health-check service

```$xslt
./artifacts/bin health-check -c ./artifacts/configs/development.yaml -d
```

## Start in docker

#### Run this commands
```$xslt
docker-compose rm # Remove previous containers
REMOVE_CONTAINERS=on DOCKER_IMAGE=golang-example-app TAG=development make docker-image # Generate new docker image
docker-compose up
```

#### or run script

```$xslt
./scripts/docker-compose-start.sh
```

# Getting Started

## Jaeger

```$xslt
http://localhost:16686
```

## Http example with gRPC

```$xslt
http://localhost:9096/products_grpc
```

## Http example with Nats Streaming

```$xslt
http://localhost:9096/products_nats
```

## Http example with graceful shutdown(long request, you can check the server shutdown)

```$xslt
http://localhost:9096/products_slowly
```

## Graphql example with gRPC

Graphql [client](https://github.com/prisma-labs/graphql-playground) for testing. End-point `http://localhost:9096/query`.

Generate JWT for Graphql authorization

```$xslt
./artifacts/bin jwt token --key='./artifacts/keys/local/private_key.pem' --fields='{"sub": "owner", "iss": "test-service"}'
```

Set JWT token in headers

```$xslt
{
  "Authorization": "bearer token"
}
```

Example query

```
query oneUser {
  users {
    one(email: "test@gmail.com") {
      email
      id
    }
  }
}
```

Example query with data loader

```
query allProducts {
  products {
    list {
      products {
        id
        productItems {
          id
          name
        }
      }
    }
  }
}
```

Example mutation

```
mutation createUser {
  users {
    createUser(email: "test1@gmail.com", password: "123456789") {
      id
      email
    }
  }
}
```

# Testing
```
➜  make test
```


================================================
FILE: app/auth/middleware.go
================================================
package auth

import (
	"io/ioutil"
	"net/http"
	"strings"

	"github.com/aristat/golang-example-app/app/common"

	"github.com/aristat/golang-example-app/app/logger"

	"github.com/aristat/golang-example-app/app/entrypoint"

	"github.com/golang-jwt/jwt"

	appContext "github.com/aristat/golang-example-app/app/context"
	"github.com/pkg/errors"
)

const prefix = "app.auth"
const defaultSubject = "anonymous"
const defaultServiceName = "unknown"
const defaultServiceId = 0

var errPublicNotFound = errors.New("public key not found for issuer")
var errAuthJWT = errors.New("Authentication failed, JWT invalid")

// CustomClaims
type CustomClaims struct {
	jwt.StandardClaims
}

// Config
type Config struct {
	Services     map[string]uint64
	RelativePath string
}

// Middleware
type Middleware struct {
	keys keys
	cfg  Config
	log  logger.Logger
}

// keys
type keys struct {
	publicPemKey  []byte
	privatePemKey []byte
}

// Handler for check Bearer token
func (m Middleware) JWTHandler(next http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		var (
			token       string
			bearerToken = strings.Split(r.Header.Get("Authorization"), " ")
			subject     = defaultSubject
			claims      *CustomClaims
			ok          bool
		)

		if len(bearerToken) > 1 {
			token = bearerToken[1]
		} else {
			common.SendGraphqlErrorf(w, http.StatusUnauthorized, "Not found authorization token")
			return
		}

		t, err := jwt.ParseWithClaims(token, &CustomClaims{}, func(t *jwt.Token) (interface{}, error) {
			if _, ok := t.Claims.(*CustomClaims); ok {
				return jwt.ParseRSAPublicKeyFromPEM(m.keys.publicPemKey)
			}

			m.log.Error("Public key not found: %s", logger.Args(errPublicNotFound.Error()))
			return nil, errPublicNotFound
		})

		if err != nil {
			m.log.Error("Parse error: %s", logger.Args(err.Error()))
			common.SendGraphqlErrorf(w, http.StatusUnauthorized, err.Error())
			return
		}

		if t.Valid {
			if claims, ok = t.Claims.(*CustomClaims); ok {
				subject = claims.Subject
			}
		} else {
			m.log.Error("Validation Error: %s", logger.Args(errAuthJWT.Error()))
			common.SendGraphqlErrorf(w, http.StatusUnauthorized, errAuthJWT.Error())
			return
		}

		serviceName, serviceID := m.Service(claims)
		r = r.WithContext(appContext.NewContext(r.Context(), appContext.Mapping{
			Subject:     subject,
			ServiceId:   serviceID,
			ServiceName: serviceName,
		}))

		next.ServeHTTP(w, r)
	}
	return http.HandlerFunc(fn)
}

// Service returns service data as pair of name and id
func (m Middleware) Service(claims *CustomClaims) (string, uint64) {
	if claims == nil {
		return defaultServiceName, defaultServiceId
	}

	issuer := claims.Issuer

	if id, ok := m.cfg.Services[issuer]; ok {
		return claims.Issuer, id
	}
	return defaultServiceName, defaultServiceId
}

func NewMiddleware(cfg Config, log logger.Logger) (*Middleware, func(), error) {
	rPath := strings.Trim(cfg.RelativePath, "/")
	log = log.WithFields(logger.Fields{"service": prefix})
	m := &Middleware{cfg: cfg, log: log}

	publicKey, err := ioutil.ReadFile(entrypoint.WorkDir() + "/" + rPath + "/public_key.pem")
	if err != nil {
		return nil, func() {}, err
	}

	m.keys.publicPemKey = publicKey
	m.keys.privatePemKey, err = ioutil.ReadFile(entrypoint.WorkDir() + "/" + rPath + "/private_key.pem")
	if err != nil {
		return nil, func() {}, err
	}

	return m, func() {}, nil
}

func NewTestMiddleware(log logger.Logger) (*Middleware, func(), error) {
	log = log.WithFields(logger.Fields{"service": prefix})
	private := ``
	public := ``

	middleware := &Middleware{
		cfg: Config{},
		keys: keys{
			publicPemKey:  []byte(public),
			privatePemKey: []byte(private),
		},
		log: log,
	}

	return middleware, func() {}, nil
}


================================================
FILE: app/auth/provider.go
================================================
package auth

import (
	"github.com/aristat/golang-example-app/app/logger"
	"github.com/google/wire"
	"github.com/spf13/viper"
)

// ProviderCfg
func ProviderCfg(cfg *viper.Viper) (Config, func(), error) {
	c := Config{}
	e := cfg.UnmarshalKey("auth", &c)
	return c, func() {}, e
}

// Provider
func Provider(cfg Config, logger logger.Logger) (*Middleware, func(), error) {
	return NewMiddleware(cfg, logger)
}

// ProviderTest
func ProviderTest(logger logger.Logger) (*Middleware, func(), error) {
	return NewTestMiddleware(logger)
}

var (
	ProviderProductionSet = wire.NewSet(Provider, ProviderCfg)
	ProviderTestSet       = wire.NewSet(ProviderTest)
)


================================================
FILE: app/casbin/provider.go
================================================
package casbin

import (
	"github.com/aristat/golang-example-app/app/entrypoint"
	"github.com/casbin/casbin"
	fileadapter "github.com/casbin/casbin/persist/file-adapter"
	"github.com/google/wire"
)

func Provider() (*casbin.Enforcer, func(), error) {
	wd := entrypoint.WorkDir()
	enf := casbin.NewEnforcer(wd+"/casbin/model.conf", wd+"/casbin/policy.csv")
	return enf, func() {}, nil
}

func ProviderTest() (*casbin.Enforcer, func(), error) {

	model := `
[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
`
	policy := `
p, reader, users, read
p, owner, users, write

g, reader, anonymous
g, owner, reader
`
	enf := casbin.NewEnforcer(casbin.NewModel(model), fileadapter.NewAdapter(policy))
	return enf, func() {}, nil
}

var (
	ProviderProductionSet = wire.NewSet(Provider)
	ProviderTestSet       = wire.NewSet(ProviderTest)
)


================================================
FILE: app/common/bcrypt.go
================================================
package common

import "golang.org/x/crypto/bcrypt"

func HashPassword(password string, cost int) (string, error) {
	bytes, err := bcrypt.GenerateFromPassword([]byte(password), cost)
	return string(bytes), err
}

func CheckPasswordHash(password, hash string) bool {
	err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
	return err == nil
}


================================================
FILE: app/common/constants.go
================================================
package common

const (
	SrvProducts = "products"
)


================================================
FILE: app/common/graphql.go
================================================
package common

import (
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/vektah/gqlparser/v2/gqlerror"

	"github.com/99designs/gqlgen/graphql"
)

func SendGraphqlError(w http.ResponseWriter, code int, errors gqlerror.List) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(code)
	b, err := json.Marshal(&graphql.Response{Errors: errors})
	if err != nil {
		panic(err)
	}
	w.Write(b)
}

func SendGraphqlErrorf(w http.ResponseWriter, code int, format string, args ...interface{}) {
	SendGraphqlError(w, code, gqlerror.List{{Message: fmt.Sprintf(format, args...)}})
}


================================================
FILE: app/common/jaeger.go
================================================
package common

import (
	"github.com/aristat/golang-example-app/app/tracing"
	"go.opentelemetry.io/otel/exporters/jaeger"
	"go.opentelemetry.io/otel/sdk/resource"
	tracesdk "go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.4.0"

	"github.com/spf13/viper"
)

func GenerateTracerForTestClient(serviceName string, cfg *viper.Viper) (*tracesdk.TracerProvider, error) {
	configuration := tracing.Configuration{}
	err := cfg.UnmarshalKey("tracing.jaeger", &configuration)
	if err != nil {
		return nil, err
	}

	exp, err := jaeger.New(
		jaeger.WithAgentEndpoint(
			jaeger.WithAgentHost(configuration.AgentHost),
			jaeger.WithAgentPort(configuration.AgentPort),
		),
	)
	if err != nil {
		return nil, err
	}

	tp := tracesdk.NewTracerProvider(
		tracesdk.WithBatcher(exp),
		tracesdk.WithResource(resource.NewWithAttributes(
			semconv.SchemaURL,
			semconv.ServiceNameKey.String(serviceName),
		)),
	)
	return tp, nil
}


================================================
FILE: app/config/injector.go
================================================
// +build wireinject

package config

import (
	"github.com/google/wire"
	"github.com/spf13/viper"
)

// Build returns spf13/viper instance with resolved dependencies
func Build() (*viper.Viper, func(), error) {
	panic(wire.Build(Provider))
}


================================================
FILE: app/config/provider.go
================================================
package config

import (
	"github.com/aristat/golang-example-app/app/entrypoint"
	"github.com/google/wire"
	"github.com/spf13/viper"
)

// Provider returns spf13/viper instance with resolved dependencies
func Provider() (*viper.Viper, func(), error) {
	v := entrypoint.Viper()
	for _, key := range v.AllKeys() {
		val := v.Get(key)
		v.Set(key, val)
	}
	return v, func() {}, nil
}

var ProviderSet = wire.NewSet(Provider)


================================================
FILE: app/config/wire_gen.go
================================================
// Code generated by Wire. DO NOT EDIT.

//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject

package config

import (
	"github.com/spf13/viper"
)

// Injectors from injector.go:

// Build returns spf13/viper instance with resolved dependencies
func Build() (*viper.Viper, func(), error) {
	viperViper, cleanup, err := Provider()
	if err != nil {
		return nil, nil, err
	}
	return viperViper, func() {
		cleanup()
	}, nil
}


================================================
FILE: app/context/context.go
================================================
package context

import (
	"context"

	"github.com/mitchellh/mapstructure"
)

const prefix = "app.context"

// Manager
type Manager struct {
	mapping *Mapping
	ctx     context.Context
}

func (m *Manager) ToMapping() *Mapping {
	return &Mapping{
		Subject:     m.mapping.Subject,
		ServiceId:   m.mapping.ServiceId,
		ServiceName: m.mapping.ServiceName,
	}
}

// NewManager
func NewManager(ctx context.Context) (*Manager, error) {
	m := &Manager{ctx: ctx}
	mapping := &Mapping{}

	config := &mapstructure.DecoderConfig{TagName: "json", Result: &mapping}
	decoder, _ := mapstructure.NewDecoder(config)
	err := decoder.Decode(ctx.Value(prefix))
	if err != nil {
		return nil, err
	}

	m.mapping = mapping
	return m, nil
}

// Mapping
type Mapping struct {
	Subject     string
	ServiceId   uint64 `json:"service_id"`
	ServiceName string `json:"service_name"`
}

// NewContext
func NewContext(ctx context.Context, m Mapping) context.Context {
	return context.WithValue(ctx, prefix, map[string]interface{}{
		"subject":      m.Subject,
		"service_id":   m.ServiceId,
		"service_name": m.ServiceName,
	})
}


================================================
FILE: app/dataloader/dataloader.go
================================================
//go:generate go run github.com/vektah/dataloaden ProductItemLoader int []*github.com/aristat/golang-example-app/generated/domain.ProductItem

package dataloader

import (
	"context"
	"fmt"
	"math/rand"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/aristat/golang-example-app/app/db/domain"
)

type ctxKeyType struct{ name string }

var ctxKey = ctxKeyType{"userDataLoader"}

type loaders struct {
	ProductItemsByProduct *ProductItemLoader
}

func LoaderMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ldrs := loaders{}

		// set this to zero what happens without data loading
		wait := 250 * time.Microsecond

		ldrs.ProductItemsByProduct = &ProductItemLoader{
			wait:     wait,
			maxBatch: 100,
			fetch: func(keys []int) ([][]*domain.ProductItem, []error) {
				fmt.Println("ProductItems Start Fetch")
				var keySQL []string
				for _, key := range keys {
					keySQL = append(keySQL, strconv.Itoa(key))
				}

				fmt.Printf("SELECT * FROM product_items WHERE product_id IN (%s)\n", strings.Join(keySQL, ","))
				time.Sleep(5 * time.Millisecond)

				productItems := make([][]*domain.ProductItem, len(keys))
				errors := make([]error, len(keys))
				for i := range keys {
					productItems[i] = []*domain.ProductItem{
						{ID: 1, Name: "item " + strconv.Itoa(rand.Int()%20+20)},
						{ID: 2, Name: "item " + strconv.Itoa(rand.Int()%20+20)},
					}
				}

				return productItems, errors
			},
		}

		dlCtx := context.WithValue(r.Context(), ctxKey, ldrs)
		next.ServeHTTP(w, r.WithContext(dlCtx))
	})
}

func CtxLoaders(ctx context.Context) loaders {
	return ctx.Value(ctxKey).(loaders)
}


================================================
FILE: app/dataloader/productitemloader_gen.go
================================================
// Code generated by github.com/vektah/dataloaden, DO NOT EDIT.

package dataloader

import (
	"sync"
	"time"

	"github.com/aristat/golang-example-app/app/db/domain"
)

// ProductItemLoaderConfig captures the config to create a new ProductItemLoader
type ProductItemLoaderConfig struct {
	// Fetch is a method that provides the data for the loader
	Fetch func(keys []int) ([][]*domain.ProductItem, []error)

	// Wait is how long wait before sending a batch
	Wait time.Duration

	// MaxBatch will limit the maximum number of keys to send in one batch, 0 = not limit
	MaxBatch int
}

// NewProductItemLoader creates a new ProductItemLoader given a fetch, wait, and maxBatch
func NewProductItemLoader(config ProductItemLoaderConfig) *ProductItemLoader {
	return &ProductItemLoader{
		fetch:    config.Fetch,
		wait:     config.Wait,
		maxBatch: config.MaxBatch,
	}
}

// ProductItemLoader batches and caches requests
type ProductItemLoader struct {
	// this method provides the data for the loader
	fetch func(keys []int) ([][]*domain.ProductItem, []error)

	// how long to done before sending a batch
	wait time.Duration

	// this will limit the maximum number of keys to send in one batch, 0 = no limit
	maxBatch int

	// INTERNAL

	// lazily created cache
	cache map[int][]*domain.ProductItem

	// the current batch. keys will continue to be collected until timeout is hit,
	// then everything will be sent to the fetch method and out to the listeners
	batch *productItemLoaderBatch

	// mutex to prevent races
	mu sync.Mutex
}

type productItemLoaderBatch struct {
	keys    []int
	data    [][]*domain.ProductItem
	error   []error
	closing bool
	done    chan struct{}
}

// Load a ProductItem by key, batching and caching will be applied automatically
func (l *ProductItemLoader) Load(key int) ([]*domain.ProductItem, error) {
	return l.LoadThunk(key)()
}

// LoadThunk returns a function that when called will block waiting for a ProductItem.
// This method should be used if you want one goroutine to make requests to many
// different data loaders without blocking until the thunk is called.
func (l *ProductItemLoader) LoadThunk(key int) func() ([]*domain.ProductItem, error) {
	l.mu.Lock()
	if it, ok := l.cache[key]; ok {
		l.mu.Unlock()
		return func() ([]*domain.ProductItem, error) {
			return it, nil
		}
	}
	if l.batch == nil {
		l.batch = &productItemLoaderBatch{done: make(chan struct{})}
	}
	batch := l.batch
	pos := batch.keyIndex(l, key)
	l.mu.Unlock()

	return func() ([]*domain.ProductItem, error) {
		<-batch.done

		var data []*domain.ProductItem
		if pos < len(batch.data) {
			data = batch.data[pos]
		}

		var err error
		// its convenient to be able to return a single error for everything
		if len(batch.error) == 1 {
			err = batch.error[0]
		} else if batch.error != nil {
			err = batch.error[pos]
		}

		if err == nil {
			l.mu.Lock()
			l.unsafeSet(key, data)
			l.mu.Unlock()
		}

		return data, err
	}
}

// LoadAll fetches many keys at once. It will be broken into appropriate sized
// sub batches depending on how the loader is configured
func (l *ProductItemLoader) LoadAll(keys []int) ([][]*domain.ProductItem, []error) {
	results := make([]func() ([]*domain.ProductItem, error), len(keys))

	for i, key := range keys {
		results[i] = l.LoadThunk(key)
	}

	productItems := make([][]*domain.ProductItem, len(keys))
	errors := make([]error, len(keys))
	for i, thunk := range results {
		productItems[i], errors[i] = thunk()
	}
	return productItems, errors
}

// LoadAllThunk returns a function that when called will block waiting for a ProductItems.
// This method should be used if you want one goroutine to make requests to many
// different data loaders without blocking until the thunk is called.
func (l *ProductItemLoader) LoadAllThunk(keys []int) func() ([][]*domain.ProductItem, []error) {
	results := make([]func() ([]*domain.ProductItem, error), len(keys))
	for i, key := range keys {
		results[i] = l.LoadThunk(key)
	}
	return func() ([][]*domain.ProductItem, []error) {
		productItems := make([][]*domain.ProductItem, len(keys))
		errors := make([]error, len(keys))
		for i, thunk := range results {
			productItems[i], errors[i] = thunk()
		}
		return productItems, errors
	}
}

// Prime the cache with the provided key and value. If the key already exists, no change is made
// and false is returned.
// (To forcefully prime the cache, clear the key first with loader.clear(key).prime(key, value).)
func (l *ProductItemLoader) Prime(key int, value []*domain.ProductItem) bool {
	l.mu.Lock()
	var found bool
	if _, found = l.cache[key]; !found {
		// make a copy when writing to the cache, its easy to pass a pointer in from a loop var
		// and end up with the whole cache pointing to the same value.
		cpy := make([]*domain.ProductItem, len(value))
		copy(cpy, value)
		l.unsafeSet(key, cpy)
	}
	l.mu.Unlock()
	return !found
}

// Clear the value at key from the cache, if it exists
func (l *ProductItemLoader) Clear(key int) {
	l.mu.Lock()
	delete(l.cache, key)
	l.mu.Unlock()
}

func (l *ProductItemLoader) unsafeSet(key int, value []*domain.ProductItem) {
	if l.cache == nil {
		l.cache = map[int][]*domain.ProductItem{}
	}
	l.cache[key] = value
}

// keyIndex will return the location of the key in the batch, if its not found
// it will add the key to the batch
func (b *productItemLoaderBatch) keyIndex(l *ProductItemLoader, key int) int {
	for i, existingKey := range b.keys {
		if key == existingKey {
			return i
		}
	}

	pos := len(b.keys)
	b.keys = append(b.keys, key)
	if pos == 0 {
		go b.startTimer(l)
	}

	if l.maxBatch != 0 && pos >= l.maxBatch-1 {
		if !b.closing {
			b.closing = true
			l.batch = nil
			go b.end(l)
		}
	}

	return pos
}

func (b *productItemLoaderBatch) startTimer(l *ProductItemLoader) {
	time.Sleep(l.wait)
	l.mu.Lock()

	// we must have hit a batch limit and are already finalizing this batch
	if b.closing {
		l.mu.Unlock()
		return
	}

	l.batch = nil
	l.mu.Unlock()

	b.end(l)
}

func (b *productItemLoaderBatch) end(l *ProductItemLoader) {
	b.data, b.error = l.fetch(b.keys)
	close(b.done)
}


================================================
FILE: app/db/db.go
================================================
package db

import (
	"context"
	"time"

	"github.com/jinzhu/gorm"

	"github.com/aristat/golang-example-app/app/logger"
	_ "github.com/lib/pq"
)

const prefix = "app.db"

// Config
type Config struct {
	URL             string
	MaxOpenConns    int
	MaxIdleConns    int
	ConnMaxLifetime time.Duration
	LogLevel        logger.Level
}

// Http
type Manager struct {
	ctx context.Context
	cfg Config
	log logger.Logger
	DB  *gorm.DB
}

// New
func New(ctx context.Context, log logger.Logger, cfg Config, db *gorm.DB) *Manager {
	return &Manager{
		ctx: ctx,
		cfg: cfg,
		log: log.WithFields(logger.Fields{"service": prefix}),
		DB:  db,
	}
}


================================================
FILE: app/db/domain/product.go
================================================
package domain

type Product struct {
	ID           int
	Name         string
	productItems []ProductItem
}


================================================
FILE: app/db/domain/product_item.go
================================================
package domain

type ProductItem struct {
	ID   int
	Name string
}


================================================
FILE: app/db/domain/user.go
================================================
package domain

type User struct {
	ID                int    `gorm:"column:id"`
	Email             string `gorm:"column:email"`
	EncryptedPassword string `gorm:"column:encrypted_password"`
}

// UsersRepo interface
type UsersRepo interface {
	CreateUser(email string, encryptPassword string) (*User, error)
	FindByEmail(email string) (*User, error)
}


================================================
FILE: app/db/injector.go
================================================
// +build wireinject

package db

import (
	"github.com/aristat/golang-example-app/app/provider"
	"github.com/google/wire"
)

func Build() (*Manager, func(), error) {
	panic(wire.Build(ProviderProductionSet, provider.AwareProductionSet))
}

func BuildTest() (*Manager, func(), error) {
	panic(wire.Build(ProviderTestSet, provider.AwareTestSet))
}


================================================
FILE: app/db/provider.go
================================================
package db

import (
	"context"
	"database/sql"

	"github.com/jinzhu/gorm"

	"github.com/aristat/golang-example-app/app/logger"

	"github.com/google/wire"
	mocket "github.com/selvatico/go-mocket"
	"github.com/spf13/viper"
)

// Cfg
func Cfg(cfg *viper.Viper) (Config, func(), error) {
	c := Config{LogLevel: logger.LevelDebug}
	e := cfg.UnmarshalKey("db", &c)
	if e != nil {
		return c, func() {}, e
	}
	return c, func() {}, nil
}

// CfgTest
func CfgTest() (Config, func(), error) {
	return Config{}, func() {}, nil
}

// ProviderGORM
func ProviderGORM(ctx context.Context, log logger.Logger, cfg Config) (*gorm.DB, func(), error) {
	log = log.WithFields(logger.Fields{"service": prefix})

	db, err := gorm.Open("postgres", cfg.URL)
	db.DB().SetMaxOpenConns(cfg.MaxOpenConns)
	db.DB().SetMaxIdleConns(cfg.MaxIdleConns)
	db.DB().SetConnMaxLifetime(cfg.ConnMaxLifetime)

	if cfg.LogLevel == logger.LevelDebug {
		db.LogMode(true)
	}

	cleanup := func() {
		if db != nil {
			_ = db.Close()
		}
		log.Info("Closed db connections")
	}

	return db, cleanup, err
}

// ProviderGORMTest for test, using go-mocket
func ProviderGORMTest() (*gorm.DB, func(), error) {
	var db *gorm.DB

	cleanup := func() {
		if db != nil {
			_ = db.Close()
		}
	}

	mocket.Catcher.Register()
	mocket.Catcher.Logging = true

	sqlDB, err := sql.Open(mocket.DriverName, "gorm")
	if err != nil {
		return db, cleanup, err
	}

	db, err = gorm.Open("postgres", sqlDB)

	return db, cleanup, err
}

// Provider
func Provider(ctx context.Context, log logger.Logger, cfg Config, db *gorm.DB) (*Manager, func(), error) {
	g := New(ctx, log, cfg, db)
	return g, func() {}, nil
}

var (
	ProviderProductionSet = wire.NewSet(Provider, ProviderGORM, Cfg)
	ProviderTestSet       = wire.NewSet(Provider, ProviderGORMTest, CfgTest)
)


================================================
FILE: app/db/repo/provider.go
================================================
package repo

import (
	"github.com/aristat/golang-example-app/app/db/domain"
	"github.com/google/wire"
)

// Repo for all records
type Repo struct {
	Users domain.UsersRepo
}

// Provider
func Provider(userDomain domain.UsersRepo) (*Repo, func(), error) {
	repo := &Repo{
		Users: userDomain,
	}

	return repo, func() {}, nil
}

var (
	ProviderProductionSet = wire.NewSet(Provider, NewUsersRepo)
	ProviderTestSet       = wire.NewSet(Provider, NewUsersRepo)
)


================================================
FILE: app/db/repo/users.go
================================================
package repo

import (
	"github.com/aristat/golang-example-app/app/db/domain"
	"github.com/jinzhu/gorm"
)

type UsersRepo struct {
	db *gorm.DB
}

func (u *UsersRepo) CreateUser(email string, encryptPassword string) (*domain.User, error) {
	user := &domain.User{Email: email, EncryptedPassword: encryptPassword}

	if err := u.db.Create(user).Error; err != nil {
		return nil, err
	}

	return user, nil
}

func (u *UsersRepo) FindByEmail(email string) (*domain.User, error) {
	user := &domain.User{}

	err := u.db.
		Table("users").
		Select("id, email, encrypted_password").
		Where("users.email = ?", email).
		Limit(1).
		Scan(&user).Error

	return user, err
}

func NewUsersRepo(db *gorm.DB) (domain.UsersRepo, func(), error) {
	a := &UsersRepo{db: db}
	return a, func() {}, nil
}


================================================
FILE: app/db/repo/users_test.go
================================================
package repo_test

import (
	"errors"
	"testing"

	"golang.org/x/crypto/bcrypt"

	"github.com/aristat/golang-example-app/app/db"
	"github.com/aristat/golang-example-app/app/db/domain"

	mocket "github.com/selvatico/go-mocket"

	"github.com/aristat/golang-example-app/app/db/repo"
	"github.com/stretchr/testify/assert"
)

var customInsertError = errors.New("sql: custom insert error")

func TestCreateUser(t *testing.T) {
	mocket.Catcher.Logging = true

	dbManager, _, e := db.BuildTest()
	assert.Nil(t, e, "DB manager error should be nil")

	userRepo, _, e := repo.NewUsersRepo(dbManager.DB)
	assert.Nil(t, e, "Repo error should be nil")

	defaultEmail := "test@gmail.com"
	defaultPassword := "123456789"
	primaryKey := 333

	mockCreateWithError := func() {
		mocket.Catcher.
			Reset().
			NewMock().
			WithQuery("INSERT  INTO \"users\" (\"email\",\"encrypted_password\") VALUES ($1,$2)").
			WithArgs(defaultEmail, defaultPassword).
			WithError(customInsertError)
	}
	mockCreate := func() {
		reply := []map[string]interface{}{{"id": primaryKey}}
		mocket.Catcher.
			Reset().
			NewMock().
			WithQuery("INSERT  INTO \"users\" (\"email\",\"encrypted_password\") VALUES ($1,$2)").
			WithArgs(defaultEmail, defaultPassword).
			WithReply(reply)
	}

	tests := []struct {
		name    string
		mock    func()
		asserts func(user *domain.User, err error)
	}{
		{
			name: "USER NOT CREATED",
			mock: mockCreateWithError,
			asserts: func(user *domain.User, err error) {
				assert.Nil(t, user, "user should be nil")
				assert.NotNil(t, err, "err should not be nil")
				assert.Equal(t, customInsertError.Error(), err.Error())
			},
		},
		{
			name: "USER CREATED",
			mock: mockCreate,
			asserts: func(user *domain.User, err error) {
				assert.Equal(t, primaryKey, user.ID)
				assert.Nil(t, err, "err should be nil")
			},
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			test.mock()

			user, err := userRepo.CreateUser(defaultEmail, defaultPassword)
			test.asserts(user, err)
		})
	}
}

func TestFindByEmail(t *testing.T) {
	mocket.Catcher.Logging = true

	dbManager, _, e := db.BuildTest()
	assert.Nil(t, e, "DB manager error should be nil")

	userRepo, _, e := repo.NewUsersRepo(dbManager.DB)
	assert.Nil(t, e, "Repo error should be nil")

	ePassword, e := bcrypt.GenerateFromPassword([]byte("12345"), 8)
	assert.Nil(t, e, "Password is correct")

	defaultEmail := "test@gmail.com"
	mockSelect := func() {
		reply := []map[string]interface{}{{"id": 1, "email": defaultEmail, "encrypted_password": ePassword}}
		mocket.Catcher.Reset().NewMock().WithQuery(`WHERE (users.email = $1) LIMIT 1`).WithArgs(defaultEmail).WithReply(reply)
	}

	tests := []struct {
		name    string
		mock    func()
		asserts func(user *domain.User, err error)
	}{
		{
			name: "USER IS EMPTY",
			mock: func() {},
			asserts: func(user *domain.User, err error) {
				assert.Equal(t, "", user.Email, "email should be equals")
				assert.NotNil(t, err, "err should not be nil")
				assert.Equal(t, err.Error(), "record not found", "error should be corrects")
			},
		},
		{
			name: "USER EXIST",
			mock: mockSelect,
			asserts: func(user *domain.User, err error) {
				assert.Equal(t, defaultEmail, user.Email, "email should be equals")
				assert.Nil(t, e, "err should be nil")
			},
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			mocket.Catcher.Reset()
			test.mock()

			user, err := userRepo.FindByEmail(defaultEmail)
			test.asserts(user, err)
		})
	}
}


================================================
FILE: app/db/wire_gen.go
================================================
// Code generated by Wire. DO NOT EDIT.

//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject

package db

import (
	"github.com/aristat/golang-example-app/app/config"
	"github.com/aristat/golang-example-app/app/entrypoint"
	"github.com/aristat/golang-example-app/app/logger"
)

import (
	_ "github.com/lib/pq"
)

// Injectors from injector.go:

func Build() (*Manager, func(), error) {
	context, cleanup, err := entrypoint.ContextProvider()
	if err != nil {
		return nil, nil, err
	}
	viper, cleanup2, err := config.Provider()
	if err != nil {
		cleanup()
		return nil, nil, err
	}
	loggerConfig, cleanup3, err := logger.ProviderCfg(viper)
	if err != nil {
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	zap, cleanup4, err := logger.Provider(context, loggerConfig)
	if err != nil {
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	dbConfig, cleanup5, err := Cfg(viper)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	db, cleanup6, err := ProviderGORM(context, zap, dbConfig)
	if err != nil {
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	manager, cleanup7, err := Provider(context, zap, dbConfig, db)
	if err != nil {
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	return manager, func() {
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
	}, nil
}

func BuildTest() (*Manager, func(), error) {
	context, cleanup, err := entrypoint.ContextProviderTest()
	if err != nil {
		return nil, nil, err
	}
	loggerConfig, cleanup2, err := logger.ProviderCfgTest()
	if err != nil {
		cleanup()
		return nil, nil, err
	}
	mock, cleanup3, err := logger.ProviderTest(context, loggerConfig)
	if err != nil {
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	dbConfig, cleanup4, err := CfgTest()
	if err != nil {
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	db, cleanup5, err := ProviderGORMTest()
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	manager, cleanup6, err := Provider(context, mock, dbConfig, db)
	if err != nil {
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	return manager, func() {
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
	}, nil
}


================================================
FILE: app/entrypoint/entrypoint.go
================================================
package entrypoint

import (
	"context"
	"os"
	"sync"

	"github.com/spf13/viper"
)

var (
	vi          *viper.Viper
	mu          sync.Mutex
	reloadCh    = make(chan struct{})
	shutdownCtx context.Context
	cancelFn    context.CancelFunc
	ep          *EntryPoint
	wd          string
)

const prefix = "app.entrypoint"

func init() {
	shutdownCtx, cancelFn = context.WithCancel(context.Background())
}

// Viper returns instance of Viper
func Viper() *viper.Viper {
	mu.Lock()
	defer mu.Unlock()
	if vi != nil {
		return vi
	}
	vi = viper.GetViper()
	return vi
}

// Initialize returns instance of entry point singleton manager, workDir uses to attach templates
func Initialize(workDir string, v *viper.Viper) (*EntryPoint, error) {
	mu.Lock()
	defer mu.Unlock()
	if ep != nil {
		return ep, nil
	}
	if len(workDir) > 0 {
		wd = workDir
	} else {
		wd, _ = os.Getwd()
	}
	vi, ep = v, &EntryPoint{}
	return ep, nil
}

// OnShutdown subscribe on shutdown event for gracefully exit via context.
func OnShutdown() context.Context {
	return shutdownCtx
}

// OnReload subscribe on reload event.
func OnReload() <-chan struct{} {
	return reloadCh
}

// EntryPoint manager of single point of application
type EntryPoint struct {
}

// Shutdown raise shutdown event.
func Shutdown(ctx context.Context, code int) {
	mu.Lock()
	defer mu.Unlock()
	cancelFn()
	if _, ok := ctx.Deadline(); ok {
		<-ctx.Done()
	}
}

// Reload raise reload event.
func (e *EntryPoint) Reload() {
	mu.Lock()
	defer mu.Unlock()
	ch := reloadCh
	reloadCh = make(chan struct{})
	close(ch)
}

// WorkDir returns current work directory
func WorkDir() string {
	return wd
}


================================================
FILE: app/entrypoint/entrypoint_test.go
================================================
package entrypoint_test

import (
	"os"
	"path/filepath"
	"testing"

	"github.com/aristat/golang-example-app/app/entrypoint"

	"github.com/stretchr/testify/assert"
)

func TestInitialize(t *testing.T) {
	wd, _ := filepath.Abs(os.Getenv("APP_WD"))
	entryPoint, err := entrypoint.Initialize(wd, nil)

	assert.Nil(t, err, "err should be nil")
	assert.NotNil(t, entryPoint, "entryPoint should not be nil")
}


================================================
FILE: app/entrypoint/provider.go
================================================
package entrypoint

import (
	"context"
	"os"
	"path/filepath"

	"github.com/google/wire"
)

// ContextProvider
func ContextProvider() (context.Context, func(), error) {
	c := OnShutdown()
	return c, func() {}, nil
}

// ContextProviderTest
func ContextProviderTest() (context.Context, func(), error) {
	// initializing
	wd, _ := filepath.Abs(os.Getenv("APP_WD"))
	_, err := Initialize(wd, nil)

	c := context.Background()
	return c, func() {}, err
}

var (
	ProviderProductionSet = wire.NewSet(ContextProvider)
	ProviderTestSet       = wire.NewSet(ContextProviderTest)
)


================================================
FILE: app/graphql/graphql.go
================================================
package graphql

import (
	"context"
	"errors"
	"net/http"
	"strings"
	"time"

	"github.com/99designs/gqlgen/graphql/handler"

	"github.com/99designs/gqlgen/graphql/handler/extension"
	"github.com/99designs/gqlgen/graphql/handler/lru"
	"github.com/99designs/gqlgen/graphql/handler/transport"

	gqlgen "github.com/99designs/gqlgen/graphql"
	"github.com/aristat/golang-example-app/app/logger"
	"github.com/aristat/golang-example-app/generated/graphql"
	"github.com/go-chi/chi/v5"
	"github.com/vektah/gqlparser/v2/gqlerror"
)

const (
	prefix = "app.graphql"
)

var errInternalServer = errors.New("internal server error")

// GraphQL
type GraphQL struct {
	ctx      context.Context
	resolver *graphql.Config
	log      logger.Logger
	cfg      Config
}

// Use
func (g *GraphQL) Use(router *chi.Mux) {
	router.Use(g.cfg.Middleware...)
}

// Routers
func (g *GraphQL) Routers(router chi.Router) {
	srv := handler.New(graphql.NewExecutableSchema(*g.resolver))

	srv.AddTransport(transport.Websocket{
		KeepAlivePingInterval: 10 * time.Second,
	})
	srv.AddTransport(transport.Options{})
	srv.AddTransport(transport.GET{})
	srv.AddTransport(transport.POST{})
	srv.AddTransport(transport.MultipartForm{})

	srv.SetQueryCache(lru.New(1000))

	if g.cfg.Introspection {
		srv.Use(extension.Introspection{})
	}
	srv.Use(extension.AutomaticPersistedQuery{
		Cache: lru.New(100),
	})

	srv.SetRecoverFunc(func(ctx context.Context, err interface{}) error {
		g.log.Alert("unhandled panic, err: %v", logger.Args(err))
		return nil
	})
	srv.SetErrorPresenter(func(ctx context.Context, e error) *gqlerror.Error {
		if e != nil {
			g.log.Alert("recover on middleware, err: %v", logger.Args(e))
			goto done
		}
		e = errInternalServer
	done:
		return gqlgen.DefaultErrorPresenter(ctx, e)
	})

	if g.cfg.Debug {
		srv.AroundResponses(func(ctx context.Context, next gqlgen.ResponseHandler) *gqlgen.Response {
			startTime := time.Now()
			rc := gqlgen.GetOperationContext(ctx)
			resp := next(ctx)
			g.log.Debug("\nVARS:\n%+v\nQUERY:\n%v\nRESPONSE:\n%v\nERROR:\n%v\n",
				logger.Args(rc.Variables, strings.TrimRight(rc.RawQuery, "\n"), string(resp.Data), resp.Errors),
				logger.WithFields(logger.Fields{
					"time": time.Since(startTime).String(),
				}),
			)
			return resp
		})
	}

	router.Handle("/query", srv)
}

// Config
type Config struct {
	Debug         bool
	Introspection bool
	Name          string
	Middleware    []func(http.Handler) http.Handler
}

// New
func New(ctx context.Context, resolver graphql.Config, log logger.Logger, cfg Config) *GraphQL {
	log = log.WithFields(logger.Fields{"service": prefix})
	return &GraphQL{
		ctx:      ctx,
		resolver: &resolver,
		cfg:      cfg,
		log:      log,
	}
}


================================================
FILE: app/graphql/provider.go
================================================
package graphql

import (
	"context"

	"github.com/aristat/golang-example-app/app/graphql_resolver"

	"github.com/aristat/golang-example-app/app/logger"
	"github.com/aristat/golang-example-app/generated/graphql"
	"github.com/google/wire"
	"github.com/spf13/viper"
)

// Cfg
func Cfg(cfg *viper.Viper) (Config, func(), error) {
	c := Config{}
	e := cfg.UnmarshalKey("graphql", &c)
	if e != nil {
		return c, func() {}, e
	}
	if cfg.IsSet("debug") && !c.Debug {
		c.Debug = cfg.GetBool("debug")
	}
	return c, func() {}, nil
}

// CfgTest
func CfgTest() (Config, func(), error) {
	return Config{}, func() {}, nil
}

// Provider
func Provider(ctx context.Context, resolver graphql.Config, log logger.Logger, cfg Config) (*GraphQL, func(), error) {
	g := New(ctx, resolver, log, cfg)
	return g, func() {}, nil
}

var (
	ProviderProductionSet = wire.NewSet(Provider, Cfg, graphql_resolver.ProviderProductionSet)
	ProviderTestSet       = wire.NewSet(Provider, CfgTest, graphql_resolver.ProviderTestSet)
)


================================================
FILE: app/graphql_resolver/injector.go
================================================
// +build wireinject

package graphql_resolver

import (
	"github.com/aristat/golang-example-app/app/db"
	"github.com/aristat/golang-example-app/app/db/repo"
	"github.com/aristat/golang-example-app/app/provider"
	"github.com/aristat/golang-example-app/generated/graphql"
	"github.com/google/wire"
)

// Build
func Build() (graphql.Config, func(), error) {
	panic(wire.Build(ProviderProductionSet, repo.ProviderProductionSet, db.ProviderProductionSet, provider.AwareProductionSet))
}

func BuildTest() (graphql.Config, func(), error) {
	panic(wire.Build(ProviderTestSet, repo.ProviderTestSet, db.ProviderTestSet, provider.AwareTestSet))
}


================================================
FILE: app/graphql_resolver/mock.go
================================================
package graphql_resolver

import (
	"context"
	"fmt"

	"github.com/aristat/golang-example-app/generated/resources/proto/products"
)

type ProductServerMock struct {
	products.UnimplementedProductsServer
}

func (s *ProductServerMock) ListProduct(ctx context.Context, in *products.ListProductIn) (*products.ListProductOut, error) {
	productIds := []int64{1, 2, 3, 4, 5}
	out := &products.ListProductOut{Status: products.ListProductOut_OK, Products: []*products.Product{}}

	for _, id := range productIds {
		out.Products = append(out.Products, &products.Product{Id: id, Name: fmt.Sprintf("product_%d", id)})
	}

	return out, nil
}


================================================
FILE: app/graphql_resolver/product.go
================================================
package graphql_resolver

import (
	"context"
	"time"

	"github.com/aristat/golang-example-app/app/dataloader"

	"github.com/aristat/golang-example-app/app/db/domain"

	"github.com/aristat/golang-example-app/app/common"
	"github.com/aristat/golang-example-app/app/grpc"
	"github.com/aristat/golang-example-app/generated/graphql"
	"github.com/aristat/golang-example-app/generated/resources/proto/products"
	"github.com/spf13/cast"
)

type productsQueryResolver struct{ *Resolver }
type productResolver struct{ *Resolver }

func (r *Resolver) ProductsQuery() graphql.ProductsQueryResolver {
	return &productsQueryResolver{r}
}

// QUERY

func (r *queryResolver) Products(ctx context.Context) (*graphql.ProductsQuery, error) {
	return &graphql.ProductsQuery{}, nil
}

func (r *productsQueryResolver) List(ctx context.Context, obj *graphql.ProductsQuery) (*graphql.ProductsListOut, error) {
	conn, d, err := grpc.GetConnGRPC(r.pollManager, common.SrvProducts)
	defer d()

	if err != nil {
		return nil, err
	}

	c := products.NewProductsClient(conn)

	ctx, cancel := context.WithTimeout(ctx, time.Second*time.Duration(r.cfg.ProductTimeout))
	defer cancel()

	productOut, err := c.ListProduct(ctx, &products.ListProductIn{Id: 1})
	if err != nil {
		return nil, err
	}

	list := make([]*domain.Product, len(productOut.Products))
	for i, product := range productOut.Products {
		list[i] = &domain.Product{
			ID:   cast.ToInt(&product.Id),
			Name: product.Name,
		}
	}

	return &graphql.ProductsListOut{Products: list}, nil
}

func (r *queryResolver) ProductsRoot(ctx context.Context) ([]*domain.Product, error) {
	return []*domain.Product{{ID: 1, Name: "test1"}, {ID: 2, Name: "test2"}}, nil
}

func (r *Resolver) Product() graphql.ProductResolver {
	return &productResolver{r}
}

func (r *productResolver) ProductItems(ctx context.Context, obj *domain.Product) ([]*domain.ProductItem, error) {
	r.log.Info("ProductItems Start Request")
	return dataloader.CtxLoaders(ctx).ProductItemsByProduct.Load(obj.ID)
}


================================================
FILE: app/graphql_resolver/product_test.go
================================================
package graphql_resolver_test

import (
	"context"
	"encoding/json"
	"log"
	"net"
	"os"
	"strconv"
	"testing"

	"github.com/aristat/golang-example-app/app/common"

	"github.com/aristat/golang-example-app/generated/resources/proto/products"

	"google.golang.org/grpc"

	"github.com/stretchr/testify/assert"

	"github.com/aristat/golang-example-app/app/graphql_resolver"
	grpc1 "github.com/aristat/golang-example-app/app/grpc"
	graphql1 "github.com/aristat/golang-example-app/generated/graphql"
)

var (
	productServerHost = "localhost"
	grpcPort          string
)

func TestMain(m *testing.M) {
	lis, err := net.Listen("tcp", ":0")
	if err != nil {
		log.Fatalf(err.Error())
	}
	defer lis.Close()

	grpcPort = ":" + strconv.Itoa(lis.Addr().(*net.TCPAddr).Port)
	s := grpc.NewServer()
	products.RegisterProductsServer(s, &graphql_resolver.ProductServerMock{})

	go func() {
		if err := s.Serve(lis); err != nil {
			log.Fatalf("Server exited with error: %v", err)
		}
	}()

	code := m.Run()

	os.Exit(code)
}

func TestList(t *testing.T) {
	var opts []grpc.DialOption
	ctx := context.Background()
	opts = append(opts, grpc.WithInsecure())

	pool, _ := grpc1.NewPool(ctx, common.SrvProducts, productServerHost+grpcPort, grpc1.ConnOptions(opts...))
	grpc1.SetPool(pool, common.SrvProducts)

	cfg, _, err := graphql_resolver.BuildTest()
	if err != nil {
		assert.Failf(t, "graphql_resolver instance failed, err: %v", err.Error())
		return
	}

	obj := graphql1.ProductsQuery{}

	out, err := cfg.Resolvers.ProductsQuery().List(ctx, &obj)
	if err != nil {
		assert.Failf(t, "request failed, err: %v", err.Error())
		return
	}

	jsonProducts, _ := json.Marshal(out.Products)
	t.Log(string(jsonProducts))
	assert.Equal(t, len(out.Products), 5)
}


================================================
FILE: app/graphql_resolver/provider.go
================================================
package graphql_resolver

import (
	"context"

	"github.com/casbin/casbin"

	"github.com/aristat/golang-example-app/app/logger"
	"github.com/aristat/golang-example-app/generated/graphql"
	"github.com/google/wire"
	"github.com/spf13/viper"
)

// Cfg
func Cfg(cfg *viper.Viper) (Config, func(), error) {
	c := Config{}
	e := cfg.UnmarshalKey("graphql_resolver", &c)
	return c, func() {}, e
}

// CfgTest
func CfgTest() (Config, func(), error) {
	return Config{ProductTimeout: 5}, func() {}, nil
}

var ProviderManagers = wire.NewSet(
	wire.Struct(new(Managers), "*"),
)

// Provider
func Provider(ctx context.Context, log logger.Logger, cfg Config, enforcer *casbin.Enforcer, managers Managers) (graphql.Config, func(), error) {
	c := New(ctx, log, cfg, enforcer, managers)
	return c, func() {}, nil
}

var (
	ProviderProductionSet = wire.NewSet(Provider, Cfg, ProviderManagers)
	ProviderTestSet       = wire.NewSet(Provider, CfgTest, ProviderManagers)
)


================================================
FILE: app/graphql_resolver/resolver.go
================================================
package graphql_resolver

import (
	"context"
	"strings"

	"github.com/pkg/errors"

	"github.com/99designs/gqlgen/graphql"
	"github.com/casbin/casbin"

	"github.com/aristat/golang-example-app/app/grpc"

	"github.com/aristat/golang-example-app/app/db/repo"

	appContext "github.com/aristat/golang-example-app/app/context"
	"github.com/aristat/golang-example-app/app/logger"
	graphql1 "github.com/aristat/golang-example-app/generated/graphql"
)

var prefix = "app.graphql_resolver"
var errPermission = errors.WithMessage(errors.New("No have permission"), prefix)

// Config
type Config struct {
	ProductTimeout int
}

// Managers
type Managers struct {
	Repo        *repo.Repo
	PollManager *grpc.PoolManager
}

type queryResolver struct{ *Resolver }
type mutationResolver struct{ *Resolver }

// Resolver config graphql resolvers
type Resolver struct {
	ctx         context.Context
	log         logger.Logger
	cfg         Config
	repo        *repo.Repo
	pollManager *grpc.PoolManager
}

// Mutation returns root graphql mutation graphql_resolver
func (r *Resolver) Mutation() graphql1.MutationResolver {
	return &mutationResolver{r}
}

// Query returns root graphql query graphql_resolver
func (r *Resolver) Query() graphql1.QueryResolver {
	return &queryResolver{r}
}

// New
func New(ctx context.Context, log logger.Logger, cfg Config, enforcer *casbin.Enforcer, managers Managers) graphql1.Config {
	log = log.WithFields(logger.Fields{"service": prefix})
	c := graphql1.Config{
		Resolvers: &Resolver{
			ctx:         ctx,
			log:         log,
			cfg:         cfg,
			repo:        managers.Repo,
			pollManager: managers.PollManager,
		},
	}

	c.Directives.HasUsersPermission = func(ctx context.Context, obj interface{}, next graphql.Resolver, role graphql1.UsersPermissionEnum) (res interface{}, err error) {
		m, err := appContext.NewManager(ctx)
		if err != nil {
			return nil, err
		}

		mapping := m.ToMapping()
		if !enforcer.Enforce(mapping.Subject, "users", strings.ToLower(string(role))) {
			return nil, errPermission
		}

		return next(ctx)
	}

	return c
}


================================================
FILE: app/graphql_resolver/resolver_gen.go
================================================
package graphql_resolver


================================================
FILE: app/graphql_resolver/user.go
================================================
package graphql_resolver

import (
	"context"

	"github.com/aristat/golang-example-app/app/common"

	graphql1 "github.com/aristat/golang-example-app/generated/graphql"
	"github.com/spf13/cast"
)

type usersQueryResolver struct{ *Resolver }
type usersMutationResolver struct{ *Resolver }

func (r *Resolver) UsersMutation() graphql1.UsersMutationResolver {
	return &usersMutationResolver{r}
}
func (r *Resolver) UsersQuery() graphql1.UsersQueryResolver {
	return &usersQueryResolver{r}
}

// QUERY

func (r *queryResolver) Users(ctx context.Context) (*graphql1.UsersQuery, error) {
	return &graphql1.UsersQuery{}, nil
}

func (r *usersQueryResolver) One(ctx context.Context, obj *graphql1.UsersQuery, email string) (*graphql1.UsersOneOut, error) {
	user, err := r.repo.Users.FindByEmail(email)

	if err != nil {
		return nil, err
	}

	userData := &graphql1.UsersOneOut{
		ID:    cast.ToString(&user.ID),
		Email: user.Email,
	}

	return userData, nil
}

// MUTATIONS

func (r *mutationResolver) Users(ctx context.Context) (*graphql1.UsersMutation, error) {
	return &graphql1.UsersMutation{}, nil
}

func (r *usersMutationResolver) CreateUser(ctx context.Context, obj *graphql1.UsersMutation, email string, password string) (*graphql1.UsersCreateOut, error) {
	encryptPassword, err := common.HashPassword(password, 8)
	if err != nil {
		return nil, err
	}

	user, err := r.repo.Users.CreateUser(email, encryptPassword)

	if err != nil {
		return nil, err
	}

	userData := &graphql1.UsersCreateOut{
		ID:     cast.ToString(user.ID),
		Email:  user.Email,
		Status: graphql1.UsersCreateOutStatusOk,
	}

	return userData, nil
}


================================================
FILE: app/graphql_resolver/user_test.go
================================================
package graphql_resolver_test

import (
	"context"
	"testing"

	"github.com/spf13/cast"

	"golang.org/x/crypto/bcrypt"

	"github.com/stretchr/testify/assert"

	"github.com/aristat/golang-example-app/app/graphql_resolver"
	graphql1 "github.com/aristat/golang-example-app/generated/graphql"
	mocket "github.com/selvatico/go-mocket"
)

type UserParams struct {
	testName string
	id       int
	email    string
}

func TestOne(t *testing.T) {
	ctx := context.Background()

	cfg, _, err := graphql_resolver.BuildTest()
	if err != nil {
		assert.Failf(t, "graphql_resolver instance failed, err: %v", err.Error())
		return
	}

	ePassword, e := bcrypt.GenerateFromPassword([]byte("12345"), 8)
	assert.Nil(t, e, "Password is correct")

	obj := graphql1.UsersQuery{}
	defaultEmail := "test@gmail.com"
	id := 1
	mockDefaultResult := func() {
		reply := []map[string]interface{}{{"id": id, "email": defaultEmail, "encrypted_password": ePassword}}
		mocket.Catcher.Reset().NewMock().WithQuery(`WHERE (users.email = $1) LIMIT 1`).WithArgs(defaultEmail).WithReply(reply)
	}

	tests := []struct {
		userParams UserParams
		mock       func()
		asserts    func(userParams UserParams, out *graphql1.UsersOneOut, err error)
	}{
		{
			userParams: UserParams{id: 2, email: "test1@gmail.com", testName: "USER NOT EXIST"},
			mock:       mockDefaultResult,
			asserts: func(userParams UserParams, out *graphql1.UsersOneOut, err error) {
				assert.NotNil(t, err, "err should not be nil")
				assert.Nil(t, out, "out should be nil")
			},
		},
		{
			userParams: UserParams{id: id, email: defaultEmail, testName: "USER EXIST"},
			mock:       mockDefaultResult,
			asserts: func(userParams UserParams, out *graphql1.UsersOneOut, err error) {
				assert.Nil(t, err, "err should be nil")
				assert.Equal(t, cast.ToString(userParams.id), out.ID, "id should be equals")
				assert.Equal(t, userParams.email, out.Email, "email should be equals")
			},
		},
	}

	for _, test := range tests {
		t.Run(test.userParams.testName, func(t *testing.T) {
			mocket.Catcher.Reset()
			test.mock()

			out, err := cfg.Resolvers.UsersQuery().One(ctx, &obj, test.userParams.email)
			test.asserts(test.userParams, out, err)
		})
	}
}


================================================
FILE: app/graphql_resolver/wire_gen.go
================================================
// Code generated by Wire. DO NOT EDIT.

//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject

package graphql_resolver

import (
	"github.com/aristat/golang-example-app/app/casbin"
	"github.com/aristat/golang-example-app/app/config"
	"github.com/aristat/golang-example-app/app/db"
	"github.com/aristat/golang-example-app/app/db/repo"
	"github.com/aristat/golang-example-app/app/entrypoint"
	"github.com/aristat/golang-example-app/app/grpc"
	"github.com/aristat/golang-example-app/app/logger"
	"github.com/aristat/golang-example-app/app/tracing"
	"github.com/aristat/golang-example-app/generated/graphql"
)

// Injectors from injector.go:

// Build
func Build() (graphql.Config, func(), error) {
	context, cleanup, err := entrypoint.ContextProvider()
	if err != nil {
		return graphql.Config{}, nil, err
	}
	viper, cleanup2, err := config.Provider()
	if err != nil {
		cleanup()
		return graphql.Config{}, nil, err
	}
	loggerConfig, cleanup3, err := logger.ProviderCfg(viper)
	if err != nil {
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	zap, cleanup4, err := logger.Provider(context, loggerConfig)
	if err != nil {
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	graphql_resolverConfig, cleanup5, err := Cfg(viper)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	enforcer, cleanup6, err := casbin.Provider()
	if err != nil {
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	dbConfig, cleanup7, err := db.Cfg(viper)
	if err != nil {
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	gormDB, cleanup8, err := db.ProviderGORM(context, zap, dbConfig)
	if err != nil {
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	usersRepo, cleanup9, err := repo.NewUsersRepo(gormDB)
	if err != nil {
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	repoRepo, cleanup10, err := repo.Provider(usersRepo)
	if err != nil {
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	configuration, cleanup11, err := tracing.Cfg(viper)
	if err != nil {
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	tracerProvider, cleanup12, err := tracing.Provider(context, configuration, zap)
	if err != nil {
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	grpcConfig, cleanup13, err := grpc.Cfg(viper)
	if err != nil {
		cleanup12()
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	poolManager, cleanup14, err := grpc.Provider(context, tracerProvider, zap, grpcConfig)
	if err != nil {
		cleanup13()
		cleanup12()
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	managers := Managers{
		Repo:        repoRepo,
		PollManager: poolManager,
	}
	graphqlConfig, cleanup15, err := Provider(context, zap, graphql_resolverConfig, enforcer, managers)
	if err != nil {
		cleanup14()
		cleanup13()
		cleanup12()
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	return graphqlConfig, func() {
		cleanup15()
		cleanup14()
		cleanup13()
		cleanup12()
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
	}, nil
}

func BuildTest() (graphql.Config, func(), error) {
	context, cleanup, err := entrypoint.ContextProviderTest()
	if err != nil {
		return graphql.Config{}, nil, err
	}
	loggerConfig, cleanup2, err := logger.ProviderCfgTest()
	if err != nil {
		cleanup()
		return graphql.Config{}, nil, err
	}
	mock, cleanup3, err := logger.ProviderTest(context, loggerConfig)
	if err != nil {
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	graphql_resolverConfig, cleanup4, err := CfgTest()
	if err != nil {
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	enforcer, cleanup5, err := casbin.ProviderTest()
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	gormDB, cleanup6, err := db.ProviderGORMTest()
	if err != nil {
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	usersRepo, cleanup7, err := repo.NewUsersRepo(gormDB)
	if err != nil {
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	repoRepo, cleanup8, err := repo.Provider(usersRepo)
	if err != nil {
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	tracerProvider, cleanup9, err := tracing.ProviderTest()
	if err != nil {
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	grpcConfig, cleanup10, err := grpc.CfgTest()
	if err != nil {
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	poolManager, cleanup11, err := grpc.Provider(context, tracerProvider, mock, grpcConfig)
	if err != nil {
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	managers := Managers{
		Repo:        repoRepo,
		PollManager: poolManager,
	}
	graphqlConfig, cleanup12, err := Provider(context, mock, graphql_resolverConfig, enforcer, managers)
	if err != nil {
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return graphql.Config{}, nil, err
	}
	return graphqlConfig, func() {
		cleanup12()
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
	}, nil
}


================================================
FILE: app/grpc/connection.go
================================================
package grpc

import (
	"sync"

	"google.golang.org/grpc"
)

var (
	srvMu   sync.Mutex
	poolSrv = map[string]*Pool{}
)

// Set pool connections
func SetPool(p *Pool, srv string) {
	if _, ok := poolSrv[srv]; !ok {
		srvMu.Lock()
		defer srvMu.Unlock()
		poolSrv[srv] = p
	}
}

// Get client connection
func GetConnGRPC(poolManager *PoolManager, srv string) (*grpc.ClientConn, Done, error) {
	if _, ok := poolSrv[srv]; !ok {
		srvMu.Lock()
		defer srvMu.Unlock()
		if _, ok := poolSrv[srv]; !ok {
			p, _, e := poolManager.NewPool(srv)
			if e != nil {
				return nil, func() {}, e
			}
			poolSrv[srv] = p
		}
	}
	return poolSrv[srv].Get()
}


================================================
FILE: app/grpc/manager.go
================================================
package grpc

import (
	"context"
	"errors"

	"go.opentelemetry.io/otel/propagation"

	"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
	tracesdk "go.opentelemetry.io/otel/sdk/trace"

	"google.golang.org/grpc/credentials/insecure"

	"github.com/aristat/golang-example-app/app/logger"
	"google.golang.org/grpc"
	"google.golang.org/grpc/keepalive"
)

const prefix = "app.grpc"

var errCfgInvalid = errors.New("cfg is not present or invalid")

// PoolManager
type PoolManager struct {
	ctx     context.Context
	tracing *tracesdk.TracerProvider
	cfg     *Config
	logger  logger.Logger
}

// New
func (p *PoolManager) NewPool(service string) (_ *Pool, loaded bool, _ error) {
	s, ok := p.cfg.Services[service]

	if !ok {
		return nil, false, errCfgInvalid
	}

	var opts []grpc.DialOption
	opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))

	cl := s.ClientParameters
	if cl == nil {
		if p.cfg.ClientParameters != nil {
			cl = p.cfg.ClientParameters
		} else {
			cl = &keepalive.ClientParameters{}
		}
	}

	opts = append(opts, grpc.WithKeepaliveParams(*cl))
	opts = append(opts,
		grpc.WithChainUnaryInterceptor(
			logger.UnaryClientInterceptor(p.logger, true),
			otelgrpc.UnaryClientInterceptor(otelgrpc.WithTracerProvider(p.tracing), otelgrpc.WithPropagators(propagation.TraceContext{})),
		),
	)
	opts = append(opts,
		grpc.WithChainStreamInterceptor(
			logger.StreamClientInterceptor(p.logger, true),
			otelgrpc.StreamClientInterceptor(otelgrpc.WithTracerProvider(p.tracing), otelgrpc.WithPropagators(propagation.TraceContext{})),
		),
	)

	pool, l := NewPool(p.ctx, service, s.Target,
		MaxConn(s.MaxConn),
		InitConn(s.InitConn),
		MaxLifeDuration(s.MaxLifeDuration),
		IdleTimeout(s.IdleTimeout),
		ConnOptions(opts...),
	)

	return pool, l, nil
}

// NewPoolManager
func NewPoolManager(ctx context.Context, tracing *tracesdk.TracerProvider, logger logger.Logger, cfg *Config) *PoolManager {
	return &PoolManager{ctx: ctx, tracing: tracing, cfg: cfg, logger: logger}
}


================================================
FILE: app/grpc/pool.go
================================================
package grpc

import (
	"context"
	"sync"
	"time"

	"github.com/pkg/errors"
	grpcpool "github.com/processout/grpc-go-pool"
	"google.golang.org/grpc"
)

var (
	poolList map[string]*Pool
	mu       sync.Mutex
)

// Done
type Done func()

type conn struct {
	conn *grpc.ClientConn
	pool *Pool
	err  error
}

func (c *conn) init() {
	c.conn, c.err = grpc.Dial(c.pool.target, c.pool.opts.dialOptions...)
}

// Pool
type Pool struct {
	id      string
	ctx     context.Context
	service string
	pool    *grpcpool.Pool
	target  string
	opts    *opts
}

// Get
func (p *Pool) Get() (*grpc.ClientConn, Done, error) {
	c, e := p.pool.Get(p.ctx)
	return c.ClientConn, func() {
		_ = c.Close()
	}, errors.WithMessage(e, prefix)
}

type opts struct {
	dialOptions     []grpc.DialOption
	initConn        int
	maxConn         int
	idleTimeout     time.Duration
	maxLifeDuration time.Duration
}

// Option
type Option func(*opts) error

// ConnOptions
func ConnOptions(o ...grpc.DialOption) Option {
	return func(f *opts) error {
		f.dialOptions = o
		return nil
	}
}

// MaxConn
func MaxConn(value int) Option {
	return func(f *opts) error {
		f.maxConn = value
		return nil
	}
}

// InitConn
func InitConn(value int) Option {
	return func(f *opts) error {
		f.initConn = value
		return nil
	}
}

// MaxLifeDuration
func MaxLifeDuration(value time.Duration) Option {
	return func(f *opts) error {
		f.maxLifeDuration = value
		return nil
	}
}

// IdleTimeout
func IdleTimeout(value time.Duration) Option {
	return func(f *opts) error {
		f.idleTimeout = value
		return nil
	}
}

// NewPool
func NewPool(ctx context.Context, service, target string, o ...Option) (_ *Pool, loaded bool) {
	mu.Lock()
	defer mu.Unlock()
	if p := poolList[service]; p != nil {
		return p, true
	}
	p := &Pool{
		id:      time.Now().String(),
		ctx:     ctx,
		service: service,
		opts:    &opts{},
		target:  target,
	}
	for _, option := range o {
		_ = option(p.opts)
	}
	factory := func() (*grpc.ClientConn, error) {
		c := &conn{pool: p}
		c.init()
		return c.conn, c.err
	}
	p.pool, _ = grpcpool.New(factory, p.opts.initConn, p.opts.maxConn, p.opts.idleTimeout, p.opts.maxLifeDuration)
	return p, false
}


================================================
FILE: app/grpc/provider.go
================================================
package grpc

import (
	"context"
	"sync"
	"time"

	tracesdk "go.opentelemetry.io/otel/sdk/trace"

	"github.com/aristat/golang-example-app/app/logger"

	"github.com/google/wire"
	"github.com/spf13/viper"
	"google.golang.org/grpc/keepalive"
)

var (
	pm      *PoolManager
	mutexPM sync.Mutex
)

// Cfg
func Cfg(cfg *viper.Viper) (*Config, func(), error) {
	c := &Config{}
	e := cfg.UnmarshalKey("grpc", c)
	if e != nil {
		return c, func() {}, e
	}
	return c, func() {}, e
}

// CfgTest
func CfgTest() (*Config, func(), error) {
	return &Config{}, func() {}, nil
}

// Service
type Service struct {
	Target           string
	MaxConn          int
	InitConn         int
	MaxLifeDuration  time.Duration
	IdleTimeout      time.Duration
	ClientParameters *keepalive.ClientParameters
}

// Config
type Config struct {
	Services         map[string]*Service
	ClientParameters *keepalive.ClientParameters
}

// Provider
func Provider(ctx context.Context, tracing *tracesdk.TracerProvider, logger logger.Logger, cfg *Config) (*PoolManager, func(), error) {
	mutexPM.Lock()
	defer mutexPM.Unlock()
	if pm != nil {
		return pm, func() {}, nil
	}
	pm = NewPoolManager(ctx, tracing, logger, cfg)
	return pm, func() {}, nil
}

var (
	ProviderProductionSet = wire.NewSet(Provider, Cfg)
	ProviderTestSet       = wire.NewSet(Provider, CfgTest)
)


================================================
FILE: app/http/http.go
================================================
package http

import (
	"context"
	"net/http"
	"sync"

	"github.com/go-chi/chi/v5"

	"github.com/go-session/session"

	"github.com/aristat/golang-example-app/app/logger"
)

const prefix = "app.http"

// Config
type Config struct {
	Debug bool
	Bind  string
}

// Http
type Http struct {
	ctx     context.Context
	cfg     Config
	session *session.Manager
	log     logger.Logger
	mux     *chi.Mux
}

// ListenAndServe
func (m *Http) ListenAndServe(wg *sync.WaitGroup, bind ...string) (server *http.Server) {
	bindAddress := m.cfg.Bind

	if len(bind) > 0 && len(bind[0]) > 0 {
		bindAddress = bind[0]
	}

	server = &http.Server{
		Addr:    bindAddress,
		Handler: m.mux,
	}

	go func() {
		defer wg.Done()

		if err := server.ListenAndServe(); err != nil {
			if err != http.ErrServerClosed {
				m.log.Emergency("Server is shutdown with error, %v", logger.Args(err))
			} else {
				err = nil
			}
		}

		m.log.Info("HTTP Server stopped successfully")
	}()

	return server
}

// New
func New(ctx context.Context, mux *chi.Mux, log logger.Logger, cfg Config) *Http {
	return &Http{
		ctx: ctx,
		cfg: cfg,
		mux: mux,
		log: log.WithFields(logger.Fields{"service": prefix}),
	}
}


================================================
FILE: app/http/injector.go
================================================
// +build wireinject

package http

import (
	"github.com/aristat/golang-example-app/app/auth"
	"github.com/aristat/golang-example-app/app/db"
	"github.com/aristat/golang-example-app/app/db/repo"
	"github.com/aristat/golang-example-app/app/graphql"
	products_router "github.com/aristat/golang-example-app/app/http_routers/products-router"
	"github.com/aristat/golang-example-app/app/provider"
	"github.com/google/wire"
)

// Build
func Build() (*Http, func(), error) {
	panic(wire.Build(
		ProviderProductionSet,
		auth.ProviderProductionSet,
		graphql.ProviderProductionSet,
		products_router.ProviderProductionSet,
		repo.ProviderProductionSet,
		db.ProviderProductionSet,
		provider.AwareProductionSet,
	))
}


================================================
FILE: app/http/logger.go
================================================
package http

import (
	"net/http"
	"time"

	"github.com/aristat/golang-example-app/app/logger"
	"github.com/go-chi/chi/v5/middleware"
)

func Logger(l logger.Logger) func(next http.Handler) http.Handler {
	return func(next http.Handler) http.Handler {
		fn := func(w http.ResponseWriter, r *http.Request) {
			ww := middleware.NewWrapResponseWriter(w, r.ProtoMajor)

			t1 := time.Now()
			defer func() {
				l.Info("proto %s, path %s, lat %d, status %d, size %d, reqId %s", logger.Args(
					r.Proto,
					r.URL.Path,
					time.Since(t1),
					ww.Status(),
					ww.BytesWritten(),
					middleware.GetReqID(r.Context()),
				))
			}()

			next.ServeHTTP(ww, r)
		}
		return http.HandlerFunc(fn)
	}
}


================================================
FILE: app/http/provider.go
================================================
package http

import (
	"context"

	"github.com/riandyrn/otelchi"

	"github.com/aristat/golang-example-app/app/dataloader"

	products_router "github.com/aristat/golang-example-app/app/http_routers/products-router"

	"github.com/aristat/golang-example-app/app/auth"

	"github.com/aristat/golang-example-app/app/graphql"
	"github.com/go-chi/chi/v5"
	"github.com/go-chi/chi/v5/middleware"

	"github.com/aristat/golang-example-app/app/logger"

	"github.com/google/wire"
	"github.com/spf13/viper"
)

var muxRouter *chi.Mux

// Cfg
func Cfg(cfg *viper.Viper) (Config, func(), error) {
	c := Config{}
	e := cfg.UnmarshalKey("http", &c)
	if e != nil {
		return c, func() {}, e
	}
	c.Debug = cfg.GetBool("debug")
	return c, func() {}, nil
}

// CfgTest
func CfgTest() (Config, func(), error) {
	return Config{}, func() {}, nil
}

// Mux
func Mux(managers Managers, log logger.Logger) (*chi.Mux, func(), error) {
	if muxRouter != nil {
		return muxRouter, func() {}, nil
	}

	muxRouter = chi.NewRouter()
	muxRouter.Use(middleware.RequestID)
	muxRouter.Use(Logger(log))
	muxRouter.Use(otelchi.Middleware("http-server", otelchi.WithChiRoutes(muxRouter)))
	muxRouter.Use(dataloader.LoaderMiddleware)

	managers.products.Router.Run(muxRouter)
	managers.graphql.Routers(muxRouter.With(managers.authMiddleware.JWTHandler))

	return muxRouter, func() {}, nil
}

// ServiceManagers
type Managers struct {
	products       *products_router.Manager
	authMiddleware *auth.Middleware
	graphql        *graphql.GraphQL
}

var ProviderManagers = wire.NewSet(
	wire.Struct(new(Managers), "*"),
)

// Provider
func Provider(ctx context.Context, mux *chi.Mux, log logger.Logger, cfg Config) (*Http, func(), error) {
	g := New(ctx, mux, log, cfg)
	return g, func() {}, nil
}

var (
	ProviderProductionSet = wire.NewSet(Provider, Cfg, Mux, ProviderManagers)
	ProviderTestSet       = wire.NewSet(Provider, CfgTest)
)


================================================
FILE: app/http/wire_gen.go
================================================
// Code generated by Wire. DO NOT EDIT.

//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject

package http

import (
	"github.com/aristat/golang-example-app/app/auth"
	"github.com/aristat/golang-example-app/app/casbin"
	"github.com/aristat/golang-example-app/app/config"
	"github.com/aristat/golang-example-app/app/db"
	"github.com/aristat/golang-example-app/app/db/repo"
	"github.com/aristat/golang-example-app/app/entrypoint"
	"github.com/aristat/golang-example-app/app/graphql"
	"github.com/aristat/golang-example-app/app/graphql_resolver"
	"github.com/aristat/golang-example-app/app/grpc"
	"github.com/aristat/golang-example-app/app/http_routers/products-router"
	"github.com/aristat/golang-example-app/app/logger"
	"github.com/aristat/golang-example-app/app/tracing"
)

// Injectors from injector.go:

// Build
func Build() (*Http, func(), error) {
	context, cleanup, err := entrypoint.ContextProvider()
	if err != nil {
		return nil, nil, err
	}
	viper, cleanup2, err := config.Provider()
	if err != nil {
		cleanup()
		return nil, nil, err
	}
	loggerConfig, cleanup3, err := logger.ProviderCfg(viper)
	if err != nil {
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	zap, cleanup4, err := logger.Provider(context, loggerConfig)
	if err != nil {
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	configuration, cleanup5, err := tracing.Cfg(viper)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	tracerProvider, cleanup6, err := tracing.Provider(context, configuration, zap)
	if err != nil {
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	grpcConfig, cleanup7, err := grpc.Cfg(viper)
	if err != nil {
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	poolManager, cleanup8, err := grpc.Provider(context, tracerProvider, zap, grpcConfig)
	if err != nil {
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	serviceManagers := products_router.ServiceManagers{
		PoolManager: poolManager,
	}
	products_routerConfig, cleanup9, err := products_router.Cfg(viper)
	if err != nil {
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	manager, cleanup10, err := products_router.Provider(context, zap, serviceManagers, products_routerConfig)
	if err != nil {
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	authConfig, cleanup11, err := auth.ProviderCfg(viper)
	if err != nil {
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	middleware, cleanup12, err := auth.Provider(authConfig, zap)
	if err != nil {
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	graphql_resolverConfig, cleanup13, err := graphql_resolver.Cfg(viper)
	if err != nil {
		cleanup12()
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	enforcer, cleanup14, err := casbin.Provider()
	if err != nil {
		cleanup13()
		cleanup12()
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	dbConfig, cleanup15, err := db.Cfg(viper)
	if err != nil {
		cleanup14()
		cleanup13()
		cleanup12()
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	gormDB, cleanup16, err := db.ProviderGORM(context, zap, dbConfig)
	if err != nil {
		cleanup15()
		cleanup14()
		cleanup13()
		cleanup12()
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	usersRepo, cleanup17, err := repo.NewUsersRepo(gormDB)
	if err != nil {
		cleanup16()
		cleanup15()
		cleanup14()
		cleanup13()
		cleanup12()
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	repoRepo, cleanup18, err := repo.Provider(usersRepo)
	if err != nil {
		cleanup17()
		cleanup16()
		cleanup15()
		cleanup14()
		cleanup13()
		cleanup12()
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	managers := graphql_resolver.Managers{
		Repo:        repoRepo,
		PollManager: poolManager,
	}
	graphqlConfig, cleanup19, err := graphql_resolver.Provider(context, zap, graphql_resolverConfig, enforcer, managers)
	if err != nil {
		cleanup18()
		cleanup17()
		cleanup16()
		cleanup15()
		cleanup14()
		cleanup13()
		cleanup12()
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	config2, cleanup20, err := graphql.Cfg(viper)
	if err != nil {
		cleanup19()
		cleanup18()
		cleanup17()
		cleanup16()
		cleanup15()
		cleanup14()
		cleanup13()
		cleanup12()
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	graphQL, cleanup21, err := graphql.Provider(context, graphqlConfig, zap, config2)
	if err != nil {
		cleanup20()
		cleanup19()
		cleanup18()
		cleanup17()
		cleanup16()
		cleanup15()
		cleanup14()
		cleanup13()
		cleanup12()
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	httpManagers := Managers{
		products:       manager,
		authMiddleware: middleware,
		graphql:        graphQL,
	}
	mux, cleanup22, err := Mux(httpManagers, zap)
	if err != nil {
		cleanup21()
		cleanup20()
		cleanup19()
		cleanup18()
		cleanup17()
		cleanup16()
		cleanup15()
		cleanup14()
		cleanup13()
		cleanup12()
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	httpConfig, cleanup23, err := Cfg(viper)
	if err != nil {
		cleanup22()
		cleanup21()
		cleanup20()
		cleanup19()
		cleanup18()
		cleanup17()
		cleanup16()
		cleanup15()
		cleanup14()
		cleanup13()
		cleanup12()
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	http, cleanup24, err := Provider(context, mux, zap, httpConfig)
	if err != nil {
		cleanup23()
		cleanup22()
		cleanup21()
		cleanup20()
		cleanup19()
		cleanup18()
		cleanup17()
		cleanup16()
		cleanup15()
		cleanup14()
		cleanup13()
		cleanup12()
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	return http, func() {
		cleanup24()
		cleanup23()
		cleanup22()
		cleanup21()
		cleanup20()
		cleanup19()
		cleanup18()
		cleanup17()
		cleanup16()
		cleanup15()
		cleanup14()
		cleanup13()
		cleanup12()
		cleanup11()
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
	}, nil
}


================================================
FILE: app/http_routers/products-router/injector.go
================================================
// +build wireinject

package products_router

import (
	"github.com/aristat/golang-example-app/app/provider"
	"github.com/google/wire"
)

// Build
func Build() (*Manager, func(), error) {
	panic(wire.Build(ProviderProductionSet, provider.AwareProductionSet))
}

func BuildTest() (*Manager, func(), error) {
	panic(wire.Build(ProviderTestSet, provider.AwareTestSet))
}


================================================
FILE: app/http_routers/products-router/manager.go
================================================
package products_router

import (
	"context"

	"github.com/aristat/golang-example-app/app/grpc"
	"github.com/aristat/golang-example-app/app/logger"
)

const prefix = "app.products-router"

// Product Manager
type Manager struct {
	ctx    context.Context
	logger logger.Logger
	Router *Router
}

// ServiceManagers
type ServiceManagers struct {
	PoolManager *grpc.PoolManager
}

func New(ctx context.Context, log logger.Logger, managers ServiceManagers, cfg *Config) *Manager {
	log = log.WithFields(logger.Fields{"service": prefix})

	router := &Router{
		ctx:         ctx,
		cfg:         cfg,
		logger:      log,
		poolManager: managers.PoolManager,
	}

	return &Manager{
		ctx:    ctx,
		logger: log,
		Router: router,
	}
}


================================================
FILE: app/http_routers/products-router/provider.go
================================================
package products_router

import (
	"context"

	"github.com/aristat/golang-example-app/app/logger"
	"github.com/google/wire"
	"github.com/spf13/viper"
)

// Cfg
func Cfg(cfg *viper.Viper) (*Config, func(), error) {
	c := &Config{}
	e := cfg.UnmarshalKey("products", c)
	if e != nil {
		return c, func() {}, e
	}
	return c, func() {}, e
}

// CfgTest
func CfgTest() (*Config, func(), error) {
	return &Config{}, func() {}, nil
}

// Config
type Config struct {
	NatsURL string
	Subject string
}

var ProviderManagers = wire.NewSet(
	wire.Struct(new(ServiceManagers), "*"),
)

// Provider
func Provider(ctx context.Context, log logger.Logger, managers ServiceManagers, cfg *Config) (*Manager, func(), error) {
	g := New(ctx, log, managers, cfg)
	return g, func() {}, nil
}

var (
	ProviderProductionSet = wire.NewSet(Provider, ProviderManagers, Cfg)
	ProviderTestSet       = wire.NewSet(Provider, ProviderManagers, CfgTest)
)


================================================
FILE: app/http_routers/products-router/router.go
================================================
package products_router

import (
	"context"
	"encoding/json"
	"net/http"
	"time"

	"github.com/nats-io/stan.go"

	"github.com/aristat/golang-example-app/app/common"
	"github.com/go-chi/chi/v5"
	"github.com/nats-io/nats.go"

	"github.com/aristat/golang-example-app/app/grpc"
	"github.com/aristat/golang-example-app/app/logger"
	"github.com/aristat/golang-example-app/generated/resources/proto/products"
)

type Router struct {
	ctx         context.Context
	cfg         *Config
	logger      logger.Logger
	poolManager *grpc.PoolManager
}

func (router *Router) Run(chiRouter chi.Router) {
	chiRouter.Get("/products_grpc", router.GetProductsGrpc)
	chiRouter.Get("/products_nats", router.GetProductsNats)
	chiRouter.Get("/products_slowly", router.GetProductsSlowly)
}

func (router *Router) GetProductsGrpc(w http.ResponseWriter, r *http.Request) {
	conn, d, err := grpc.GetConnGRPC(router.poolManager, common.SrvProducts)
	defer d()
	defer r.Body.Close()

	if err != nil {
		router.logger.Printf("[ERROR] %s", err.Error())
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	c := products.NewProductsClient(conn)

	ctx, cancel := context.WithTimeout(r.Context(), time.Second)
	defer cancel()

	e := json.NewEncoder(w)

	productOut, err := c.ListProduct(ctx, &products.ListProductIn{Id: 1})
	if err != nil {
		w.WriteHeader(http.StatusBadGateway)
		e.Encode("{}")
		return
	}

	e.Encode(productOut)
}

func (router *Router) GetProductsNats(w http.ResponseWriter, r *http.Request) {
	// Connect to NATS
	nc, err := nats.Connect(router.cfg.NatsURL)
	if err != nil {
		router.logger.Error(err.Error())
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	defer nc.Close()

	sc, err := stan.Connect("test-cluster", "stan-pub", stan.NatsConn(nc))
	if err != nil {
		router.logger.Error(err.Error())
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	// Close connection
	defer sc.Close()

	message := "Hello"
	router.logger.Printf("[NATS] send %s", message)
	err = sc.Publish(router.cfg.Subject, []byte(message))

	if err != nil {
		router.logger.Printf("[ERROR] %s", err.Error())
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	e := json.NewEncoder(w)
	e.Encode("done")
}

func (router *Router) GetProductsSlowly(w http.ResponseWriter, r *http.Request) {
	router.logger.Info("Start sleep")
	time.Sleep(time.Second * 10)
	router.logger.Info("Stop sleep")
	e := json.NewEncoder(w)
	e.Encode("")
}


================================================
FILE: app/http_routers/products-router/router_test.go
================================================
package products_router_test

import (
	"context"
	"log"
	"net"
	"net/http"
	"net/http/httptest"
	"os"
	"strconv"
	"strings"
	"testing"

	products_router "github.com/aristat/golang-example-app/app/http_routers/products-router"
	"github.com/stretchr/testify/assert"

	"github.com/aristat/golang-example-app/app/common"
	grpc1 "github.com/aristat/golang-example-app/app/grpc"

	"github.com/aristat/golang-example-app/app/graphql_resolver"

	"github.com/aristat/golang-example-app/generated/resources/proto/products"

	"google.golang.org/grpc"
)

var (
	productServerHost = "localhost"
	grpcPort          string
)

func TestMain(m *testing.M) {
	lis, err := net.Listen("tcp", ":0")
	if err != nil {
		log.Fatalf(err.Error())
	}
	defer lis.Close()

	grpcPort = ":" + strconv.Itoa(lis.Addr().(*net.TCPAddr).Port)
	s := grpc.NewServer()
	products.RegisterProductsServer(s, &graphql_resolver.ProductServerMock{})

	go func() {
		if err := s.Serve(lis); err != nil {
			log.Fatalf("Server exited with error: %v", err)
		}
	}()

	code := m.Run()

	os.Exit(code)
}

func TestGetProductsGrpc(t *testing.T) {
	var opts []grpc.DialOption
	ctx := context.Background()
	opts = append(opts, grpc.WithInsecure())

	pool, _ := grpc1.NewPool(ctx, common.SrvProducts, productServerHost+grpcPort, grpc1.ConnOptions(opts...))
	grpc1.SetPool(pool, common.SrvProducts)

	tests := []struct {
		name         string
		expectedCode int
	}{
		{
			name:         "successful",
			expectedCode: http.StatusOK,
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			provider, _, e := products_router.BuildTest()
			assert.Nil(t, e, "err should be nil")

			rec := httptest.NewRecorder()
			req, _ := http.NewRequest(http.MethodGet, "/products_grpc", strings.NewReader(""))
			provider.Router.GetProductsGrpc(rec, req)

			assert.Equal(t, test.expectedCode, rec.Code)
			assert.NotNil(t, rec.Body)
		})
	}
}


================================================
FILE: app/http_routers/products-router/wire_gen.go
================================================
// Code generated by Wire. DO NOT EDIT.

//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject

package products_router

import (
	"github.com/aristat/golang-example-app/app/config"
	"github.com/aristat/golang-example-app/app/entrypoint"
	"github.com/aristat/golang-example-app/app/grpc"
	"github.com/aristat/golang-example-app/app/logger"
	"github.com/aristat/golang-example-app/app/tracing"
)

// Injectors from injector.go:

// Build
func Build() (*Manager, func(), error) {
	context, cleanup, err := entrypoint.ContextProvider()
	if err != nil {
		return nil, nil, err
	}
	viper, cleanup2, err := config.Provider()
	if err != nil {
		cleanup()
		return nil, nil, err
	}
	loggerConfig, cleanup3, err := logger.ProviderCfg(viper)
	if err != nil {
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	zap, cleanup4, err := logger.Provider(context, loggerConfig)
	if err != nil {
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	configuration, cleanup5, err := tracing.Cfg(viper)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	tracerProvider, cleanup6, err := tracing.Provider(context, configuration, zap)
	if err != nil {
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	grpcConfig, cleanup7, err := grpc.Cfg(viper)
	if err != nil {
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	poolManager, cleanup8, err := grpc.Provider(context, tracerProvider, zap, grpcConfig)
	if err != nil {
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	serviceManagers := ServiceManagers{
		PoolManager: poolManager,
	}
	products_routerConfig, cleanup9, err := Cfg(viper)
	if err != nil {
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	manager, cleanup10, err := Provider(context, zap, serviceManagers, products_routerConfig)
	if err != nil {
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	return manager, func() {
		cleanup10()
		cleanup9()
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
	}, nil
}

func BuildTest() (*Manager, func(), error) {
	context, cleanup, err := entrypoint.ContextProviderTest()
	if err != nil {
		return nil, nil, err
	}
	loggerConfig, cleanup2, err := logger.ProviderCfgTest()
	if err != nil {
		cleanup()
		return nil, nil, err
	}
	mock, cleanup3, err := logger.ProviderTest(context, loggerConfig)
	if err != nil {
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	tracerProvider, cleanup4, err := tracing.ProviderTest()
	if err != nil {
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	grpcConfig, cleanup5, err := grpc.CfgTest()
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	poolManager, cleanup6, err := grpc.Provider(context, tracerProvider, mock, grpcConfig)
	if err != nil {
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	serviceManagers := ServiceManagers{
		PoolManager: poolManager,
	}
	products_routerConfig, cleanup7, err := CfgTest()
	if err != nil {
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	manager, cleanup8, err := Provider(context, mock, serviceManagers, products_routerConfig)
	if err != nil {
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	return manager, func() {
		cleanup8()
		cleanup7()
		cleanup6()
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
	}, nil
}


================================================
FILE: app/logger/injector.go
================================================
// +build wireinject

package logger

import (
	"github.com/aristat/golang-example-app/app/config"
	"github.com/aristat/golang-example-app/app/entrypoint"
	"github.com/google/wire"
)

// Build returns logger instance implemented of Logger interface with resolved dependencies
func Build() (Logger, func(), error) {
	panic(wire.Build(ProviderProductionSet, entrypoint.ProviderProductionSet, config.ProviderSet))
}

func BuildTest() (Logger, func(), error) {
	panic(wire.Build(ProviderTestSet, entrypoint.ProviderTestSet))
}


================================================
FILE: app/logger/logger.go
================================================
package logger

type (
	Fields map[string]interface{}
)

// Level represent RFC5424 logger severity
type Level int8

// String implements interface Stringer
func (l Level) String() string {
	switch l {
	case LevelDebug:
		return "debug"
	case LevelInfo:
		return "info"
	case LevelNotice:
		return "notice"
	case LevelWarning:
		return "warning"
	case LevelError:
		return "error"
	case LevelCritical:
		return "critical"
	case LevelAlert:
		return "alert"
	case LevelEmergency:
		return "emergency"
	}
	return "unknown"
}

// FromString set logger level from string representation
func (l *Level) FromString(level string) Level {
	switch level {
	case "debug":
		*l = LevelDebug
	case "info":
		*l = LevelInfo
	case "notice":
		*l = LevelNotice
	case "warning":
		*l = LevelWarning
	case "error":
		*l = LevelError
	case "critical":
		*l = LevelCritical
	case "alert":
		*l = LevelAlert
	case "emergency":
		*l = LevelEmergency
	}
	return *l
}

const (
	// Debug: debug-level messages
	LevelDebug Level = 7
	// Informational: informational messages
	LevelInfo Level = 6
	// Notice: normal but significant condition
	LevelNotice Level = 5
	// Warning: warning conditions
	LevelWarning Level = 4
	// Error: error conditions
	LevelError Level = 3
	// Critical: critical conditions
	LevelCritical Level = 2
	// Alert: action must be taken immediately
	LevelAlert Level = 1
	// Emergency: system is unusable
	LevelEmergency Level = 0
)

type opts struct {
	args   []interface{}
	fields Fields
}

// Option is func hook for underling logic call
type Option func(*opts) error

// Args returns func hook a logger for replace fmt placeholders on represent values
func Args(a ...interface{}) Option {
	return func(f *opts) error {
		f.args = a
		return nil
	}
}

// WithFields returns func hook a logger for adding fields for call
func WithFields(fields Fields) Option {
	return func(f *opts) error {
		f.fields = fields
		return nil
	}
}

// Config is a general logger config settings
type Config struct {
	Debug bool
}

// Logger is the interface for logger client
type Logger interface {
	// Printf is like fmt.Printf, push to log entry with debug level
	Printf(format string, a ...interface{})
	// Emergency push to log entry with emergency level & throw panic
	Emergency(format string, opts ...Option)
	// Alert push to log entry with alert level
	Alert(format string, opts ...Option)
	// Critical push to log entry with critical level
	Critical(format string, opts ...Option)
	// Error push to log entry with error level
	Error(format string, opts ...Option)
	// Warning push to log entry with warning level
	Warning(format string, opts ...Option)
	// Notice push to log entry with notice level
	Notice(format string, opts ...Option)
	// Info push to log entry with info level
	Info(format string, opts ...Option)
	// Debug push to log entry with debug level
	Debug(format string, opts ...Option)
	// Write push to log entry with debug level
	Write(p []byte) (n int, err error)
	// Log push to log with specified level
	Log(level Level, format string, opts ...Option)
	// WithFields create new instance with fields
	WithFields(fields Fields) Logger
}


================================================
FILE: app/logger/middleware.go
================================================
package logger

import (
	"context"
	"strings"
	"time"

	"google.golang.org/grpc"
)

// UnaryClientInterceptor wrapper to logging query
func UnaryClientInterceptor(log Logger, enable bool) grpc.UnaryClientInterceptor {
	return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
		if !enable {
			return invoker(ctx, method, req, reply, cc, opts...)
		}

		startTime := time.Now()
		err := invoker(ctx, method, req, reply, cc, opts...)

		var e string
		if err != nil {
			e = strings.ReplaceAll(err.Error(), "\n", "")
		}

		log.Debug("\nQUERY UnaryClient:\n\nData: %v\n\nERROR:\n%v\n\n", Args(req, e), WithFields(Fields{
			"time": time.Since(startTime).String(),
		}))

		return err
	}
}

// StreamClientInterceptor returns a new streaming client interceptor
func StreamClientInterceptor(log Logger, enable bool) grpc.StreamClientInterceptor {
	return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
		if !enable {
			return streamer(ctx, desc, cc, method, opts...)
		}

		startTime := time.Now()
		clientStream, err := streamer(ctx, desc, cc, method, opts...)
		var e string
		if err != nil {
			e = strings.ReplaceAll(err.Error(), "\n", "")
		}

		log.Debug("\nQUERY StreamClient:\n\nMethod: %v\n\nERROR:\n%v\n\n", Args(method, e), WithFields(Fields{
			"time": time.Since(startTime).String(),
		}))

		return clientStream, err
	}
}

// UnaryServerInterceptor wrapper to logging query
func UnaryServerInterceptor(log Logger, enable bool) grpc.UnaryServerInterceptor {
	return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
		if !enable {
			return handler(ctx, req)
		}

		startTime := time.Now()
		res, err := handler(ctx, req)

		var e string
		if err != nil {
			e = strings.ReplaceAll(err.Error(), "\n", "")
		}

		log.Debug("\nQUERY UnaryServer:\n\nFullMethod: %v\nData: %v\nRESPONSE:\n\nData: %v\nERROR:\n%v\n", Args(info.FullMethod, req, res, e), WithFields(Fields{
			"time": time.Since(startTime).String(),
		}))

		return res, err
	}
}

// StreamServerInterceptor returns a new streaming server interceptor
func StreamServerInterceptor(log Logger, enable bool) grpc.StreamServerInterceptor {
	return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
		if !enable {
			return handler(srv, stream)
		}

		startTime := time.Now()
		err := handler(srv, stream)

		var e string
		if err != nil {
			e = strings.ReplaceAll(err.Error(), "\n", "")
		}

		log.Debug("\nQUERY StreamServer:\n\nFullMethod: %v\n\nERROR:\n%v\n", Args(info.FullMethod, e), WithFields(Fields{
			"time": time.Since(startTime).String(),
		}))

		return err
	}
}


================================================
FILE: app/logger/mock.go
================================================
package logger

import (
	"context"
)

// Entity represent log struct with all assets
type Entity struct {
	Level  Level
	Fields Fields
	Args   []interface{}
	Format string
}

// Mock is the logger with stubbed methods
type Mock struct {
	ctx     context.Context
	ch      chan Entity
	discard bool
	cfg     Config
	fields  map[string]interface{}
}

// Printf is like fmt.Printf, push to log entry with debug level
func (m *Mock) Printf(format string, a ...interface{}) {
	m.Debug(format, Args(a...))
}

// Emergency push to log entry with emergency level & throw panic
func (m *Mock) Emergency(format string, opts ...Option) {
	m.Log(LevelEmergency, format, opts...)
}

// Alert push to log entry with alert level
func (m *Mock) Alert(format string, opts ...Option) {
	m.Log(LevelAlert, format, opts...)
}

// Critical push to log entry with critical level
func (m *Mock) Critical(format string, opts ...Option) {
	m.Log(LevelCritical, format, opts...)
}

// Error push to log entry with error level
func (m *Mock) Error(format string, opts ...Option) {
	m.Log(LevelError, format, opts...)
}

// Warning push to log entry with warning level
func (m *Mock) Warning(format string, opts ...Option) {
	m.Log(LevelWarning, format, opts...)
}

// Notice push to log entry with notice level
func (m *Mock) Notice(format string, opts ...Option) {
	m.Log(LevelNotice, format, opts...)
}

// Info push to log entry with info level
func (m *Mock) Info(format string, opts ...Option) {
	m.Log(LevelInfo, format, opts...)
}

// Debug push to log entry with debug level
func (m *Mock) Debug(format string, opts ...Option) {
	m.Log(LevelDebug, format, opts...)
}

// Write push to log entry with debug level
func (m *Mock) Write(p []byte) (n int, err error) {
	m.Debug(string(p))
	return len(p), nil
}

// Log push to log with specified level
func (m *Mock) Log(level Level, format string, o ...Option) {
	if !m.discard {
		return
	}
	opts := &opts{}
	for _, option := range o {
		_ = option(opts)
	}
	var (
		fields = map[string]interface{}{}
	)
	// fields
	for k, v := range m.fields {
		fields[k] = v
	}
	for k, v := range opts.fields {
		fields[k] = v
	}

	go func() {
		m.ch <- Entity{
			Level:  level,
			Format: format,
			Args:   opts.args,
			Fields: fields,
		}
	}()
}

// WithFields create new instance with fields
func (m *Mock) WithFields(fields Fields) Logger {
	nm := &Mock{}
	copyMock(nm, m, fields)
	return nm
}

func copyMock(dst, src *Mock, fields map[string]interface{}) {
	var cFields = map[string]interface{}{}
	// fields
	for k, v := range src.fields {
		cFields[k] = v
	}
	dst.fields = cFields
	if fields != nil {
		for k, v := range fields {
			dst.fields[k] = v
		}
	}
	dst.discard = src.discard
	dst.ch = src.ch
}

// Catch returns channel of entity structure for testing event content
func (m *Mock) Catch() <-chan Entity {
	return m.ch
}

// NewMock returns mock instance implemented of Logger interface
func newMock(ctx context.Context, cfg Config, discard bool) *Mock {
	return &Mock{
		ctx:     ctx,
		cfg:     cfg,
		ch:      make(chan Entity),
		discard: discard,
	}
}


================================================
FILE: app/logger/provider.go
================================================
package logger

import (
	"context"

	"github.com/google/wire"
	"github.com/spf13/viper"
)

// ProviderCfg returns configuration for production logger
func ProviderCfg(cfg *viper.Viper) (Config, func(), error) {
	c := Config{}
	e := cfg.UnmarshalKey("logger", &c)
	if e != nil {
		return c, func() {}, e
	}
	if cfg.IsSet("debug") && !c.Debug {
		c.Debug = cfg.GetBool("debug")
	}
	return c, func() {}, nil
}

// ProviderCfgTest returns configuration for stub/mock logger
func ProviderCfgTest() (Config, func(), error) {
	return Config{}, func() {}, nil
}

// Provider returns logger instance implemented of Logger interface with resolved dependencies
func Provider(ctx context.Context, cfg Config) (*Zap, func(), error) {
	return newZap(ctx, cfg), func() {}, nil
}

// ProviderTest returns stub/mock logger instance implemented of Logger interface with resolved dependencies
func ProviderTest(ctx context.Context, cfg Config) (*Mock, func(), error) {
	mock := newMock(ctx, cfg, true)

	cleanup := func() {
		if mock.ch != nil {
			close(mock.ch)
		}
	}
	return mock, cleanup, nil
}

var (
	ProviderProductionSet = wire.NewSet(Provider, ProviderCfg, wire.Bind(new(Logger), new(*Zap)))
	ProviderTestSet       = wire.NewSet(ProviderTest, ProviderCfgTest, wire.Bind(new(Logger), new(*Mock)))
)


================================================
FILE: app/logger/wire_gen.go
================================================
// Code generated by Wire. DO NOT EDIT.

//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject

package logger

import (
	"github.com/aristat/golang-example-app/app/config"
	"github.com/aristat/golang-example-app/app/entrypoint"
)

// Injectors from injector.go:

// Build returns logger instance implemented of Logger interface with resolved dependencies
func Build() (Logger, func(), error) {
	context, cleanup, err := entrypoint.ContextProvider()
	if err != nil {
		return nil, nil, err
	}
	viper, cleanup2, err := config.Provider()
	if err != nil {
		cleanup()
		return nil, nil, err
	}
	loggerConfig, cleanup3, err := ProviderCfg(viper)
	if err != nil {
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	zap, cleanup4, err := Provider(context, loggerConfig)
	if err != nil {
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	return zap, func() {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
	}, nil
}

func BuildTest() (Logger, func(), error) {
	context, cleanup, err := entrypoint.ContextProviderTest()
	if err != nil {
		return nil, nil, err
	}
	loggerConfig, cleanup2, err := ProviderCfgTest()
	if err != nil {
		cleanup()
		return nil, nil, err
	}
	mock, cleanup3, err := ProviderTest(context, loggerConfig)
	if err != nil {
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	return mock, func() {
		cleanup3()
		cleanup2()
		cleanup()
	}, nil
}


================================================
FILE: app/logger/zap.go
================================================
package logger

import (
	"context"

	"go.uber.org/zap/zapcore"

	"go.uber.org/zap"
)

// Zap is uber/zap logger implemented of Logger interface
type Zap struct {
	ctx    context.Context
	cfg    Config
	logger *zap.SugaredLogger
	fields map[string]interface{}
}

// Printf is like fmt.Printf, push to log entry with debug level
func (z *Zap) Printf(format string, a ...interface{}) {
	z.Debug(format, Args(a...))
}

// Emergency push to log entry with emergency level & throw panic
func (z *Zap) Emergency(format string, opts ...Option) {
	z.Log(LevelEmergency, format, opts...)
}

// Alert push to log entry with alert level
func (z *Zap) Alert(format string, opts ...Option) {
	z.Log(LevelAlert, format, opts...)
}

// Critical push to log entry with critical level
func (z *Zap) Critical(format string, opts ...Option) {
	z.Log(LevelCritical, format, opts...)
}

// Error push to log entry with error level
func (z *Zap) Error(format string, opts ...Option) {
	z.Log(LevelError, format, opts...)
}

// Warning push to log entry with warning level
func (z *Zap) Warning(format string, opts ...Option) {
	z.Log(LevelWarning, format, opts...)
}

// Notice push to log entry with notice level
func (z *Zap) Notice(format string, opts ...Option) {
	z.Log(LevelNotice, format, opts...)
}

// Info push to log entry with info level
func (z *Zap) Info(format string, opts ...Option) {
	z.Log(LevelInfo, format, opts...)
}

// Debug push to log entry with debug level
func (z *Zap) Debug(format string, opts ...Option) {
	z.Log(LevelDebug, format, opts...)
}

// Write push to log entry with debug level
func (z *Zap) Write(p []byte) (n int, err error) {
	z.Debug(string(p))
	return len(p), nil
}

// Log push to log with specified level
func (z *Zap) Log(level Level, format string, o ...Option) {
	opts := &opts{}
	for _, option := range o {
		_ = option(opts)
	}
	var (
		wargs = []interface{}{"level", level.String()}
	)

	// fields
	for k, v := range z.fields {
		wargs = append(wargs, k, v)
	}
	for k, v := range opts.fields {
		wargs = append(wargs, k, v)
	}

	var logger = z.logger
	if len(wargs) > 0 {
		logger = logger.With(wargs...)
	}

	if len(opts.args) == 0 {
		var fn func(args ...interface{})
		switch level {
		default:
			fn = logger.Debug
		case LevelInfo, LevelNotice:
			fn = logger.Info
		case LevelWarning:
			fn = logger.Warn
		case LevelError, LevelCritical, LevelAlert:
			fn = logger.Error
		case LevelEmergency:
			fn = logger.Panic
		}
		fn(format)
	} else {
		var fn func(format string, args ...interface{})
		switch level {
		default:
			fn = logger.Debugf
		case LevelInfo, LevelNotice:
			fn = logger.Infof
		case LevelWarning:
			fn = logger.Warnf
		case LevelError, LevelCritical, LevelAlert:
			fn = logger.Errorf
		case LevelEmergency:
			fn = logger.Panicf
		}
		fn(format, opts.args...)
	}
}

// WithFields create new instance with fields
func (z *Zap) WithFields(fields Fields) Logger {
	nz := &Zap{}
	copyZap(nz, z, fields)
	return nz
}

func copyZap(dst, src *Zap, fields map[string]interface{}) {
	var cFields = map[string]interface{}{}
	// fields
	for k, v := range src.fields {
		cFields[k] = v
	}
	dst.fields = cFields
	if fields != nil {
		for k, v := range fields {
			dst.fields[k] = v
		}
	}
	dst.logger = src.logger
}

// NewZap returns zap logger
func newZap(ctx context.Context, cfg Config) *Zap {
	var logger *zap.Logger

	if !cfg.Debug {
		cfg := zap.NewProductionConfig()
		logger, _ = cfg.Build(zap.AddCallerSkip(3), zap.AddStacktrace(zap.WarnLevel))
	} else {
		cfg := zap.NewDevelopmentConfig()
		cfg.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
		logger, _ = cfg.Build(zap.AddCallerSkip(3), zap.AddStacktrace(zap.WarnLevel))
	}

	go func(logger *zap.Logger) {
		<-ctx.Done()
		_ = logger.Sync()
	}(logger)

	return &Zap{ctx: ctx, cfg: cfg, logger: logger.Sugar()}
}


================================================
FILE: app/provider/provider.go
================================================
package provider

import (
	"github.com/aristat/golang-example-app/app/casbin"
	"github.com/aristat/golang-example-app/app/config"
	"github.com/aristat/golang-example-app/app/entrypoint"
	"github.com/aristat/golang-example-app/app/grpc"
	"github.com/aristat/golang-example-app/app/logger"
	"github.com/aristat/golang-example-app/app/tracing"
	"github.com/google/wire"
)

var AwareProductionSet = wire.NewSet(
	entrypoint.ProviderProductionSet,
	logger.ProviderProductionSet,
	config.ProviderSet,
	tracing.ProviderProductionSet,
	grpc.ProviderProductionSet,
	casbin.ProviderProductionSet,
)

var AwareTestSet = wire.NewSet(
	entrypoint.ProviderTestSet,
	logger.ProviderTestSet,
	tracing.ProviderTestSet,
	grpc.ProviderTestSet,
	casbin.ProviderTestSet,
)


================================================
FILE: app/tracing/jaeger.go
================================================
package tracing

import (
	"context"

	"go.opentelemetry.io/otel/exporters/jaeger"
	"go.opentelemetry.io/otel/sdk/resource"
	tracesdk "go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.4.0"

	"github.com/aristat/golang-example-app/app/logger"
	"github.com/pkg/errors"
)

type Configuration struct {
	AgentHost   string
	AgentPort   string
	ServiceName string
}

const prefix = "app.tracer"

func newJaegerTracer(ctx context.Context, configuration *Configuration, log logger.Logger) (*tracesdk.TracerProvider, error) {
	log = log.WithFields(logger.Fields{"service": prefix})

	exp, err := jaeger.New(
		jaeger.WithAgentEndpoint(
			jaeger.WithAgentHost(configuration.AgentHost),
			jaeger.WithAgentPort(configuration.AgentPort),
		),
	)
	if err != nil {
		return nil, errors.WithMessage(err, prefix)
	}

	tracer := tracesdk.NewTracerProvider(
		tracesdk.WithBatcher(exp),
		tracesdk.WithResource(resource.NewWithAttributes(
			semconv.SchemaURL,
			semconv.ServiceNameKey.String(configuration.ServiceName),
		)),
	)

	go func() {
		<-ctx.Done()
		if err := tracer.Shutdown(ctx); err != nil {
			log.Printf("Error shutting down tracer provider: %v", err)
		}
	}()

	return tracer, errors.WithMessage(err, prefix)
}


================================================
FILE: app/tracing/provider.go
================================================
package tracing

import (
	"context"

	"go.opentelemetry.io/otel/propagation"

	"github.com/google/wire"
	"github.com/spf13/viper"

	tracesdk "go.opentelemetry.io/otel/sdk/trace"

	"go.opentelemetry.io/otel"

	"github.com/aristat/golang-example-app/app/logger"
)

// Cfg
func Cfg(cfg *viper.Viper) (*Configuration, func(), error) {
	c := Configuration{}
	e := cfg.UnmarshalKey("tracing.jaeger", &c)
	if e != nil {
		return nil, func() {}, e
	}
	return &c, func() {}, nil
}

// Provider
func Provider(ctx context.Context, configuration *Configuration, log logger.Logger) (*tracesdk.TracerProvider, func(), error) {
	t, e := newJaegerTracer(ctx, configuration, log)
	otel.SetTracerProvider(t)
	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
	return t, func() {}, e
}

// ProviderTest
func ProviderTest() (*tracesdk.TracerProvider, func(), error) {
	m := tracesdk.NewTracerProvider()
	return m, func() {}, nil
}

var (
	ProviderProductionSet = wire.NewSet(Provider, Cfg)
	ProviderTestSet       = wire.NewSet(ProviderTest)
)


================================================
FILE: cmd/daemon/daemon.go
================================================
package daemon

import (
	"context"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"

	"github.com/aristat/golang-example-app/app/entrypoint"
	"github.com/aristat/golang-example-app/app/http"
	"github.com/aristat/golang-example-app/app/logger"

	"github.com/spf13/cobra"
)

var (
	bind          string
	gracefulDelay time.Duration
	Cmd           = &cobra.Command{
		Use:           "daemon",
		Short:         "Gateway API daemon",
		SilenceUsage:  true,
		SilenceErrors: true,
		Run: func(_ *cobra.Command, _ []string) {
			var (
				e error
				s *http.Http
				c func()
			)

			log, c, e := logger.Build()
			if e != nil {
				panic(e)
			}
			defer c()
			defer func() {
				if r := recover(); r != nil {
					if re, _ := r.(error); re != nil {
						log.Error(re.Error())
					} else {
						log.Alert("unhandled panic, err: %v", logger.Args(r))
					}
				}
			}()

			s, c, e = http.Build()
			if e != nil {
				log.Error(e.Error())
				return
			}
			defer c()

			wg := &sync.WaitGroup{}
			wg.Add(1)

			server := s.ListenAndServe(wg, bind)

			shutdownSignal := make(chan os.Signal)
			signal.Notify(shutdownSignal, syscall.SIGTERM, syscall.SIGINT)
			sig := <-shutdownSignal
			log.Printf("OS signaled `%v`\n", sig.String())

			log.Info("Server shutdown is raised")
			if e := server.Shutdown(context.Background()); e != nil {
				log.Emergency("Graceful shutdown error, %v", logger.Args(e))
			}

			wg.Wait()

			log.Printf("Graceful shutdown in %s\n", gracefulDelay)
			ctx, _ := context.WithTimeout(context.Background(), gracefulDelay)
			entrypoint.Shutdown(ctx, 0)
		},
	}
)

func init() {
	Cmd.PersistentFlags().StringVarP(&bind, "bind", "b", ":9096", "bind address")
	Cmd.PersistentFlags().DurationVar(&gracefulDelay, "graceful.delay", 50*time.Millisecond, "graceful delay")
}


================================================
FILE: cmd/health-check-service/health_check_service.go
================================================
package health_check_service

import (
	"context"
	"log"
	"math/rand"
	"net"
	"time"

	"go.opentelemetry.io/otel/propagation"

	"go.opentelemetry.io/otel"

	"github.com/aristat/golang-example-app/app/config"

	"github.com/aristat/golang-example-app/app/logger"

	"github.com/aristat/golang-example-app/app/common"

	"github.com/aristat/golang-example-app/generated/resources/proto/health_checks"
	"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
	emptypb "google.golang.org/protobuf/types/known/emptypb"

	"github.com/spf13/cobra"
	"google.golang.org/grpc"
)

// Config
type Config struct {
	Port          string
	RandomDisable bool
}

type server struct {
	cfg Config
	health_checks.UnimplementedHealthChecksServer
}

func (s *server) IsAlive(ctx context.Context, empty *emptypb.Empty) (*health_checks.IsAliveOut, error) {
	if s.cfg.RandomDisable {
		return &health_checks.IsAliveOut{Status: health_checks.IsAliveOut_OK}, nil
	}

	var status health_checks.IsAliveOut_Status

	rand.Seed(time.Now().UTC().UnixNano())
	number := rand.Intn(2-0) + 0

	if number == 1 {
		status = health_checks.IsAliveOut_OK
	} else {
		status = health_checks.IsAliveOut_NOT_OK
	}

	return &health_checks.IsAliveOut{Status: status}, nil
}

// Example service, which need for testing jaeger and grpc pool
var (
	//bind string
	Cmd = &cobra.Command{
		Use:           "health-check",
		Short:         "Health check",
		SilenceUsage:  true,
		SilenceErrors: true,
		Run: func(_ *cobra.Command, _ []string) {
			conf, c, e := config.Build()
			if e != nil {
				panic(e)
			}
			defer c()

			clientConfig := Config{}
			e = conf.UnmarshalKey("services.healthCheckService", &clientConfig)
			if e != nil {
				log.Fatal("Config initialize error")
			}

			log, c, e := logger.Build()
			if e != nil {
				panic(e)
			}
			defer c()

			defer func() {
				if r := recover(); r != nil {
					if re, _ := r.(error); re != nil {
						log.Error(re.Error())
					} else {
						log.Alert("unhandled panic, err: %v", logger.Args(r))
					}
				}
			}()

			tracer, e := common.GenerateTracerForTestClient("golang-example-app-health-check-service", conf)
			otel.SetTracerProvider(tracer)

			if e != nil {
				panic(e)
			}

			defer func() {
				if err := tracer.Shutdown(context.Background()); err != nil {
					log.Printf("Error shutting down tracer provider: %v", err)
				}
			}()

			lis, err := net.Listen("tcp", ":"+clientConfig.Port)
			if err != nil {
				panic(err)
			}

			s := grpc.NewServer(
				grpc.ChainUnaryInterceptor(
					logger.UnaryServerInterceptor(log, true),
					otelgrpc.UnaryServerInterceptor(otelgrpc.WithTracerProvider(tracer), otelgrpc.WithPropagators(propagation.TraceContext{})),
				),
				grpc.ChainStreamInterceptor(
					logger.StreamServerInterceptor(log, true),
					otelgrpc.StreamServerInterceptor(otelgrpc.WithTracerProvider(tracer), otelgrpc.WithPropagators(propagation.TraceContext{})),
				),
			)
			health_checks.RegisterHealthChecksServer(s, &server{cfg: clientConfig})
			if err := s.Serve(lis); err != nil {
				panic(err)
			}
		},
	}
)

func init() {
}


================================================
FILE: cmd/jwt/jwt.go
================================================
package jwt

import "github.com/spf13/cobra"

var Cmd = &cobra.Command{
	Use:           "jwt",
	Short:         "Tools for generate JWT",
	SilenceUsage:  true,
	SilenceErrors: true,
}

func init() {
	Cmd.AddCommand(tokenCmd)
}


================================================
FILE: cmd/jwt/token.go
================================================
package jwt

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"time"

	"github.com/spf13/cast"

	"github.com/golang-jwt/jwt"
	"github.com/spf13/cobra"
)

var (
	jwtFlagPrivateKey string
	jwtFlagFields     string
)

func init() {
	tokenCmd.PersistentFlags().StringVar(&jwtFlagPrivateKey, "key", "", "private key")
	tokenCmd.PersistentFlags().StringVar(&jwtFlagFields, "fields", "", "JWT fields in JSON format")
}

var tokenCmd = &cobra.Command{
	Use:           "token",
	Short:         "Generate JWT token with sign",
	Example:       `jwt --key='{path to private key}' --fields='{in json format {"key":"value"} }'`,
	SilenceUsage:  true,
	SilenceErrors: true,
	Run: func(cmd *cobra.Command, args []string) {

		if jwtFlagPrivateKey == "" {
			fmt.Printf("Flag `key` is required\n")
			os.Exit(1)
		}

		privatePemKey, err := ioutil.ReadFile(jwtFlagPrivateKey)

		if err != nil {

			fmt.Printf("Error occurred: %v\n", err.Error())
			os.Exit(1)
		}

		fields := make(map[string]interface{})

		if jwtFlagFields != "" {

			if err = json.Unmarshal([]byte(jwtFlagFields), &fields); err != nil {

				fmt.Printf("Parse fields error %v\n", err.Error())
				os.Exit(1)
			}
		}

		jwtEncoded, err := GenerateJWT(privatePemKey, fields)

		if err != nil {

			fmt.Printf("Error occurred: %v\n", err.Error())
			os.Exit(1)
		}

		fmt.Println(jwtEncoded)
	},
}

// GenerateJWT returns token signed by private key with filled fields
func GenerateJWT(privateKey []byte, fields map[string]interface{}) (string, error) {

	type CustomClaims struct {
		UserId int64 `json:"user_id,omitempty"`
		jwt.StandardClaims
	}

	claims := &CustomClaims{}

	for k, v := range fields {
		switch k {
		case "aud":
			claims.Audience = cast.ToString(v)
		case "sub":
			claims.Subject = cast.ToString(v)
		case "iss":
			claims.Issuer = cast.ToString(v)
		case "id":
			claims.Id = cast.ToString(v)
		case "exp":
			claims.ExpiresAt = cast.ToInt64(v)
		case "user_id":
			claims.UserId = cast.ToInt64(v)
		case "nbf":
			claims.NotBefore = cast.ToInt64(v)
		case "iat":
			claims.IssuedAt = time.Now().Unix()
		}
	}

	var (
		sPrivateKey interface{}
		err         error
	)

	sPrivateKey, err = jwt.ParseRSAPrivateKeyFromPEM(privateKey)
	if err != nil {
		return "", err
	}

	token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
	ss, err := token.SignedString(sPrivateKey)

	if err != nil {

		return "", err
	}
	return ss, nil
}


================================================
FILE: cmd/migrate/migrate.go
================================================
package migrate

import (
	"database/sql"
	"fmt"
	"os"

	"github.com/aristat/golang-example-app/app/entrypoint"
	_ "github.com/lib/pq"
	migrate "github.com/rubenv/sql-migrate"
	"github.com/spf13/cobra"
)

var (
	argDsn, argTable string
	argLimit         int
	db               *sql.DB
	ms               *migrate.FileMigrationSource
	initCmdFn        = func(cmd *cobra.Command, _ []string) (re error) {
		var e error
		defer func() {
			recover()
			re = e
		}()
		ms = &migrate.FileMigrationSource{
			Dir: entrypoint.WorkDir() + "/migrations",
		}
		migrate.SetTable(argTable)
		db, e = sql.Open("postgres", argDsn)
		if e != nil {
			return e
		}
		return nil
	}
	cmdUp = &cobra.Command{
		Use:           "up",
		Short:         "Migrates the database to the most recent version available",
		SilenceUsage:  true,
		SilenceErrors: true,
		Run: func(_ *cobra.Command, _ []string) {
			if e := initCmdFn(nil, nil); e != nil {
				fmt.Printf("Failed: %v\n", e.Error())
				os.Exit(1)
			}
			n, err := migrate.ExecMax(db, "postgres", ms, migrate.Up, argLimit)
			if err != nil {
				fmt.Printf("Failed: %v\n", err.Error())
				os.Exit(1)
			}
			fmt.Printf("Applied %d migrations!\n", n)
		},
	}
	cmdDown = &cobra.Command{
		Use:           "down",
		Short:         "Rollback a database migration",
		SilenceUsage:  true,
		SilenceErrors: true,
		Run: func(_ *cobra.Command, _ []string) {
			if e := initCmdFn(nil, nil); e != nil {
				fmt.Printf("Failed: %v\n", e.Error())
				os.Exit(1)
			}
			n, err := migrate.ExecMax(db, "postgres", ms, migrate.Down, argLimit)
			if err != nil {
				fmt.Printf("Failed: %v\n", err.Error())
				os.Exit(1)
			}
			fmt.Printf("Applied %d migrations!\n", n)
		},
	}
	Cmd = &cobra.Command{
		Use:           "migrate",
		Short:         "SQL migration tool",
		SilenceUsage:  true,
		SilenceErrors: true,
	}
)

func init() {
	Cmd.PersistentFlags().StringVar(&argTable, "table", "migrations", "Table for migration history")
	Cmd.PersistentFlags().IntVar(&argLimit, "limit", 1, "Limit the number of migrations (0 = unlimited)")
	Cmd.PersistentFlags().StringVar(&argDsn, "dsn", "postgres://localhost:5432/golang_example_development?sslmode=disable", "DSN connection string")
	Cmd.AddCommand(cmdUp, cmdDown)
}


================================================
FILE: cmd/product-service/nats_service.go
================================================
package product_service

import (
	"github.com/aristat/golang-example-app/app/logger"
	"github.com/nats-io/stan.go"
)

type natsService struct {
	logger logger.Logger
}

func (s *natsService) workerHanlder(m *stan.Msg) {
	s.logger.Info("[NATS] Received a message: %s\n", logger.Args(string(m.Data)))
	m.Ack()
}


================================================
FILE: cmd/product-service/product_service.go
================================================
package product_service

import (
	"context"
	"errors"
	"log"
	"net"
	"time"

	"go.opentelemetry.io/otel/propagation"

	"google.golang.org/grpc/credentials/insecure"

	"go.opentelemetry.io/otel"

	"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"

	"github.com/nats-io/nats.go"
	"github.com/nats-io/stan.go"

	"github.com/aristat/golang-example-app/app/config"

	"github.com/aristat/golang-example-app/app/common"
	"github.com/aristat/golang-example-app/app/logger"

	"github.com/aristat/golang-example-app/generated/resources/proto/health_checks"
	"github.com/aristat/golang-example-app/generated/resources/proto/products"
	emptypb "google.golang.org/protobuf/types/known/emptypb"

	"github.com/spf13/cobra"
	"google.golang.org/grpc"
)

// Config
type Config struct {
	Port           string
	HealthCheckUrl string
	NatsURL        string
	Subject        string
}

type server struct {
	logger logger.Logger
	cfg    Config
	products.UnimplementedProductsServer
}

func (s *server) ListProduct(ctx context.Context, in *products.ListProductIn) (*products.ListProductOut, error) {
	tracer := otel.GetTracerProvider()

	conn, err := grpc.Dial(s.cfg.HealthCheckUrl,
		grpc.WithTransportCredentials(insecure.NewCredentials()),
		grpc.WithChainUnaryInterceptor(
			logger.UnaryClientInterceptor(s.logger, true),
			otelgrpc.UnaryClientInterceptor(otelgrpc.WithTracerProvider(tracer), otelgrpc.WithPropagators(propagation.TraceContext{})),
		),
		grpc.WithChainStreamInterceptor(
			logger.StreamClientInterceptor(s.logger, true),
			otelgrpc.StreamClientInterceptor(otelgrpc.WithTracerProvider(tracer), otelgrpc.WithPropagators(propagation.TraceContext{})),
		),
	)

	if err != nil {
		return nil, err
	}
	defer conn.Close()
	c := health_checks.NewHealthChecksClient(conn)

	ctx, cancel := context.WithTimeout(ctx, time.Second)
	defer cancel()
	isAliveOut, err := c.IsAlive(ctx, &emptypb.Empty{})
	if err != nil {
		return nil, err
	}

	if isAliveOut.Status != health_checks.IsAliveOut_OK {
		return nil, errors.New("Heal checks not working")
	}

	// test result
	out := &products.ListProductOut{Status: products.ListProductOut_OK, Products: []*products.Product{}}
	out.Products = append(out.Products, &products.Product{Id: 1, Name: "first_product"})
	out.Products = append(out.Products, &products.Product{Id: 2, Name: "second_product"})

	return out, nil
}

// Example service, which gives some data
var (
	//bind string
	Cmd = &cobra.Command{
		Use:           "product-service",
		Short:         "Product service",
		SilenceUsage:  true,
		SilenceErrors: true,
		Run: func(_ *cobra.Command, _ []string) {
			conf, c, e := config.Build()
			if e != nil {
				panic(e)
			}
			defer c()

			clientConfig := Config{}
			e = conf.UnmarshalKey("services.productService", &clientConfig)
			if e != nil {
				log.Fatal("Config initialize error")
			}

			log, c, e := logger.Build()
			if e != nil {
				panic(e)
			}
			defer c()

			defer func() {
				if r := recover(); r != nil {
					if re, _ := r.(error); re != nil {
						log.Error(re.Error())
					} else {
						log.Alert("unhandled panic, err: %v", logger.Args(r))
					}
				}
			}()

			tracer, e := common.GenerateTracerForTestClient("golang-example-app-product-service", conf)
			otel.SetTracerProvider(tracer)

			if e != nil {
				panic(e)
			}

			defer func() {
				if err := tracer.Shutdown(context.Background()); err != nil {
					log.Printf("Error shutting down tracer provider: %v", err)
				}
			}()

			log.Info("Start product service %s", logger.Args(clientConfig.Port))
			lis, err := net.Listen("tcp", ":"+clientConfig.Port)
			if err != nil {
				panic(err)
			}

			nc, err := nats.Connect(clientConfig.NatsURL)
			if err != nil {
				log.Error(err.Error())
				panic(err)
			}
			defer nc.Close()

			sc, _ := stan.Connect("test-cluster", "example-subscriber", stan.NatsConn(nc))
			natsService := natsService{logger: log}
			_, err = sc.QueueSubscribe(clientConfig.Subject, "worker", natsService.workerHanlder, stan.DurableName("i-will-remember"), stan.MaxInflight(1), stan.SetManualAckMode())

			if err != nil {
				sc.Close()
				log.Error(err.Error())
				panic(err)
			}

			s := grpc.NewServer(
				grpc.ChainUnaryInterceptor(
					logger.UnaryServerInterceptor(log, true),
					otelgrpc.UnaryServerInterceptor(otelgrpc.WithTracerProvider(tracer), otelgrpc.WithPropagators(propagation.TraceContext{})),
				),
				grpc.ChainStreamInterceptor(
					logger.StreamServerInterceptor(log, true),
					otelgrpc.StreamServerInterceptor(otelgrpc.WithTracerProvider(tracer), otelgrpc.WithPropagators(propagation.TraceContext{})),
				),
			)
			products.RegisterProductsServer(s, &server{logger: log, cfg: clientConfig})

			if err := s.Serve(lis); err != nil {
				panic(err)
			}
		},
	}
)

func init() {
}


================================================
FILE: cmd/root.go
================================================
package cmd

import (
	"bytes"
	"encoding/json"
	"fmt"
	"os"
	"os/signal"
	"path/filepath"
	"strings"
	"syscall"

	"github.com/aristat/golang-example-app/cmd/jwt"

	"github.com/aristat/golang-example-app/cmd/migrate"

	health_check_service "github.com/aristat/golang-example-app/cmd/health-check-service"
	product_service "github.com/aristat/golang-example-app/cmd/product-service"

	"github.com/aristat/golang-example-app/app/entrypoint"
	"github.com/aristat/golang-example-app/app/logger"

	"go.uber.org/automaxprocs/maxprocs"

	"github.com/aristat/golang-example-app/cmd/daemon"

	"github.com/pkg/errors"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
)

var (
	configPath string
	debug      bool
	v          *viper.Viper
	log        logger.Logger
)

const prefix = "cmd.root"

// Root command
var rootCmd = &cobra.Command{
	Use:           "bin [command]",
	Long:          "",
	SilenceUsage:  true,
	SilenceErrors: true,
	PersistentPreRun: func(cmd *cobra.Command, _ []string) {
		l, c, e := logger.Build()
		defer c()
		if e != nil {
			panic(e)
		}

		log = l.WithFields(logger.Fields{"service": prefix})

		v.SetConfigFile(configPath)

		if configPath != "" {
			e := v.ReadInConfig()
			if e != nil {
				log.Error("can't read config, %v", logger.Args(errors.WithMessage(e, prefix)))
				os.Exit(1)
			}
		}

		if debug {
			b, _ := json.Marshal(v.AllSettings())
			var out bytes.Buffer
			e := json.Indent(&out, b, "", "  ")
			if e != nil {
				log.Error("can't prettify config")
				os.Exit(1)
			}
			fmt.Println(string(out.Bytes()))
		}

		_, _ = maxprocs.Set(maxprocs.Logger(log.Printf))
	},
}

func init() {
	v = viper.New()
	v.SetConfigType("yaml")
	v.SetEnvPrefix("APP")
	v.SetEnvKeyReplacer(strings.NewReplacer("-", "_", ".", "_"))
	v.AutomaticEnv()

	// pflags
	rootCmd.PersistentFlags().StringVarP(&configPath, "config", "c", "", "config file")
	rootCmd.PersistentFlags().BoolVarP(&debug, "debug", "d", false, "debug mode")

	// initializing
	wd := os.Getenv("APP_WD")
	if len(wd) == 0 {
		wd, _ = filepath.Abs(filepath.Dir(os.Args[0]))
	}
	wd, _ = filepath.Abs(wd)
	ep, _ := entrypoint.Initialize(wd, v)

	// bin pflags to viper
	_ = v.BindPFlags(rootCmd.PersistentFlags())

	go func() {
		reloadSignal := make(chan os.Signal)
		signal.Notify(reloadSignal, syscall.SIGHUP)
		for {
			sig := <-reloadSignal
			ep.Reload()
			fmt.Printf("OS signaled `%v`, reload", sig.String())
		}
	}()
}

func Execute() {
	rootCmd.AddCommand(daemon.Cmd, product_service.Cmd, health_check_service.Cmd, migrate.Cmd, jwt.Cmd)
	if e := rootCmd.Execute(); e != nil {
		_, _ = fmt.Fprintf(os.Stderr, "%v\n", e.Error())
		os.Exit(1)
	}
}


================================================
FILE: dbconfig.yml
================================================
development:
    dialect: postgres
    datasource: dbname=golang_example_development sslmode=disable
    dir: resources/migrations
    table: migrations


================================================
FILE: docker/app/Dockerfile
================================================
FROM golang:1.17.9-alpine3.15 as builder

RUN apk add --update make \
    && rm -rf /tmp/* \
    && rm -rf /var/cache/apk/*

RUN mkdir /build
WORKDIR /build

COPY . .

RUN GOOS=linux GOARCH=amd64 make build

FROM alpine:3.9

COPY --from=builder /build/docker/app/files /
COPY --from=builder /build/artifacts /app/

WORKDIR /app

RUN apk --no-cache add tzdata bash \
    && chmod +x /docker/bin/* \
    && chmod +x bin \
    && rm -rf /tmp/* \
    && rm -rf /var/cache/apk/*

ENTRYPOINT ["/docker/bin/entrypoint.sh"]


================================================
FILE: docker/app/files/docker/bin/entrypoint.sh
================================================
#!/usr/bin/env sh

exec ./bin "$@"


================================================
FILE: docker-compose.yml
================================================
version: '3.7'
services:
  jaeger:
    image: jaegertracing/all-in-one:latest
    networks:
      - intranet
    ports:
      - "5775:5775/udp"
      - "6831:6831/udp"
      - "6832:6832/udp"
      - "5778:5778"
      - "16686:16686"
      - "14268:14268"
      - "9411:9411"

  #=============================#

  # check migration before start
  daemon-migrate:
    image: golang-example-app:development
    depends_on:
      - postgres
    networks:
      - intranet
    command:
      migrate up --dsn=postgres://postgres@postgres:5432/golang_example_development?sslmode=disable --limit=0

  daemon:
    image: golang-example-app:development
    command: daemon -c ./configs/docker_development.yaml -d
    depends_on:
      - product_service
      - health_check_service
      - daemon-migrate
      - postgres
      - redis
      - nats-streaming
    networks:
      - intranet
    ports:
      - "9096:9096"

  #=============================#

  product_service:
    image: golang-example-app:development
    command: product-service -c ./configs/docker_development.yaml -d
    depends_on:
      - postgres
    networks:
      - intranet
    ports:
      - "50051:50051"

  #=============================#

  health_check_service:
    image: golang-example-app:development
    command: health-check -c ./configs/docker_development.yaml -d
    networks:
      - intranet
    ports:
      - "50052:50052"

  #=============================#

  postgres:
    image: postgres:9.6
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_DB=golang_example_development
      - POSTGRES_HOST_AUTH_METHOD=trust
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5532:5432"
    networks:
      - intranet

  redis:
    image: redis:latest
    volumes:
      - redis_data:/data
    networks:
      - intranet

  nats-streaming:
    image: nats-streaming
    ports:
      - "8222:8222"
      - "4222:4222"
    networks:
      - intranet

networks:
  intranet:
    driver: bridge

volumes:
  postgres_data:
  redis_data:


================================================
FILE: generated/graphql/generated.go
================================================
// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.

package graphql

import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"strconv"
	"sync"
	"sync/atomic"

	"github.com/99designs/gqlgen/graphql"
	"github.com/99designs/gqlgen/graphql/introspection"
	"github.com/aristat/golang-example-app/app/db/domain"
	gqlparser "github.com/vektah/gqlparser/v2"
	"github.com/vektah/gqlparser/v2/ast"
)

// region    ************************** generated!.gotpl **************************

// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface.
func NewExecutableSchema(cfg Config) graphql.ExecutableSchema {
	return &executableSchema{
		resolvers:  cfg.Resolvers,
		directives: cfg.Directives,
		complexity: cfg.Complexity,
	}
}

type Config struct {
	Resolvers  ResolverRoot
	Directives DirectiveRoot
	Complexity ComplexityRoot
}

type ResolverRoot interface {
	Mutation() MutationResolver
	Product() ProductResolver
	ProductsQuery() ProductsQueryResolver
	Query() QueryResolver
	UsersMutation() UsersMutationResolver
	UsersQuery() UsersQueryResolver
}

type DirectiveRoot struct {
	HasUsersPermission func(ctx context.Context, obj interface{}, next graphql.Resolver, permission UsersPermissionEnum) (res interface{}, err error)
}

type ComplexityRoot struct {
	Mutation struct {
		Users func(childComplexity int) int
	}

	Product struct {
		ID           func(childComplexity int) int
		Name         func(childComplexity int) int
		ProductItems func(childComplexity int) int
	}

	ProductItem struct {
		ID   func(childComplexity int) int
		Name func(childComplexity int) int
	}

	ProductsListOut struct {
		Products func(childComplexity int) int
	}

	ProductsQuery struct {
		List func(childComplexity int) int
	}

	Query struct {
		Products func(childComplexity int) int
		Users    func(childComplexity int) int
	}

	UsersCreateOut struct {
		Email  func(childComplexity int) int
		ID     func(childComplexity int) int
		Status func(childComplexity int) int
	}

	UsersMutation struct {
		CreateUser func(childComplexity int, email string, password string) int
	}

	UsersOneOut struct {
		Email func(childComplexity int) int
		ID    func(childComplexity int) int
	}

	UsersQuery struct {
		One func(childComplexity int, email string) int
	}
}

type MutationResolver interface {
	Users(ctx context.Context) (*UsersMutation, error)
}
type ProductResolver interface {
	ProductItems(ctx context.Context, obj *domain.Product) ([]*domain.ProductItem, error)
}
type ProductsQueryResolver interface {
	List(ctx context.Context, obj *ProductsQuery) (*ProductsListOut, error)
}
type QueryResolver interface {
	Users(ctx context.Context) (*UsersQuery, error)
	Products(ctx context.Context) (*ProductsQuery, error)
}
type UsersMutationResolver interface {
	CreateUser(ctx context.Context, obj *UsersMutation, email string, password string) (*UsersCreateOut, error)
}
type UsersQueryResolver interface {
	One(ctx context.Context, obj *UsersQuery, email string) (*UsersOneOut, error)
}

type executableSchema struct {
	resolvers  ResolverRoot
	directives DirectiveRoot
	complexity ComplexityRoot
}

func (e *executableSchema) Schema() *ast.Schema {
	return parsedSchema
}

func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) {
	ec := executionContext{nil, e}
	_ = ec
	switch typeName + "." + field {

	case "Mutation.users":
		if e.complexity.Mutation.Users == nil {
			break
		}

		return e.complexity.Mutation.Users(childComplexity), true

	case "Product.id":
		if e.complexity.Product.ID == nil {
			break
		}

		return e.complexity.Product.ID(childComplexity), true

	case "Product.name":
		if e.complexity.Product.Name == nil {
			break
		}

		return e.complexity.Product.Name(childComplexity), true

	case "Product.productItems":
		if e.complexity.Product.ProductItems == nil {
			break
		}

		return e.complexity.Product.ProductItems(childComplexity), true

	case "ProductItem.id":
		if e.complexity.ProductItem.ID == nil {
			break
		}

		return e.complexity.ProductItem.ID(childComplexity), true

	case "ProductItem.name":
		if e.complexity.ProductItem.Name == nil {
			break
		}

		return e.complexity.ProductItem.Name(childComplexity), true

	case "ProductsListOut.products":
		if e.complexity.ProductsListOut.Products == nil {
			break
		}

		return e.complexity.ProductsListOut.Products(childComplexity), true

	case "ProductsQuery.list":
		if e.complexity.ProductsQuery.List == nil {
			break
		}

		return e.complexity.ProductsQuery.List(childComplexity), true

	case "Query.products":
		if e.complexity.Query.Products == nil {
			break
		}

		return e.complexity.Query.Products(childComplexity), true

	case "Query.users":
		if e.complexity.Query.Users == nil {
			break
		}

		return e.complexity.Query.Users(childComplexity), true

	case "UsersCreateOut.email":
		if e.complexity.UsersCreateOut.Email == nil {
			break
		}

		return e.complexity.UsersCreateOut.Email(childComplexity), true

	case "UsersCreateOut.id":
		if e.complexity.UsersCreateOut.ID == nil {
			break
		}

		return e.complexity.UsersCreateOut.ID(childComplexity), true

	case "UsersCreateOut.status":
		if e.complexity.UsersCreateOut.Status == nil {
			break
		}

		return e.complexity.UsersCreateOut.Status(childComplexity), true

	case "UsersMutation.createUser":
		if e.complexity.UsersMutation.CreateUser == nil {
			break
		}

		args, err := ec.field_UsersMutation_createUser_args(context.TODO(), rawArgs)
		if err != nil {
			return 0, false
		}

		return e.complexity.UsersMutation.CreateUser(childComplexity, args["email"].(string), args["password"].(string)), true

	case "UsersOneOut.email":
		if e.complexity.UsersOneOut.Email == nil {
			break
		}

		return e.complexity.UsersOneOut.Email(childComplexity), true

	case "UsersOneOut.id":
		if e.complexity.UsersOneOut.ID == nil {
			break
		}

		return e.complexity.UsersOneOut.ID(childComplexity), true

	case "UsersQuery.one":
		if e.complexity.UsersQuery.One == nil {
			break
		}

		args, err := ec.field_UsersQuery_one_args(context.TODO(), rawArgs)
		if err != nil {
			return 0, false
		}

		return e.complexity.UsersQuery.One(childComplexity, args["email"].(string)), true

	}
	return 0, false
}

func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
	rc := graphql.GetOperationContext(ctx)
	ec := executionContext{rc, e}
	first := true

	switch rc.Operation.Operation {
	case ast.Query:
		return func(ctx context.Context) *graphql.Response {
			if !first {
				return nil
			}
			first = false
			data := ec._Query(ctx, rc.Operation.SelectionSet)
			var buf bytes.Buffer
			data.MarshalGQL(&buf)

			return &graphql.Response{
				Data: buf.Bytes(),
			}
		}
	case ast.Mutation:
		return func(ctx context.Context) *graphql.Response {
			if !first {
				return nil
			}
			first = false
			data := ec._Mutation(ctx, rc.Operation.SelectionSet)
			var buf bytes.Buffer
			data.MarshalGQL(&buf)

			return &graphql.Response{
				Data: buf.Bytes(),
			}
		}

	default:
		return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation"))
	}
}

type executionContext struct {
	*graphql.OperationContext
	*executableSchema
}

func (ec *executionContext) introspectSchema() (*introspection.Schema, error) {
	if ec.DisableIntrospection {
		return nil, errors.New("introspection disabled")
	}
	return introspection.WrapSchema(parsedSchema), nil
}

func (ec *executionContext) introspectType(name string) (*introspection.Type, error) {
	if ec.DisableIntrospection {
		return nil, errors.New("introspection disabled")
	}
	return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil
}

var sources = []*ast.Source{
	{Name: "resources/graphql/products.graphql", Input: `type ProductsQuery {
    list: ProductsListOut!
}

type Product {
    id: ID!
    name: String!
    productItems: [ProductItem!]!
}

type ProductItem {
    id: ID!
    name: String!
}

type ProductsListOut {
    products: [Product!]!
}
`, BuiltIn: false},
	{Name: "resources/graphql/root.graphql", Input: `type Query {
    users: UsersQuery
    products: ProductsQuery
}

type Mutation {
    users: UsersMutation
}
`, BuiltIn: false},
	{Name: "resources/graphql/user.graphql", Input: `type UsersOneOut {
    id: ID!
    email: String!
}

type UsersQuery {
    one(email: String!): UsersOneOut! @hasUsersPermission(permission: READ)
}

type UsersMutation {
    createUser(email: String!, password: String!): UsersCreateOut! @hasUsersPermission(permission: WRITE)
}

type UsersCreateOut {
    status: UsersCreateOutStatus!
    id: ID!
    email: String!
}

enum UsersCreateOutStatus {
    OK
    BAD_REQUEST
    SERVER_INTERNAL_ERROR
}

directive @hasUsersPermission(permission: UsersPermissionEnum!) on FIELD_DEFINITION

enum UsersPermissionEnum {
    READ
    WRITE
}
`, BuiltIn: false},
}
var parsedSchema = gqlparser.MustLoadSchema(sources...)

// endregion ************************** generated!.gotpl **************************

// region    ***************************** args.gotpl *****************************

func (ec *executionContext) dir_hasUsersPermission_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
	var err error
	args := map[string]interface{}{}
	var arg0 UsersPermissionEnum
	if tmp, ok := rawArgs["permission"]; ok {
		ctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField("permission"))
		arg0, err = ec.unmarshalNUsersPermissionEnum2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersPermissionEnum(ctx, tmp)
		if err != nil {
			return nil, err
		}
	}
	args["permission"] = arg0
	return args, nil
}

func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
	var err error
	args := map[string]interface{}{}
	var arg0 string
	if tmp, ok := rawArgs["name"]; ok {
		ctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField("name"))
		arg0, err = ec.unmarshalNString2string(ctx, tmp)
		if err != nil {
			return nil, err
		}
	}
	args["name"] = arg0
	return args, nil
}

func (ec *executionContext) field_UsersMutation_createUser_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
	var err error
	args := map[string]interface{}{}
	var arg0 string
	if tmp, ok := rawArgs["email"]; ok {
		ctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField("email"))
		arg0, err = ec.unmarshalNString2string(ctx, tmp)
		if err != nil {
			return nil, err
		}
	}
	args["email"] = arg0
	var arg1 string
	if tmp, ok := rawArgs["password"]; ok {
		ctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField("password"))
		arg1, err = ec.unmarshalNString2string(ctx, tmp)
		if err != nil {
			return nil, err
		}
	}
	args["password"] = arg1
	return args, nil
}

func (ec *executionContext) field_UsersQuery_one_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
	var err error
	args := map[string]interface{}{}
	var arg0 string
	if tmp, ok := rawArgs["email"]; ok {
		ctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField("email"))
		arg0, err = ec.unmarshalNString2string(ctx, tmp)
		if err != nil {
			return nil, err
		}
	}
	args["email"] = arg0
	return args, nil
}

func (ec *executionContext) field___Type_enumValues_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
	var err error
	args := map[string]interface{}{}
	var arg0 bool
	if tmp, ok := rawArgs["includeDeprecated"]; ok {
		ctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField("includeDeprecated"))
		arg0, err = ec.unmarshalOBoolean2bool(ctx, tmp)
		if err != nil {
			return nil, err
		}
	}
	args["includeDeprecated"] = arg0
	return args, nil
}

func (ec *executionContext) field___Type_fields_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
	var err error
	args := map[string]interface{}{}
	var arg0 bool
	if tmp, ok := rawArgs["includeDeprecated"]; ok {
		ctx := graphql.WithFieldInputContext(ctx, graphql.NewFieldInputWithField("includeDeprecated"))
		arg0, err = ec.unmarshalOBoolean2bool(ctx, tmp)
		if err != nil {
			return nil, err
		}
	}
	args["includeDeprecated"] = arg0
	return args, nil
}

// endregion ***************************** args.gotpl *****************************

// region    ************************** directives.gotpl **************************

// endregion ************************** directives.gotpl **************************

// region    **************************** field.gotpl *****************************

func (ec *executionContext) _Mutation_users(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "Mutation",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return ec.resolvers.Mutation().Users(rctx)
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		return graphql.Null
	}
	res := resTmp.(*UsersMutation)
	fc.Result = res
	return ec.marshalOUsersMutation2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersMutation(ctx, field.Selections, res)
}

func (ec *executionContext) _Product_id(ctx context.Context, field graphql.CollectedField, obj *domain.Product) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "Product",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.ID, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(int)
	fc.Result = res
	return ec.marshalNID2int(ctx, field.Selections, res)
}

func (ec *executionContext) _Product_name(ctx context.Context, field graphql.CollectedField, obj *domain.Product) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "Product",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Name, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(string)
	fc.Result = res
	return ec.marshalNString2string(ctx, field.Selections, res)
}

func (ec *executionContext) _Product_productItems(ctx context.Context, field graphql.CollectedField, obj *domain.Product) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "Product",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return ec.resolvers.Product().ProductItems(rctx, obj)
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.([]*domain.ProductItem)
	fc.Result = res
	return ec.marshalNProductItem2ᚕᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋappᚋdbᚋdomainᚐProductItemᚄ(ctx, field.Selections, res)
}

func (ec *executionContext) _ProductItem_id(ctx context.Context, field graphql.CollectedField, obj *domain.ProductItem) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "ProductItem",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.ID, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(int)
	fc.Result = res
	return ec.marshalNID2int(ctx, field.Selections, res)
}

func (ec *executionContext) _ProductItem_name(ctx context.Context, field graphql.CollectedField, obj *domain.ProductItem) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "ProductItem",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Name, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(string)
	fc.Result = res
	return ec.marshalNString2string(ctx, field.Selections, res)
}

func (ec *executionContext) _ProductsListOut_products(ctx context.Context, field graphql.CollectedField, obj *ProductsListOut) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "ProductsListOut",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Products, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.([]*domain.Product)
	fc.Result = res
	return ec.marshalNProduct2ᚕᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋappᚋdbᚋdomainᚐProductᚄ(ctx, field.Selections, res)
}

func (ec *executionContext) _ProductsQuery_list(ctx context.Context, field graphql.CollectedField, obj *ProductsQuery) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "ProductsQuery",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return ec.resolvers.ProductsQuery().List(rctx, obj)
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(*ProductsListOut)
	fc.Result = res
	return ec.marshalNProductsListOut2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐProductsListOut(ctx, field.Selections, res)
}

func (ec *executionContext) _Query_users(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "Query",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return ec.resolvers.Query().Users(rctx)
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		return graphql.Null
	}
	res := resTmp.(*UsersQuery)
	fc.Result = res
	return ec.marshalOUsersQuery2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersQuery(ctx, field.Selections, res)
}

func (ec *executionContext) _Query_products(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "Query",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return ec.resolvers.Query().Products(rctx)
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		return graphql.Null
	}
	res := resTmp.(*ProductsQuery)
	fc.Result = res
	return ec.marshalOProductsQuery2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐProductsQuery(ctx, field.Selections, res)
}

func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "Query",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	rawArgs := field.ArgumentMap(ec.Variables)
	args, err := ec.field_Query___type_args(ctx, rawArgs)
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	fc.Args = args
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return ec.introspectType(args["name"].(string))
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		return graphql.Null
	}
	res := resTmp.(*introspection.Type)
	fc.Result = res
	return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)
}

func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "Query",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return ec.introspectSchema()
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		return graphql.Null
	}
	res := resTmp.(*introspection.Schema)
	fc.Result = res
	return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res)
}

func (ec *executionContext) _UsersCreateOut_status(ctx context.Context, field graphql.CollectedField, obj *UsersCreateOut) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "UsersCreateOut",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Status, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(UsersCreateOutStatus)
	fc.Result = res
	return ec.marshalNUsersCreateOutStatus2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersCreateOutStatus(ctx, field.Selections, res)
}

func (ec *executionContext) _UsersCreateOut_id(ctx context.Context, field graphql.CollectedField, obj *UsersCreateOut) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "UsersCreateOut",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.ID, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(string)
	fc.Result = res
	return ec.marshalNID2string(ctx, field.Selections, res)
}

func (ec *executionContext) _UsersCreateOut_email(ctx context.Context, field graphql.CollectedField, obj *UsersCreateOut) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "UsersCreateOut",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Email, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(string)
	fc.Result = res
	return ec.marshalNString2string(ctx, field.Selections, res)
}

func (ec *executionContext) _UsersMutation_createUser(ctx context.Context, field graphql.CollectedField, obj *UsersMutation) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "UsersMutation",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	rawArgs := field.ArgumentMap(ec.Variables)
	args, err := ec.field_UsersMutation_createUser_args(ctx, rawArgs)
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	fc.Args = args
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		directive0 := func(rctx context.Context) (interface{}, error) {
			ctx = rctx // use context from middleware stack in children
			return ec.resolvers.UsersMutation().CreateUser(rctx, obj, args["email"].(string), args["password"].(string))
		}
		directive1 := func(ctx context.Context) (interface{}, error) {
			permission, err := ec.unmarshalNUsersPermissionEnum2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersPermissionEnum(ctx, "WRITE")
			if err != nil {
				return nil, err
			}
			if ec.directives.HasUsersPermission == nil {
				return nil, errors.New("directive hasUsersPermission is not implemented")
			}
			return ec.directives.HasUsersPermission(ctx, obj, directive0, permission)
		}

		tmp, err := directive1(rctx)
		if err != nil {
			return nil, err
		}
		if tmp == nil {
			return nil, nil
		}
		if data, ok := tmp.(*UsersCreateOut); ok {
			return data, nil
		}
		return nil, fmt.Errorf(`unexpected type %T from directive, should be *github.com/aristat/golang-example-app/generated/graphql.UsersCreateOut`, tmp)
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(*UsersCreateOut)
	fc.Result = res
	return ec.marshalNUsersCreateOut2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersCreateOut(ctx, field.Selections, res)
}

func (ec *executionContext) _UsersOneOut_id(ctx context.Context, field graphql.CollectedField, obj *UsersOneOut) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "UsersOneOut",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.ID, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(string)
	fc.Result = res
	return ec.marshalNID2string(ctx, field.Selections, res)
}

func (ec *executionContext) _UsersOneOut_email(ctx context.Context, field graphql.CollectedField, obj *UsersOneOut) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "UsersOneOut",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Email, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(string)
	fc.Result = res
	return ec.marshalNString2string(ctx, field.Selections, res)
}

func (ec *executionContext) _UsersQuery_one(ctx context.Context, field graphql.CollectedField, obj *UsersQuery) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "UsersQuery",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	rawArgs := field.ArgumentMap(ec.Variables)
	args, err := ec.field_UsersQuery_one_args(ctx, rawArgs)
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	fc.Args = args
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		directive0 := func(rctx context.Context) (interface{}, error) {
			ctx = rctx // use context from middleware stack in children
			return ec.resolvers.UsersQuery().One(rctx, obj, args["email"].(string))
		}
		directive1 := func(ctx context.Context) (interface{}, error) {
			permission, err := ec.unmarshalNUsersPermissionEnum2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersPermissionEnum(ctx, "READ")
			if err != nil {
				return nil, err
			}
			if ec.directives.HasUsersPermission == nil {
				return nil, errors.New("directive hasUsersPermission is not implemented")
			}
			return ec.directives.HasUsersPermission(ctx, obj, directive0, permission)
		}

		tmp, err := directive1(rctx)
		if err != nil {
			return nil, err
		}
		if tmp == nil {
			return nil, nil
		}
		if data, ok := tmp.(*UsersOneOut); ok {
			return data, nil
		}
		return nil, fmt.Errorf(`unexpected type %T from directive, should be *github.com/aristat/golang-example-app/generated/graphql.UsersOneOut`, tmp)
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(*UsersOneOut)
	fc.Result = res
	return ec.marshalNUsersOneOut2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersOneOut(ctx, field.Selections, res)
}

func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Directive",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Name, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(string)
	fc.Result = res
	return ec.marshalNString2string(ctx, field.Selections, res)
}

func (ec *executionContext) ___Directive_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Directive",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Description, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		return graphql.Null
	}
	res := resTmp.(string)
	fc.Result = res
	return ec.marshalOString2string(ctx, field.Selections, res)
}

func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Directive",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Locations, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.([]string)
	fc.Result = res
	return ec.marshalN__DirectiveLocation2ᚕstringᚄ(ctx, field.Selections, res)
}

func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Directive",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Args, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.([]introspection.InputValue)
	fc.Result = res
	return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res)
}

func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__EnumValue",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Name, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(string)
	fc.Result = res
	return ec.marshalNString2string(ctx, field.Selections, res)
}

func (ec *executionContext) ___EnumValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__EnumValue",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Description, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		return graphql.Null
	}
	res := resTmp.(string)
	fc.Result = res
	return ec.marshalOString2string(ctx, field.Selections, res)
}

func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__EnumValue",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.IsDeprecated(), nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(bool)
	fc.Result = res
	return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}

func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__EnumValue",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.DeprecationReason(), nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		return graphql.Null
	}
	res := resTmp.(*string)
	fc.Result = res
	return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}

func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Field",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Name, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(string)
	fc.Result = res
	return ec.marshalNString2string(ctx, field.Selections, res)
}

func (ec *executionContext) ___Field_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Field",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Description, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		return graphql.Null
	}
	res := resTmp.(string)
	fc.Result = res
	return ec.marshalOString2string(ctx, field.Selections, res)
}

func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Field",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Args, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.([]introspection.InputValue)
	fc.Result = res
	return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res)
}

func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Field",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Type, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(*introspection.Type)
	fc.Result = res
	return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)
}

func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Field",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.IsDeprecated(), nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(bool)
	fc.Result = res
	return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}

func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Field",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.DeprecationReason(), nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		return graphql.Null
	}
	res := resTmp.(*string)
	fc.Result = res
	return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}

func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__InputValue",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Name, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(string)
	fc.Result = res
	return ec.marshalNString2string(ctx, field.Selections, res)
}

func (ec *executionContext) ___InputValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__InputValue",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Description, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		return graphql.Null
	}
	res := resTmp.(string)
	fc.Result = res
	return ec.marshalOString2string(ctx, field.Selections, res)
}

func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__InputValue",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Type, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(*introspection.Type)
	fc.Result = res
	return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)
}

func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__InputValue",
		Field:    field,
		Args:     nil,
		IsMethod: false,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.DefaultValue, nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		return graphql.Null
	}
	res := resTmp.(*string)
	fc.Result = res
	return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}

func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Schema",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Types(), nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.([]introspection.Type)
	fc.Result = res
	return ec.marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res)
}

func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Schema",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.QueryType(), nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(*introspection.Type)
	fc.Result = res
	return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)
}

func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Schema",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.MutationType(), nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		return graphql.Null
	}
	res := resTmp.(*introspection.Type)
	fc.Result = res
	return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)
}

func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Schema",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.SubscriptionType(), nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		return graphql.Null
	}
	res := resTmp.(*introspection.Type)
	fc.Result = res
	return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)
}

func (ec *executionContext) ___Schema_directives(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Schema",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Directives(), nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.([]introspection.Directive)
	fc.Result = res
	return ec.marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx, field.Selections, res)
}

func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Type",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Kind(), nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		if !graphql.HasFieldError(ctx, fc) {
			ec.Errorf(ctx, "must not be null")
		}
		return graphql.Null
	}
	res := resTmp.(string)
	fc.Result = res
	return ec.marshalN__TypeKind2string(ctx, field.Selections, res)
}

func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Type",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Name(), nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		return graphql.Null
	}
	res := resTmp.(*string)
	fc.Result = res
	return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}

func (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Type",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Description(), nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		return graphql.Null
	}
	res := resTmp.(string)
	fc.Result = res
	return ec.marshalOString2string(ctx, field.Selections, res)
}

func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Type",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	rawArgs := field.ArgumentMap(ec.Variables)
	args, err := ec.field___Type_fields_args(ctx, rawArgs)
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	fc.Args = args
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Fields(args["includeDeprecated"].(bool)), nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		return graphql.Null
	}
	res := resTmp.([]introspection.Field)
	fc.Result = res
	return ec.marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx, field.Selections, res)
}

func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Type",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Interfaces(), nil
	})
	if err != nil {
		ec.Error(ctx, err)
		return graphql.Null
	}
	if resTmp == nil {
		return graphql.Null
	}
	res := resTmp.([]introspection.Type)
	fc.Result = res
	return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res)
}

func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {
	defer func() {
		if r := recover(); r != nil {
			ec.Error(ctx, ec.Recover(ctx, r))
			ret = graphql.Null
		}
	}()
	fc := &graphql.FieldContext{
		Object:   "__Type",
		Field:    field,
		Args:     nil,
		IsMethod: true,
	}

	ctx = graphql.WithFieldContext(ctx, fc)
	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
		ctx = rctx // use context from middleware stack in children
		return obj.Pos
Download .txt
gitextract_na8wnxnj/

├── .circleci/
│   └── config.yml
├── .gitignore
├── Makefile
├── README.md
├── app/
│   ├── auth/
│   │   ├── middleware.go
│   │   └── provider.go
│   ├── casbin/
│   │   └── provider.go
│   ├── common/
│   │   ├── bcrypt.go
│   │   ├── constants.go
│   │   ├── graphql.go
│   │   └── jaeger.go
│   ├── config/
│   │   ├── injector.go
│   │   ├── provider.go
│   │   └── wire_gen.go
│   ├── context/
│   │   └── context.go
│   ├── dataloader/
│   │   ├── dataloader.go
│   │   └── productitemloader_gen.go
│   ├── db/
│   │   ├── db.go
│   │   ├── domain/
│   │   │   ├── product.go
│   │   │   ├── product_item.go
│   │   │   └── user.go
│   │   ├── injector.go
│   │   ├── provider.go
│   │   ├── repo/
│   │   │   ├── provider.go
│   │   │   ├── users.go
│   │   │   └── users_test.go
│   │   └── wire_gen.go
│   ├── entrypoint/
│   │   ├── entrypoint.go
│   │   ├── entrypoint_test.go
│   │   └── provider.go
│   ├── graphql/
│   │   ├── graphql.go
│   │   └── provider.go
│   ├── graphql_resolver/
│   │   ├── injector.go
│   │   ├── mock.go
│   │   ├── product.go
│   │   ├── product_test.go
│   │   ├── provider.go
│   │   ├── resolver.go
│   │   ├── resolver_gen.go
│   │   ├── user.go
│   │   ├── user_test.go
│   │   └── wire_gen.go
│   ├── grpc/
│   │   ├── connection.go
│   │   ├── manager.go
│   │   ├── pool.go
│   │   └── provider.go
│   ├── http/
│   │   ├── http.go
│   │   ├── injector.go
│   │   ├── logger.go
│   │   ├── provider.go
│   │   └── wire_gen.go
│   ├── http_routers/
│   │   └── products-router/
│   │       ├── injector.go
│   │       ├── manager.go
│   │       ├── provider.go
│   │       ├── router.go
│   │       ├── router_test.go
│   │       └── wire_gen.go
│   ├── logger/
│   │   ├── injector.go
│   │   ├── logger.go
│   │   ├── middleware.go
│   │   ├── mock.go
│   │   ├── provider.go
│   │   ├── wire_gen.go
│   │   └── zap.go
│   ├── provider/
│   │   └── provider.go
│   └── tracing/
│       ├── jaeger.go
│       └── provider.go
├── cmd/
│   ├── daemon/
│   │   └── daemon.go
│   ├── health-check-service/
│   │   └── health_check_service.go
│   ├── jwt/
│   │   ├── jwt.go
│   │   └── token.go
│   ├── migrate/
│   │   └── migrate.go
│   ├── product-service/
│   │   ├── nats_service.go
│   │   └── product_service.go
│   └── root.go
├── dbconfig.yml
├── docker/
│   └── app/
│       ├── Dockerfile
│       └── files/
│           └── docker/
│               └── bin/
│                   └── entrypoint.sh
├── docker-compose.yml
├── generated/
│   ├── graphql/
│   │   ├── generated.go
│   │   └── models_gen.go
│   └── resources/
│       └── proto/
│           ├── health_checks/
│           │   ├── health_checks.pb.go
│           │   └── health_checks_grpc.pb.go
│           └── products/
│               ├── products.pb.go
│               └── products_grpc.pb.go
├── go.mod
├── go.sum
├── gqlgen.yml
├── main.go
├── prototool.yaml
├── resources/
│   ├── casbin/
│   │   ├── model.conf
│   │   └── policy.csv
│   ├── configs/
│   │   ├── development.yaml
│   │   └── docker_development.yaml
│   ├── graphql/
│   │   ├── products.graphql
│   │   ├── root.graphql
│   │   └── user.graphql
│   ├── keys/
│   │   └── local/
│   │       ├── private_key.pem
│   │       └── public_key.pem
│   ├── migrations/
│   │   ├── 20181215164636-create_users.sql
│   │   └── 20181216210607-records.sql
│   ├── proto/
│   │   ├── health_checks/
│   │   │   └── health_checks.proto
│   │   └── products/
│   │       └── products.proto
│   └── templates/
│       └── helpers/
│           └── errors.html
└── scripts/
    ├── docker-compose-start.sh
    └── remove_docker_containers.sh
Download .txt
SYMBOL INDEX (527 symbols across 77 files)

FILE: app/auth/middleware.go
  constant prefix (line 20) | prefix = "app.auth"
  constant defaultSubject (line 21) | defaultSubject = "anonymous"
  constant defaultServiceName (line 22) | defaultServiceName = "unknown"
  constant defaultServiceId (line 23) | defaultServiceId = 0
  type CustomClaims (line 29) | type CustomClaims struct
  type Config (line 34) | type Config struct
  type Middleware (line 40) | type Middleware struct
    method JWTHandler (line 53) | func (m Middleware) JWTHandler(next http.Handler) http.Handler {
    method Service (line 108) | func (m Middleware) Service(claims *CustomClaims) (string, uint64) {
  type keys (line 47) | type keys struct
  function NewMiddleware (line 121) | func NewMiddleware(cfg Config, log logger.Logger) (*Middleware, func(), ...
  function NewTestMiddleware (line 140) | func NewTestMiddleware(log logger.Logger) (*Middleware, func(), error) {

FILE: app/auth/provider.go
  function ProviderCfg (line 10) | func ProviderCfg(cfg *viper.Viper) (Config, func(), error) {
  function Provider (line 17) | func Provider(cfg Config, logger logger.Logger) (*Middleware, func(), er...
  function ProviderTest (line 22) | func ProviderTest(logger logger.Logger) (*Middleware, func(), error) {

FILE: app/casbin/provider.go
  function Provider (line 10) | func Provider() (*casbin.Enforcer, func(), error) {
  function ProviderTest (line 16) | func ProviderTest() (*casbin.Enforcer, func(), error) {

FILE: app/common/bcrypt.go
  function HashPassword (line 5) | func HashPassword(password string, cost int) (string, error) {
  function CheckPasswordHash (line 10) | func CheckPasswordHash(password, hash string) bool {

FILE: app/common/constants.go
  constant SrvProducts (line 4) | SrvProducts = "products"

FILE: app/common/graphql.go
  function SendGraphqlError (line 13) | func SendGraphqlError(w http.ResponseWriter, code int, errors gqlerror.L...
  function SendGraphqlErrorf (line 23) | func SendGraphqlErrorf(w http.ResponseWriter, code int, format string, a...

FILE: app/common/jaeger.go
  function GenerateTracerForTestClient (line 13) | func GenerateTracerForTestClient(serviceName string, cfg *viper.Viper) (...

FILE: app/config/injector.go
  function Build (line 11) | func Build() (*viper.Viper, func(), error) {

FILE: app/config/provider.go
  function Provider (line 10) | func Provider() (*viper.Viper, func(), error) {

FILE: app/config/wire_gen.go
  function Build (line 16) | func Build() (*viper.Viper, func(), error) {

FILE: app/context/context.go
  constant prefix (line 9) | prefix = "app.context"
  type Manager (line 12) | type Manager struct
    method ToMapping (line 17) | func (m *Manager) ToMapping() *Mapping {
  function NewManager (line 26) | func NewManager(ctx context.Context) (*Manager, error) {
  type Mapping (line 42) | type Mapping struct
  function NewContext (line 49) | func NewContext(ctx context.Context, m Mapping) context.Context {

FILE: app/dataloader/dataloader.go
  type ctxKeyType (line 17) | type ctxKeyType struct
  type loaders (line 21) | type loaders struct
  function LoaderMiddleware (line 25) | func LoaderMiddleware(next http.Handler) http.Handler {
  function CtxLoaders (line 63) | func CtxLoaders(ctx context.Context) loaders {

FILE: app/dataloader/productitemloader_gen.go
  type ProductItemLoaderConfig (line 13) | type ProductItemLoaderConfig struct
  function NewProductItemLoader (line 25) | func NewProductItemLoader(config ProductItemLoaderConfig) *ProductItemLo...
  type ProductItemLoader (line 34) | type ProductItemLoader struct
    method Load (line 66) | func (l *ProductItemLoader) Load(key int) ([]*domain.ProductItem, erro...
    method LoadThunk (line 73) | func (l *ProductItemLoader) LoadThunk(key int) func() ([]*domain.Produ...
    method LoadAll (line 116) | func (l *ProductItemLoader) LoadAll(keys []int) ([][]*domain.ProductIt...
    method LoadAllThunk (line 134) | func (l *ProductItemLoader) LoadAllThunk(keys []int) func() ([][]*doma...
    method Prime (line 152) | func (l *ProductItemLoader) Prime(key int, value []*domain.ProductItem...
    method Clear (line 167) | func (l *ProductItemLoader) Clear(key int) {
    method unsafeSet (line 173) | func (l *ProductItemLoader) unsafeSet(key int, value []*domain.Product...
  type productItemLoaderBatch (line 57) | type productItemLoaderBatch struct
    method keyIndex (line 182) | func (b *productItemLoaderBatch) keyIndex(l *ProductItemLoader, key in...
    method startTimer (line 206) | func (b *productItemLoaderBatch) startTimer(l *ProductItemLoader) {
    method end (line 222) | func (b *productItemLoaderBatch) end(l *ProductItemLoader) {

FILE: app/db/db.go
  constant prefix (line 13) | prefix = "app.db"
  type Config (line 16) | type Config struct
  type Manager (line 25) | type Manager struct
  function New (line 33) | func New(ctx context.Context, log logger.Logger, cfg Config, db *gorm.DB...

FILE: app/db/domain/product.go
  type Product (line 3) | type Product struct

FILE: app/db/domain/product_item.go
  type ProductItem (line 3) | type ProductItem struct

FILE: app/db/domain/user.go
  type User (line 3) | type User struct
  type UsersRepo (line 10) | type UsersRepo interface

FILE: app/db/injector.go
  function Build (line 10) | func Build() (*Manager, func(), error) {
  function BuildTest (line 14) | func BuildTest() (*Manager, func(), error) {

FILE: app/db/provider.go
  function Cfg (line 17) | func Cfg(cfg *viper.Viper) (Config, func(), error) {
  function CfgTest (line 27) | func CfgTest() (Config, func(), error) {
  function ProviderGORM (line 32) | func ProviderGORM(ctx context.Context, log logger.Logger, cfg Config) (*...
  function ProviderGORMTest (line 55) | func ProviderGORMTest() (*gorm.DB, func(), error) {
  function Provider (line 78) | func Provider(ctx context.Context, log logger.Logger, cfg Config, db *go...

FILE: app/db/repo/provider.go
  type Repo (line 9) | type Repo struct
  function Provider (line 14) | func Provider(userDomain domain.UsersRepo) (*Repo, func(), error) {

FILE: app/db/repo/users.go
  type UsersRepo (line 8) | type UsersRepo struct
    method CreateUser (line 12) | func (u *UsersRepo) CreateUser(email string, encryptPassword string) (...
    method FindByEmail (line 22) | func (u *UsersRepo) FindByEmail(email string) (*domain.User, error) {
  function NewUsersRepo (line 35) | func NewUsersRepo(db *gorm.DB) (domain.UsersRepo, func(), error) {

FILE: app/db/repo/users_test.go
  function TestCreateUser (line 20) | func TestCreateUser(t *testing.T) {
  function TestFindByEmail (line 85) | func TestFindByEmail(t *testing.T) {

FILE: app/db/wire_gen.go
  function Build (line 21) | func Build() (*Manager, func(), error) {
  function BuildTest (line 82) | func BuildTest() (*Manager, func(), error) {

FILE: app/entrypoint/entrypoint.go
  constant prefix (line 21) | prefix = "app.entrypoint"
  function init (line 23) | func init() {
  function Viper (line 28) | func Viper() *viper.Viper {
  function Initialize (line 39) | func Initialize(workDir string, v *viper.Viper) (*EntryPoint, error) {
  function OnShutdown (line 55) | func OnShutdown() context.Context {
  function OnReload (line 60) | func OnReload() <-chan struct{} {
  type EntryPoint (line 65) | type EntryPoint struct
    method Reload (line 79) | func (e *EntryPoint) Reload() {
  function Shutdown (line 69) | func Shutdown(ctx context.Context, code int) {
  function WorkDir (line 88) | func WorkDir() string {

FILE: app/entrypoint/entrypoint_test.go
  function TestInitialize (line 13) | func TestInitialize(t *testing.T) {

FILE: app/entrypoint/provider.go
  function ContextProvider (line 12) | func ContextProvider() (context.Context, func(), error) {
  function ContextProviderTest (line 18) | func ContextProviderTest() (context.Context, func(), error) {

FILE: app/graphql/graphql.go
  constant prefix (line 24) | prefix = "app.graphql"
  type GraphQL (line 30) | type GraphQL struct
    method Use (line 38) | func (g *GraphQL) Use(router *chi.Mux) {
    method Routers (line 43) | func (g *GraphQL) Routers(router chi.Router) {
  type Config (line 96) | type Config struct
  function New (line 104) | func New(ctx context.Context, resolver graphql.Config, log logger.Logger...

FILE: app/graphql/provider.go
  function Cfg (line 15) | func Cfg(cfg *viper.Viper) (Config, func(), error) {
  function CfgTest (line 28) | func CfgTest() (Config, func(), error) {
  function Provider (line 33) | func Provider(ctx context.Context, resolver graphql.Config, log logger.L...

FILE: app/graphql_resolver/injector.go
  function Build (line 14) | func Build() (graphql.Config, func(), error) {
  function BuildTest (line 18) | func BuildTest() (graphql.Config, func(), error) {

FILE: app/graphql_resolver/mock.go
  type ProductServerMock (line 10) | type ProductServerMock struct
    method ListProduct (line 14) | func (s *ProductServerMock) ListProduct(ctx context.Context, in *produ...

FILE: app/graphql_resolver/product.go
  type productsQueryResolver (line 18) | type productsQueryResolver struct
    method List (line 31) | func (r *productsQueryResolver) List(ctx context.Context, obj *graphql...
  type productResolver (line 19) | type productResolver struct
    method ProductItems (line 68) | func (r *productResolver) ProductItems(ctx context.Context, obj *domai...
  method ProductsQuery (line 21) | func (r *Resolver) ProductsQuery() graphql.ProductsQueryResolver {
  method Products (line 27) | func (r *queryResolver) Products(ctx context.Context) (*graphql.Products...
  method ProductsRoot (line 60) | func (r *queryResolver) ProductsRoot(ctx context.Context) ([]*domain.Pro...
  method Product (line 64) | func (r *Resolver) Product() graphql.ProductResolver {

FILE: app/graphql_resolver/product_test.go
  function TestMain (line 30) | func TestMain(m *testing.M) {
  function TestList (line 52) | func TestList(t *testing.T) {

FILE: app/graphql_resolver/provider.go
  function Cfg (line 15) | func Cfg(cfg *viper.Viper) (Config, func(), error) {
  function CfgTest (line 22) | func CfgTest() (Config, func(), error) {
  function Provider (line 31) | func Provider(ctx context.Context, log logger.Logger, cfg Config, enforc...

FILE: app/graphql_resolver/resolver.go
  type Config (line 25) | type Config struct
  type Managers (line 30) | type Managers struct
  type queryResolver (line 35) | type queryResolver struct
  type mutationResolver (line 36) | type mutationResolver struct
  type Resolver (line 39) | type Resolver struct
    method Mutation (line 48) | func (r *Resolver) Mutation() graphql1.MutationResolver {
    method Query (line 53) | func (r *Resolver) Query() graphql1.QueryResolver {
  function New (line 58) | func New(ctx context.Context, log logger.Logger, cfg Config, enforcer *c...

FILE: app/graphql_resolver/user.go
  type usersQueryResolver (line 12) | type usersQueryResolver struct
    method One (line 28) | func (r *usersQueryResolver) One(ctx context.Context, obj *graphql1.Us...
  type usersMutationResolver (line 13) | type usersMutationResolver struct
    method CreateUser (line 49) | func (r *usersMutationResolver) CreateUser(ctx context.Context, obj *g...
  method UsersMutation (line 15) | func (r *Resolver) UsersMutation() graphql1.UsersMutationResolver {
  method UsersQuery (line 18) | func (r *Resolver) UsersQuery() graphql1.UsersQueryResolver {
  method Users (line 24) | func (r *queryResolver) Users(ctx context.Context) (*graphql1.UsersQuery...
  method Users (line 45) | func (r *mutationResolver) Users(ctx context.Context) (*graphql1.UsersMu...

FILE: app/graphql_resolver/user_test.go
  type UserParams (line 18) | type UserParams struct
  function TestOne (line 24) | func TestOne(t *testing.T) {

FILE: app/graphql_resolver/wire_gen.go
  function Build (line 24) | func Build() (graphql.Config, func(), error) {
  function BuildTest (line 213) | func BuildTest() (graphql.Config, func(), error) {

FILE: app/grpc/connection.go
  function SetPool (line 15) | func SetPool(p *Pool, srv string) {
  function GetConnGRPC (line 24) | func GetConnGRPC(poolManager *PoolManager, srv string) (*grpc.ClientConn...

FILE: app/grpc/manager.go
  constant prefix (line 19) | prefix = "app.grpc"
  type PoolManager (line 24) | type PoolManager struct
    method NewPool (line 32) | func (p *PoolManager) NewPool(service string) (_ *Pool, loaded bool, _...
  function NewPoolManager (line 77) | func NewPoolManager(ctx context.Context, tracing *tracesdk.TracerProvide...

FILE: app/grpc/pool.go
  type Done (line 19) | type Done
  type conn (line 21) | type conn struct
    method init (line 27) | func (c *conn) init() {
  type Pool (line 32) | type Pool struct
    method Get (line 42) | func (p *Pool) Get() (*grpc.ClientConn, Done, error) {
  type opts (line 49) | type opts struct
  type Option (line 58) | type Option
  function ConnOptions (line 61) | func ConnOptions(o ...grpc.DialOption) Option {
  function MaxConn (line 69) | func MaxConn(value int) Option {
  function InitConn (line 77) | func InitConn(value int) Option {
  function MaxLifeDuration (line 85) | func MaxLifeDuration(value time.Duration) Option {
  function IdleTimeout (line 93) | func IdleTimeout(value time.Duration) Option {
  function NewPool (line 101) | func NewPool(ctx context.Context, service, target string, o ...Option) (...

FILE: app/grpc/provider.go
  function Cfg (line 23) | func Cfg(cfg *viper.Viper) (*Config, func(), error) {
  function CfgTest (line 33) | func CfgTest() (*Config, func(), error) {
  type Service (line 38) | type Service struct
  type Config (line 48) | type Config struct
  function Provider (line 54) | func Provider(ctx context.Context, tracing *tracesdk.TracerProvider, log...

FILE: app/http/http.go
  constant prefix (line 15) | prefix = "app.http"
  type Config (line 18) | type Config struct
  type Http (line 24) | type Http struct
    method ListenAndServe (line 33) | func (m *Http) ListenAndServe(wg *sync.WaitGroup, bind ...string) (ser...
  function New (line 63) | func New(ctx context.Context, mux *chi.Mux, log logger.Logger, cfg Confi...

FILE: app/http/injector.go
  function Build (line 16) | func Build() (*Http, func(), error) {

FILE: app/http/logger.go
  function Logger (line 11) | func Logger(l logger.Logger) func(next http.Handler) http.Handler {

FILE: app/http/provider.go
  function Cfg (line 27) | func Cfg(cfg *viper.Viper) (Config, func(), error) {
  function CfgTest (line 38) | func CfgTest() (Config, func(), error) {
  function Mux (line 43) | func Mux(managers Managers, log logger.Logger) (*chi.Mux, func(), error) {
  type Managers (line 61) | type Managers struct
  function Provider (line 72) | func Provider(ctx context.Context, mux *chi.Mux, log logger.Logger, cfg ...

FILE: app/http/wire_gen.go
  function Build (line 27) | func Build() (*Http, func(), error) {

FILE: app/http_routers/products-router/injector.go
  function Build (line 11) | func Build() (*Manager, func(), error) {
  function BuildTest (line 15) | func BuildTest() (*Manager, func(), error) {

FILE: app/http_routers/products-router/manager.go
  constant prefix (line 10) | prefix = "app.products-router"
  type Manager (line 13) | type Manager struct
  type ServiceManagers (line 20) | type ServiceManagers struct
  function New (line 24) | func New(ctx context.Context, log logger.Logger, managers ServiceManager...

FILE: app/http_routers/products-router/provider.go
  function Cfg (line 12) | func Cfg(cfg *viper.Viper) (*Config, func(), error) {
  function CfgTest (line 22) | func CfgTest() (*Config, func(), error) {
  type Config (line 27) | type Config struct
  function Provider (line 37) | func Provider(ctx context.Context, log logger.Logger, managers ServiceMa...

FILE: app/http_routers/products-router/router.go
  type Router (line 20) | type Router struct
    method Run (line 27) | func (router *Router) Run(chiRouter chi.Router) {
    method GetProductsGrpc (line 33) | func (router *Router) GetProductsGrpc(w http.ResponseWriter, r *http.R...
    method GetProductsNats (line 61) | func (router *Router) GetProductsNats(w http.ResponseWriter, r *http.R...
    method GetProductsSlowly (line 94) | func (router *Router) GetProductsSlowly(w http.ResponseWriter, r *http...

FILE: app/http_routers/products-router/router_test.go
  function TestMain (line 32) | func TestMain(m *testing.M) {
  function TestGetProductsGrpc (line 54) | func TestGetProductsGrpc(t *testing.T) {

FILE: app/http_routers/products-router/wire_gen.go
  function Build (line 20) | func Build() (*Manager, func(), error) {
  function BuildTest (line 123) | func BuildTest() (*Manager, func(), error) {

FILE: app/logger/injector.go
  function Build (line 12) | func Build() (Logger, func(), error) {
  function BuildTest (line 16) | func BuildTest() (Logger, func(), error) {

FILE: app/logger/logger.go
  type Fields (line 4) | type Fields
  type Level (line 8) | type Level
    method String (line 11) | func (l Level) String() string {
    method FromString (line 34) | func (l *Level) FromString(level string) Level {
  constant LevelDebug (line 58) | LevelDebug Level = 7
  constant LevelInfo (line 60) | LevelInfo Level = 6
  constant LevelNotice (line 62) | LevelNotice Level = 5
  constant LevelWarning (line 64) | LevelWarning Level = 4
  constant LevelError (line 66) | LevelError Level = 3
  constant LevelCritical (line 68) | LevelCritical Level = 2
  constant LevelAlert (line 70) | LevelAlert Level = 1
  constant LevelEmergency (line 72) | LevelEmergency Level = 0
  type opts (line 75) | type opts struct
  type Option (line 81) | type Option
  function Args (line 84) | func Args(a ...interface{}) Option {
  function WithFields (line 92) | func WithFields(fields Fields) Option {
  type Config (line 100) | type Config struct
  type Logger (line 105) | type Logger interface

FILE: app/logger/middleware.go
  function UnaryClientInterceptor (line 12) | func UnaryClientInterceptor(log Logger, enable bool) grpc.UnaryClientInt...
  function StreamClientInterceptor (line 35) | func StreamClientInterceptor(log Logger, enable bool) grpc.StreamClientI...
  function UnaryServerInterceptor (line 57) | func UnaryServerInterceptor(log Logger, enable bool) grpc.UnaryServerInt...
  function StreamServerInterceptor (line 80) | func StreamServerInterceptor(log Logger, enable bool) grpc.StreamServerI...

FILE: app/logger/mock.go
  type Entity (line 8) | type Entity struct
  type Mock (line 16) | type Mock struct
    method Printf (line 25) | func (m *Mock) Printf(format string, a ...interface{}) {
    method Emergency (line 30) | func (m *Mock) Emergency(format string, opts ...Option) {
    method Alert (line 35) | func (m *Mock) Alert(format string, opts ...Option) {
    method Critical (line 40) | func (m *Mock) Critical(format string, opts ...Option) {
    method Error (line 45) | func (m *Mock) Error(format string, opts ...Option) {
    method Warning (line 50) | func (m *Mock) Warning(format string, opts ...Option) {
    method Notice (line 55) | func (m *Mock) Notice(format string, opts ...Option) {
    method Info (line 60) | func (m *Mock) Info(format string, opts ...Option) {
    method Debug (line 65) | func (m *Mock) Debug(format string, opts ...Option) {
    method Write (line 70) | func (m *Mock) Write(p []byte) (n int, err error) {
    method Log (line 76) | func (m *Mock) Log(level Level, format string, o ...Option) {
    method WithFields (line 106) | func (m *Mock) WithFields(fields Fields) Logger {
    method Catch (line 129) | func (m *Mock) Catch() <-chan Entity {
  function copyMock (line 112) | func copyMock(dst, src *Mock, fields map[string]interface{}) {
  function newMock (line 134) | func newMock(ctx context.Context, cfg Config, discard bool) *Mock {

FILE: app/logger/provider.go
  function ProviderCfg (line 11) | func ProviderCfg(cfg *viper.Viper) (Config, func(), error) {
  function ProviderCfgTest (line 24) | func ProviderCfgTest() (Config, func(), error) {
  function Provider (line 29) | func Provider(ctx context.Context, cfg Config) (*Zap, func(), error) {
  function ProviderTest (line 34) | func ProviderTest(ctx context.Context, cfg Config) (*Mock, func(), error) {

FILE: app/logger/wire_gen.go
  function Build (line 17) | func Build() (Logger, func(), error) {
  function BuildTest (line 48) | func BuildTest() (Logger, func(), error) {

FILE: app/logger/zap.go
  type Zap (line 12) | type Zap struct
    method Printf (line 20) | func (z *Zap) Printf(format string, a ...interface{}) {
    method Emergency (line 25) | func (z *Zap) Emergency(format string, opts ...Option) {
    method Alert (line 30) | func (z *Zap) Alert(format string, opts ...Option) {
    method Critical (line 35) | func (z *Zap) Critical(format string, opts ...Option) {
    method Error (line 40) | func (z *Zap) Error(format string, opts ...Option) {
    method Warning (line 45) | func (z *Zap) Warning(format string, opts ...Option) {
    method Notice (line 50) | func (z *Zap) Notice(format string, opts ...Option) {
    method Info (line 55) | func (z *Zap) Info(format string, opts ...Option) {
    method Debug (line 60) | func (z *Zap) Debug(format string, opts ...Option) {
    method Write (line 65) | func (z *Zap) Write(p []byte) (n int, err error) {
    method Log (line 71) | func (z *Zap) Log(level Level, format string, o ...Option) {
    method WithFields (line 127) | func (z *Zap) WithFields(fields Fields) Logger {
  function copyZap (line 133) | func copyZap(dst, src *Zap, fields map[string]interface{}) {
  function newZap (line 149) | func newZap(ctx context.Context, cfg Config) *Zap {

FILE: app/tracing/jaeger.go
  type Configuration (line 15) | type Configuration struct
  constant prefix (line 21) | prefix = "app.tracer"
  function newJaegerTracer (line 23) | func newJaegerTracer(ctx context.Context, configuration *Configuration, ...

FILE: app/tracing/provider.go
  function Cfg (line 19) | func Cfg(cfg *viper.Viper) (*Configuration, func(), error) {
  function Provider (line 29) | func Provider(ctx context.Context, configuration *Configuration, log log...
  function ProviderTest (line 37) | func ProviderTest() (*tracesdk.TracerProvider, func(), error) {

FILE: cmd/daemon/daemon.go
  function init (line 79) | func init() {

FILE: cmd/health-check-service/health_check_service.go
  type Config (line 29) | type Config struct
  type server (line 34) | type server struct
    method IsAlive (line 39) | func (s *server) IsAlive(ctx context.Context, empty *emptypb.Empty) (*...
  function init (line 131) | func init() {

FILE: cmd/jwt/jwt.go
  function init (line 12) | func init() {

FILE: cmd/jwt/token.go
  function init (line 21) | func init() {
  function GenerateJWT (line 71) | func GenerateJWT(privateKey []byte, fields map[string]interface{}) (stri...

FILE: cmd/migrate/migrate.go
  function init (line 79) | func init() {

FILE: cmd/product-service/nats_service.go
  type natsService (line 8) | type natsService struct
    method workerHanlder (line 12) | func (s *natsService) workerHanlder(m *stan.Msg) {

FILE: cmd/product-service/product_service.go
  type Config (line 35) | type Config struct
  type server (line 42) | type server struct
    method ListProduct (line 48) | func (s *server) ListProduct(ctx context.Context, in *products.ListPro...
  function init (line 180) | func init() {

FILE: cmd/root.go
  constant prefix (line 39) | prefix = "cmd.root"
  function init (line 81) | func init() {
  function Execute (line 114) | func Execute() {

FILE: generated/graphql/generated.go
  function NewExecutableSchema (line 24) | func NewExecutableSchema(cfg Config) graphql.ExecutableSchema {
  type Config (line 32) | type Config struct
  type ResolverRoot (line 38) | type ResolverRoot interface
  type DirectiveRoot (line 47) | type DirectiveRoot struct
  type ComplexityRoot (line 51) | type ComplexityRoot struct
  type MutationResolver (line 100) | type MutationResolver interface
  type ProductResolver (line 103) | type ProductResolver interface
  type ProductsQueryResolver (line 106) | type ProductsQueryResolver interface
  type QueryResolver (line 109) | type QueryResolver interface
  type UsersMutationResolver (line 113) | type UsersMutationResolver interface
  type UsersQueryResolver (line 116) | type UsersQueryResolver interface
  type executableSchema (line 120) | type executableSchema struct
    method Schema (line 126) | func (e *executableSchema) Schema() *ast.Schema {
    method Complexity (line 130) | func (e *executableSchema) Complexity(typeName, field string, childCom...
    method Exec (line 268) | func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseH...
  type executionContext (line 308) | type executionContext struct
    method introspectSchema (line 313) | func (ec *executionContext) introspectSchema() (*introspection.Schema,...
    method introspectType (line 320) | func (ec *executionContext) introspectType(name string) (*introspectio...
    method dir_hasUsersPermission_args (line 395) | func (ec *executionContext) dir_hasUsersPermission_args(ctx context.Co...
    method field_Query___type_args (line 410) | func (ec *executionContext) field_Query___type_args(ctx context.Contex...
    method field_UsersMutation_createUser_args (line 425) | func (ec *executionContext) field_UsersMutation_createUser_args(ctx co...
    method field_UsersQuery_one_args (line 449) | func (ec *executionContext) field_UsersQuery_one_args(ctx context.Cont...
    method field___Type_enumValues_args (line 464) | func (ec *executionContext) field___Type_enumValues_args(ctx context.C...
    method field___Type_fields_args (line 479) | func (ec *executionContext) field___Type_fields_args(ctx context.Conte...
    method _Mutation_users (line 502) | func (ec *executionContext) _Mutation_users(ctx context.Context, field...
    method _Product_id (line 533) | func (ec *executionContext) _Product_id(ctx context.Context, field gra...
    method _Product_name (line 567) | func (ec *executionContext) _Product_name(ctx context.Context, field g...
    method _Product_productItems (line 601) | func (ec *executionContext) _Product_productItems(ctx context.Context,...
    method _ProductItem_id (line 635) | func (ec *executionContext) _ProductItem_id(ctx context.Context, field...
    method _ProductItem_name (line 669) | func (ec *executionContext) _ProductItem_name(ctx context.Context, fie...
    method _ProductsListOut_products (line 703) | func (ec *executionContext) _ProductsListOut_products(ctx context.Cont...
    method _ProductsQuery_list (line 737) | func (ec *executionContext) _ProductsQuery_list(ctx context.Context, f...
    method _Query_users (line 771) | func (ec *executionContext) _Query_users(ctx context.Context, field gr...
    method _Query_products (line 802) | func (ec *executionContext) _Query_products(ctx context.Context, field...
    method _Query___type (line 833) | func (ec *executionContext) _Query___type(ctx context.Context, field g...
    method _Query___schema (line 871) | func (ec *executionContext) _Query___schema(ctx context.Context, field...
    method _UsersCreateOut_status (line 902) | func (ec *executionContext) _UsersCreateOut_status(ctx context.Context...
    method _UsersCreateOut_id (line 936) | func (ec *executionContext) _UsersCreateOut_id(ctx context.Context, fi...
    method _UsersCreateOut_email (line 970) | func (ec *executionContext) _UsersCreateOut_email(ctx context.Context,...
    method _UsersMutation_createUser (line 1004) | func (ec *executionContext) _UsersMutation_createUser(ctx context.Cont...
    method _UsersOneOut_id (line 1069) | func (ec *executionContext) _UsersOneOut_id(ctx context.Context, field...
    method _UsersOneOut_email (line 1103) | func (ec *executionContext) _UsersOneOut_email(ctx context.Context, fi...
    method _UsersQuery_one (line 1137) | func (ec *executionContext) _UsersQuery_one(ctx context.Context, field...
    method ___Directive_name (line 1202) | func (ec *executionContext) ___Directive_name(ctx context.Context, fie...
    method ___Directive_description (line 1236) | func (ec *executionContext) ___Directive_description(ctx context.Conte...
    method ___Directive_locations (line 1267) | func (ec *executionContext) ___Directive_locations(ctx context.Context...
    method ___Directive_args (line 1301) | func (ec *executionContext) ___Directive_args(ctx context.Context, fie...
    method ___EnumValue_name (line 1335) | func (ec *executionContext) ___EnumValue_name(ctx context.Context, fie...
    method ___EnumValue_description (line 1369) | func (ec *executionContext) ___EnumValue_description(ctx context.Conte...
    method ___EnumValue_isDeprecated (line 1400) | func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Cont...
    method ___EnumValue_deprecationReason (line 1434) | func (ec *executionContext) ___EnumValue_deprecationReason(ctx context...
    method ___Field_name (line 1465) | func (ec *executionContext) ___Field_name(ctx context.Context, field g...
    method ___Field_description (line 1499) | func (ec *executionContext) ___Field_description(ctx context.Context, ...
    method ___Field_args (line 1530) | func (ec *executionContext) ___Field_args(ctx context.Context, field g...
    method ___Field_type (line 1564) | func (ec *executionContext) ___Field_type(ctx context.Context, field g...
    method ___Field_isDeprecated (line 1598) | func (ec *executionContext) ___Field_isDeprecated(ctx context.Context,...
    method ___Field_deprecationReason (line 1632) | func (ec *executionContext) ___Field_deprecationReason(ctx context.Con...
    method ___InputValue_name (line 1663) | func (ec *executionContext) ___InputValue_name(ctx context.Context, fi...
    method ___InputValue_description (line 1697) | func (ec *executionContext) ___InputValue_description(ctx context.Cont...
    method ___InputValue_type (line 1728) | func (ec *executionContext) ___InputValue_type(ctx context.Context, fi...
    method ___InputValue_defaultValue (line 1762) | func (ec *executionContext) ___InputValue_defaultValue(ctx context.Con...
    method ___Schema_types (line 1793) | func (ec *executionContext) ___Schema_types(ctx context.Context, field...
    method ___Schema_queryType (line 1827) | func (ec *executionContext) ___Schema_queryType(ctx context.Context, f...
    method ___Schema_mutationType (line 1861) | func (ec *executionContext) ___Schema_mutationType(ctx context.Context...
    method ___Schema_subscriptionType (line 1892) | func (ec *executionContext) ___Schema_subscriptionType(ctx context.Con...
    method ___Schema_directives (line 1923) | func (ec *executionContext) ___Schema_directives(ctx context.Context, ...
    method ___Type_kind (line 1957) | func (ec *executionContext) ___Type_kind(ctx context.Context, field gr...
    method ___Type_name (line 1991) | func (ec *executionContext) ___Type_name(ctx context.Context, field gr...
    method ___Type_description (line 2022) | func (ec *executionContext) ___Type_description(ctx context.Context, f...
    method ___Type_fields (line 2053) | func (ec *executionContext) ___Type_fields(ctx context.Context, field ...
    method ___Type_interfaces (line 2091) | func (ec *executionContext) ___Type_interfaces(ctx context.Context, fi...
    method ___Type_possibleTypes (line 2122) | func (ec *executionContext) ___Type_possibleTypes(ctx context.Context,...
    method ___Type_enumValues (line 2153) | func (ec *executionContext) ___Type_enumValues(ctx context.Context, fi...
    method ___Type_inputFields (line 2191) | func (ec *executionContext) ___Type_inputFields(ctx context.Context, f...
    method ___Type_ofType (line 2222) | func (ec *executionContext) ___Type_ofType(ctx context.Context, field ...
    method _Mutation (line 2267) | func (ec *executionContext) _Mutation(ctx context.Context, sel ast.Sel...
    method _Product (line 2295) | func (ec *executionContext) _Product(ctx context.Context, sel ast.Sele...
    method _ProductItem (line 2341) | func (ec *executionContext) _ProductItem(ctx context.Context, sel ast....
    method _ProductsListOut (line 2373) | func (ec *executionContext) _ProductsListOut(ctx context.Context, sel ...
    method _ProductsQuery (line 2400) | func (ec *executionContext) _ProductsQuery(ctx context.Context, sel as...
    method _Query (line 2436) | func (ec *executionContext) _Query(ctx context.Context, sel ast.Select...
    method _UsersCreateOut (line 2488) | func (ec *executionContext) _UsersCreateOut(ctx context.Context, sel a...
    method _UsersMutation (line 2525) | func (ec *executionContext) _UsersMutation(ctx context.Context, sel as...
    method _UsersOneOut (line 2561) | func (ec *executionContext) _UsersOneOut(ctx context.Context, sel ast....
    method _UsersQuery (line 2593) | func (ec *executionContext) _UsersQuery(ctx context.Context, sel ast.S...
    method ___Directive (line 2629) | func (ec *executionContext) ___Directive(ctx context.Context, sel ast....
    method ___EnumValue (line 2668) | func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast....
    method ___Field (line 2704) | func (ec *executionContext) ___Field(ctx context.Context, sel ast.Sele...
    method ___InputValue (line 2750) | func (ec *executionContext) ___InputValue(ctx context.Context, sel ast...
    method ___Schema (line 2786) | func (ec *executionContext) ___Schema(ctx context.Context, sel ast.Sel...
    method ___Type (line 2827) | func (ec *executionContext) ___Type(ctx context.Context, sel ast.Selec...
    method unmarshalNBoolean2bool (line 2872) | func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context...
    method marshalNBoolean2bool (line 2877) | func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, ...
    method unmarshalNID2int (line 2887) | func (ec *executionContext) unmarshalNID2int(ctx context.Context, v in...
    method marshalNID2int (line 2892) | func (ec *executionContext) marshalNID2int(ctx context.Context, sel as...
    method unmarshalNID2string (line 2902) | func (ec *executionContext) unmarshalNID2string(ctx context.Context, v...
    method marshalNID2string (line 2907) | func (ec *executionContext) marshalNID2string(ctx context.Context, sel...
    method marshalNProduct2ᚕᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋappᚋdbᚋdomainᚐProductᚄ (line 2917) | func (ec *executionContext) marshalNProduct2ᚕᚖgithubᚗcomᚋaristatᚋgolan...
    method marshalNProduct2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋappᚋdbᚋdomainᚐProduct (line 2954) | func (ec *executionContext) marshalNProduct2ᚖgithubᚗcomᚋaristatᚋgolang...
    method marshalNProductItem2ᚕᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋappᚋdbᚋdomainᚐProductItemᚄ (line 2964) | func (ec *executionContext) marshalNProductItem2ᚕᚖgithubᚗcomᚋaristatᚋg...
    method marshalNProductItem2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋappᚋdbᚋdomainᚐProductItem (line 3001) | func (ec *executionContext) marshalNProductItem2ᚖgithubᚗcomᚋaristatᚋgo...
    method marshalNProductsListOut2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐProductsListOut (line 3011) | func (ec *executionContext) marshalNProductsListOut2githubᚗcomᚋaristat...
    method marshalNProductsListOut2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐProductsListOut (line 3015) | func (ec *executionContext) marshalNProductsListOut2ᚖgithubᚗcomᚋarista...
    method unmarshalNString2string (line 3025) | func (ec *executionContext) unmarshalNString2string(ctx context.Contex...
    method marshalNString2string (line 3030) | func (ec *executionContext) marshalNString2string(ctx context.Context,...
    method marshalNUsersCreateOut2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersCreateOut (line 3040) | func (ec *executionContext) marshalNUsersCreateOut2githubᚗcomᚋaristatᚋ...
    method marshalNUsersCreateOut2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersCreateOut (line 3044) | func (ec *executionContext) marshalNUsersCreateOut2ᚖgithubᚗcomᚋaristat...
    method unmarshalNUsersCreateOutStatus2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersCreateOutStatus (line 3054) | func (ec *executionContext) unmarshalNUsersCreateOutStatus2githubᚗcomᚋ...
    method marshalNUsersCreateOutStatus2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersCreateOutStatus (line 3060) | func (ec *executionContext) marshalNUsersCreateOutStatus2githubᚗcomᚋar...
    method marshalNUsersOneOut2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersOneOut (line 3064) | func (ec *executionContext) marshalNUsersOneOut2githubᚗcomᚋaristatᚋgol...
    method marshalNUsersOneOut2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersOneOut (line 3068) | func (ec *executionContext) marshalNUsersOneOut2ᚖgithubᚗcomᚋaristatᚋgo...
    method unmarshalNUsersPermissionEnum2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersPermissionEnum (line 3078) | func (ec *executionContext) unmarshalNUsersPermissionEnum2githubᚗcomᚋa...
    method marshalNUsersPermissionEnum2githubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersPermissionEnum (line 3084) | func (ec *executionContext) marshalNUsersPermissionEnum2githubᚗcomᚋari...
    method marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective (line 3088) | func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋg...
    method marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ (line 3092) | func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋ...
    method unmarshalN__DirectiveLocation2string (line 3129) | func (ec *executionContext) unmarshalN__DirectiveLocation2string(ctx c...
    method marshalN__DirectiveLocation2string (line 3134) | func (ec *executionContext) marshalN__DirectiveLocation2string(ctx con...
    method unmarshalN__DirectiveLocation2ᚕstringᚄ (line 3144) | func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx...
    method marshalN__DirectiveLocation2ᚕstringᚄ (line 3165) | func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx c...
    method marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue (line 3202) | func (ec *executionContext) marshalN__EnumValue2githubᚗcomᚋ99designsᚋg...
    method marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField (line 3206) | func (ec *executionContext) marshalN__Field2githubᚗcomᚋ99designsᚋgqlge...
    method marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue (line 3210) | func (ec *executionContext) marshalN__InputValue2githubᚗcomᚋ99designsᚋ...
    method marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ (line 3214) | func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designs...
    method marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType (line 3251) | func (ec *executionContext) marshalN__Type2githubᚗcomᚋ99designsᚋgqlgen...
    method marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ (line 3255) | func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlge...
    method marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType (line 3292) | func (ec *executionContext) marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlge...
    method unmarshalN__TypeKind2string (line 3302) | func (ec *executionContext) unmarshalN__TypeKind2string(ctx context.Co...
    method marshalN__TypeKind2string (line 3307) | func (ec *executionContext) marshalN__TypeKind2string(ctx context.Cont...
    method unmarshalOBoolean2bool (line 3317) | func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context...
    method marshalOBoolean2bool (line 3322) | func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, ...
    method unmarshalOBoolean2ᚖbool (line 3326) | func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Contex...
    method marshalOBoolean2ᚖbool (line 3334) | func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context,...
    method marshalOProductsQuery2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐProductsQuery (line 3341) | func (ec *executionContext) marshalOProductsQuery2ᚖgithubᚗcomᚋaristatᚋ...
    method unmarshalOString2string (line 3348) | func (ec *executionContext) unmarshalOString2string(ctx context.Contex...
    method marshalOString2string (line 3353) | func (ec *executionContext) marshalOString2string(ctx context.Context,...
    method unmarshalOString2ᚖstring (line 3357) | func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Conte...
    method marshalOString2ᚖstring (line 3365) | func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context...
    method marshalOUsersMutation2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersMutation (line 3372) | func (ec *executionContext) marshalOUsersMutation2ᚖgithubᚗcomᚋaristatᚋ...
    method marshalOUsersQuery2ᚖgithubᚗcomᚋaristatᚋgolangᚑexampleᚑappᚋgeneratedᚋgraphqlᚐUsersQuery (line 3379) | func (ec *executionContext) marshalOUsersQuery2ᚖgithubᚗcomᚋaristatᚋgol...
    method marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ (line 3386) | func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋ...
    method marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ (line 3426) | func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlg...
    method marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ (line 3466) | func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designs...
    method marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema (line 3506) | func (ec *executionContext) marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgql...
    method marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ (line 3513) | func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlge...
    method marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType (line 3553) | func (ec *executionContext) marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlge...

FILE: generated/graphql/models_gen.go
  type ProductsListOut (line 13) | type ProductsListOut struct
  type ProductsQuery (line 17) | type ProductsQuery struct
  type UsersCreateOut (line 21) | type UsersCreateOut struct
  type UsersMutation (line 27) | type UsersMutation struct
  type UsersOneOut (line 31) | type UsersOneOut struct
  type UsersQuery (line 36) | type UsersQuery struct
  type UsersCreateOutStatus (line 40) | type UsersCreateOutStatus
    method IsValid (line 54) | func (e UsersCreateOutStatus) IsValid() bool {
    method String (line 62) | func (e UsersCreateOutStatus) String() string {
    method UnmarshalGQL (line 66) | func (e *UsersCreateOutStatus) UnmarshalGQL(v interface{}) error {
    method MarshalGQL (line 79) | func (e UsersCreateOutStatus) MarshalGQL(w io.Writer) {
  constant UsersCreateOutStatusOk (line 43) | UsersCreateOutStatusOk                  UsersCreateOutStatus = "OK"
  constant UsersCreateOutStatusBadRequest (line 44) | UsersCreateOutStatusBadRequest          UsersCreateOutStatus = "BAD_REQU...
  constant UsersCreateOutStatusServerInternalError (line 45) | UsersCreateOutStatusServerInternalError UsersCreateOutStatus = "SERVER_I...
  type UsersPermissionEnum (line 83) | type UsersPermissionEnum
    method IsValid (line 95) | func (e UsersPermissionEnum) IsValid() bool {
    method String (line 103) | func (e UsersPermissionEnum) String() string {
    method UnmarshalGQL (line 107) | func (e *UsersPermissionEnum) UnmarshalGQL(v interface{}) error {
    method MarshalGQL (line 120) | func (e UsersPermissionEnum) MarshalGQL(w io.Writer) {
  constant UsersPermissionEnumRead (line 86) | UsersPermissionEnumRead  UsersPermissionEnum = "READ"
  constant UsersPermissionEnumWrite (line 87) | UsersPermissionEnumWrite UsersPermissionEnum = "WRITE"

FILE: generated/resources/proto/health_checks/health_checks.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type IsAliveOut_Status (line 24) | type IsAliveOut_Status
    method Enum (line 43) | func (x IsAliveOut_Status) Enum() *IsAliveOut_Status {
    method String (line 49) | func (x IsAliveOut_Status) String() string {
    method Descriptor (line 53) | func (IsAliveOut_Status) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 57) | func (IsAliveOut_Status) Type() protoreflect.EnumType {
    method Number (line 61) | func (x IsAliveOut_Status) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 66) | func (IsAliveOut_Status) EnumDescriptor() ([]byte, []int) {
  constant IsAliveOut_OK (line 27) | IsAliveOut_OK     IsAliveOut_Status = 0
  constant IsAliveOut_NOT_OK (line 28) | IsAliveOut_NOT_OK IsAliveOut_Status = 2
  type IsAliveOut (line 70) | type IsAliveOut struct
    method Reset (line 78) | func (x *IsAliveOut) Reset() {
    method String (line 87) | func (x *IsAliveOut) String() string {
    method ProtoMessage (line 91) | func (*IsAliveOut) ProtoMessage() {}
    method ProtoReflect (line 93) | func (x *IsAliveOut) ProtoReflect() protoreflect.Message {
    method Descriptor (line 106) | func (*IsAliveOut) Descriptor() ([]byte, []int) {
    method GetStatus (line 110) | func (x *IsAliveOut) GetStatus() IsAliveOut_Status {
  function file_resources_proto_health_checks_health_checks_proto_rawDescGZIP (line 149) | func file_resources_proto_health_checks_health_checks_proto_rawDescGZIP(...
  function init (line 174) | func init() { file_resources_proto_health_checks_health_checks_proto_ini...
  function file_resources_proto_health_checks_health_checks_proto_init (line 175) | func file_resources_proto_health_checks_health_checks_proto_init() {

FILE: generated/resources/proto/health_checks/health_checks_grpc.pb.go
  constant _ (line 16) | _ = grpc.SupportPackageIsVersion7
  type HealthChecksClient (line 21) | type HealthChecksClient interface
  type healthChecksClient (line 25) | type healthChecksClient struct
    method IsAlive (line 33) | func (c *healthChecksClient) IsAlive(ctx context.Context, in *emptypb....
  function NewHealthChecksClient (line 29) | func NewHealthChecksClient(cc grpc.ClientConnInterface) HealthChecksClie...
  type HealthChecksServer (line 45) | type HealthChecksServer interface
  type UnimplementedHealthChecksServer (line 51) | type UnimplementedHealthChecksServer struct
    method IsAlive (line 54) | func (UnimplementedHealthChecksServer) IsAlive(context.Context, *empty...
    method mustEmbedUnimplementedHealthChecksServer (line 57) | func (UnimplementedHealthChecksServer) mustEmbedUnimplementedHealthChe...
  type UnsafeHealthChecksServer (line 62) | type UnsafeHealthChecksServer interface
  function RegisterHealthChecksServer (line 66) | func RegisterHealthChecksServer(s grpc.ServiceRegistrar, srv HealthCheck...
  function _HealthChecks_IsAlive_Handler (line 70) | func _HealthChecks_IsAlive_Handler(srv interface{}, ctx context.Context,...

FILE: generated/resources/proto/products/products.pb.go
  constant _ (line 18) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 20) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type ListProductOut_Status (line 23) | type ListProductOut_Status
    method Enum (line 42) | func (x ListProductOut_Status) Enum() *ListProductOut_Status {
    method String (line 48) | func (x ListProductOut_Status) String() string {
    method Descriptor (line 52) | func (ListProductOut_Status) Descriptor() protoreflect.EnumDescriptor {
    method Type (line 56) | func (ListProductOut_Status) Type() protoreflect.EnumType {
    method Number (line 60) | func (x ListProductOut_Status) Number() protoreflect.EnumNumber {
    method EnumDescriptor (line 65) | func (ListProductOut_Status) EnumDescriptor() ([]byte, []int) {
  constant ListProductOut_OK (line 26) | ListProductOut_OK        ListProductOut_Status = 0
  constant ListProductOut_NOT_FOUND (line 27) | ListProductOut_NOT_FOUND ListProductOut_Status = 2
  type Product (line 69) | type Product struct
    method Reset (line 78) | func (x *Product) Reset() {
    method String (line 87) | func (x *Product) String() string {
    method ProtoMessage (line 91) | func (*Product) ProtoMessage() {}
    method ProtoReflect (line 93) | func (x *Product) ProtoReflect() protoreflect.Message {
    method Descriptor (line 106) | func (*Product) Descriptor() ([]byte, []int) {
    method GetId (line 110) | func (x *Product) GetId() int64 {
    method GetName (line 117) | func (x *Product) GetName() string {
  type ListProductIn (line 124) | type ListProductIn struct
    method Reset (line 132) | func (x *ListProductIn) Reset() {
    method String (line 141) | func (x *ListProductIn) String() string {
    method ProtoMessage (line 145) | func (*ListProductIn) ProtoMessage() {}
    method ProtoReflect (line 147) | func (x *ListProductIn) ProtoReflect() protoreflect.Message {
    method Descriptor (line 160) | func (*ListProductIn) Descriptor() ([]byte, []int) {
    method GetId (line 164) | func (x *ListProductIn) GetId() int64 {
  type ListProductOut (line 171) | type ListProductOut struct
    method Reset (line 180) | func (x *ListProductOut) Reset() {
    method String (line 189) | func (x *ListProductOut) String() string {
    method ProtoMessage (line 193) | func (*ListProductOut) ProtoMessage() {}
    method ProtoReflect (line 195) | func (x *ListProductOut) ProtoReflect() protoreflect.Message {
    method Descriptor (line 208) | func (*ListProductOut) Descriptor() ([]byte, []int) {
    method GetStatus (line 212) | func (x *ListProductOut) GetStatus() ListProductOut_Status {
    method GetProducts (line 219) | func (x *ListProductOut) GetProducts() []*Product {
  function file_resources_proto_products_products_proto_rawDescGZIP (line 263) | func file_resources_proto_products_products_proto_rawDescGZIP() []byte {
  function init (line 290) | func init() { file_resources_proto_products_products_proto_init() }
  function file_resources_proto_products_products_proto_init (line 291) | func file_resources_proto_products_products_proto_init() {

FILE: generated/resources/proto/products/products_grpc.pb.go
  constant _ (line 15) | _ = grpc.SupportPackageIsVersion7
  type ProductsClient (line 20) | type ProductsClient interface
  type productsClient (line 24) | type productsClient struct
    method ListProduct (line 32) | func (c *productsClient) ListProduct(ctx context.Context, in *ListProd...
  function NewProductsClient (line 28) | func NewProductsClient(cc grpc.ClientConnInterface) ProductsClient {
  type ProductsServer (line 44) | type ProductsServer interface
  type UnimplementedProductsServer (line 50) | type UnimplementedProductsServer struct
    method ListProduct (line 53) | func (UnimplementedProductsServer) ListProduct(context.Context, *ListP...
    method mustEmbedUnimplementedProductsServer (line 56) | func (UnimplementedProductsServer) mustEmbedUnimplementedProductsServe...
  type UnsafeProductsServer (line 61) | type UnsafeProductsServer interface
  function RegisterProductsServer (line 65) | func RegisterProductsServer(s grpc.ServiceRegistrar, srv ProductsServer) {
  function _Products_ListProduct_Handler (line 69) | func _Products_ListProduct_Handler(srv interface{}, ctx context.Context,...

FILE: main.go
  function main (line 5) | func main() {

FILE: resources/migrations/20181215164636-create_users.sql
  type users (line 4) | CREATE TABLE users(
  type users_email (line 10) | CREATE UNIQUE INDEX users_email ON users USING btree (email)
Condensed preview — 106 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (396K chars).
[
  {
    "path": ".circleci/config.yml",
    "chars": 1899,
    "preview": "version: 2.1\njobs:\n  test:\n    docker:\n      - image: cimg/go:1.17\n    working_directory: ~/golang-example-app\n    steps"
  },
  {
    "path": ".gitignore",
    "chars": 328,
    "preview": "# Binaries for programs and plugins\n*.exe\n*.dll\n*.so\n*.dylib\n\n# Test binary, build with `go test -c`\n*.test\n\n# Output of"
  },
  {
    "path": "Makefile",
    "chars": 2392,
    "preview": "GO_DIR ?= $(shell pwd)\nGO_PKG ?= $(shell go list -e -f \"{{ .ImportPath }}\")\n\nGOOS ?= $(shell go env GOOS || echo linux)\n"
  },
  {
    "path": "README.md",
    "chars": 5466,
    "preview": "![golang logo](golang_logo.png)\n\n# Golang Example Application\n\n# Table of Contents\n\n- [Overview](#overview)\n- [Package l"
  },
  {
    "path": "app/auth/middleware.go",
    "chars": 3724,
    "preview": "package auth\n\nimport (\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/aristat/golang-example-app/app/common\"\n\n\t\"githu"
  },
  {
    "path": "app/auth/provider.go",
    "chars": 655,
    "preview": "package auth\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/google/wire\"\n\t\"github.com/spf13/"
  },
  {
    "path": "app/casbin/provider.go",
    "chars": 1002,
    "preview": "package casbin\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/entrypoint\"\n\t\"github.com/casbin/casbin\"\n\tfileadapte"
  },
  {
    "path": "app/common/bcrypt.go",
    "chars": 357,
    "preview": "package common\n\nimport \"golang.org/x/crypto/bcrypt\"\n\nfunc HashPassword(password string, cost int) (string, error) {\n\tbyt"
  },
  {
    "path": "app/common/constants.go",
    "chars": 52,
    "preview": "package common\n\nconst (\n\tSrvProducts = \"products\"\n)\n"
  },
  {
    "path": "app/common/graphql.go",
    "chars": 586,
    "preview": "package common\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/vektah/gqlparser/v2/gqlerror\"\n\n\t\"github.com/9"
  },
  {
    "path": "app/common/jaeger.go",
    "chars": 951,
    "preview": "package common\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/tracing\"\n\t\"go.opentelemetry.io/otel/exporters/jaege"
  },
  {
    "path": "app/config/injector.go",
    "chars": 243,
    "preview": "// +build wireinject\n\npackage config\n\nimport (\n\t\"github.com/google/wire\"\n\t\"github.com/spf13/viper\"\n)\n\n// Build returns s"
  },
  {
    "path": "app/config/provider.go",
    "chars": 422,
    "preview": "package config\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/entrypoint\"\n\t\"github.com/google/wire\"\n\t\"github.com/"
  },
  {
    "path": "app/config/wire_gen.go",
    "chars": 470,
    "preview": "// Code generated by Wire. DO NOT EDIT.\n\n//go:generate go run github.com/google/wire/cmd/wire\n//go:build !wireinject\n// "
  },
  {
    "path": "app/context/context.go",
    "chars": 1101,
    "preview": "package context\n\nimport (\n\t\"context\"\n\n\t\"github.com/mitchellh/mapstructure\"\n)\n\nconst prefix = \"app.context\"\n\n// Manager\nt"
  },
  {
    "path": "app/dataloader/dataloader.go",
    "chars": 1681,
    "preview": "//go:generate go run github.com/vektah/dataloaden ProductItemLoader int []*github.com/aristat/golang-example-app/generat"
  },
  {
    "path": "app/dataloader/productitemloader_gen.go",
    "chars": 6083,
    "preview": "// Code generated by github.com/vektah/dataloaden, DO NOT EDIT.\n\npackage dataloader\n\nimport (\n\t\"sync\"\n\t\"time\"\n\n\t\"github."
  },
  {
    "path": "app/db/db.go",
    "chars": 638,
    "preview": "package db\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/jinzhu/gorm\"\n\n\t\"github.com/aristat/golang-example-app/app/logger\"\n"
  },
  {
    "path": "app/db/domain/product.go",
    "chars": 107,
    "preview": "package domain\n\ntype Product struct {\n\tID           int\n\tName         string\n\tproductItems []ProductItem\n}\n"
  },
  {
    "path": "app/db/domain/product_item.go",
    "chars": 67,
    "preview": "package domain\n\ntype ProductItem struct {\n\tID   int\n\tName string\n}\n"
  },
  {
    "path": "app/db/domain/user.go",
    "chars": 351,
    "preview": "package domain\n\ntype User struct {\n\tID                int    `gorm:\"column:id\"`\n\tEmail             string `gorm:\"column:"
  },
  {
    "path": "app/db/injector.go",
    "chars": 347,
    "preview": "// +build wireinject\n\npackage db\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/provider\"\n\t\"github.com/google/wir"
  },
  {
    "path": "app/db/provider.go",
    "chars": 1792,
    "preview": "package db\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\n\t\"github.com/jinzhu/gorm\"\n\n\t\"github.com/aristat/golang-example-app/app/"
  },
  {
    "path": "app/db/repo/provider.go",
    "chars": 460,
    "preview": "package repo\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/db/domain\"\n\t\"github.com/google/wire\"\n)\n\n// Repo for a"
  },
  {
    "path": "app/db/repo/users.go",
    "chars": 784,
    "preview": "package repo\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/db/domain\"\n\t\"github.com/jinzhu/gorm\"\n)\n\ntype UsersRep"
  },
  {
    "path": "app/db/repo/users_test.go",
    "chars": 3509,
    "preview": "package repo_test\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\n\t\"golang.org/x/crypto/bcrypt\"\n\n\t\"github.com/aristat/golang-example-app"
  },
  {
    "path": "app/db/wire_gen.go",
    "chars": 2440,
    "preview": "// Code generated by Wire. DO NOT EDIT.\n\n//go:generate go run github.com/google/wire/cmd/wire\n//go:build !wireinject\n// "
  },
  {
    "path": "app/entrypoint/entrypoint.go",
    "chars": 1633,
    "preview": "package entrypoint\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"sync\"\n\n\t\"github.com/spf13/viper\"\n)\n\nvar (\n\tvi          *viper.Viper\n\tmu "
  },
  {
    "path": "app/entrypoint/entrypoint_test.go",
    "chars": 404,
    "preview": "package entrypoint_test\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/aristat/golang-example-app/app/entrypo"
  },
  {
    "path": "app/entrypoint/provider.go",
    "chars": 572,
    "preview": "package entrypoint\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/google/wire\"\n)\n\n// ContextProvider\nfunc Con"
  },
  {
    "path": "app/graphql/graphql.go",
    "chars": 2703,
    "preview": "package graphql\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/99designs/gqlgen/graphql/han"
  },
  {
    "path": "app/graphql/provider.go",
    "chars": 998,
    "preview": "package graphql\n\nimport (\n\t\"context\"\n\n\t\"github.com/aristat/golang-example-app/app/graphql_resolver\"\n\n\t\"github.com/arista"
  },
  {
    "path": "app/graphql_resolver/injector.go",
    "chars": 638,
    "preview": "// +build wireinject\n\npackage graphql_resolver\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/db\"\n\t\"github.com/ar"
  },
  {
    "path": "app/graphql_resolver/mock.go",
    "chars": 630,
    "preview": "package graphql_resolver\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/aristat/golang-example-app/generated/resources/proto/"
  },
  {
    "path": "app/graphql_resolver/product.go",
    "chars": 2004,
    "preview": "package graphql_resolver\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/aristat/golang-example-app/app/dataloader\"\n\n\t\"github"
  },
  {
    "path": "app/graphql_resolver/product_test.go",
    "chars": 1736,
    "preview": "package graphql_resolver_test\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"log\"\n\t\"net\"\n\t\"os\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github."
  },
  {
    "path": "app/graphql_resolver/provider.go",
    "chars": 953,
    "preview": "package graphql_resolver\n\nimport (\n\t\"context\"\n\n\t\"github.com/casbin/casbin\"\n\n\t\"github.com/aristat/golang-example-app/app/"
  },
  {
    "path": "app/graphql_resolver/resolver.go",
    "chars": 2070,
    "preview": "package graphql_resolver\n\nimport (\n\t\"context\"\n\t\"strings\"\n\n\t\"github.com/pkg/errors\"\n\n\t\"github.com/99designs/gqlgen/graphq"
  },
  {
    "path": "app/graphql_resolver/resolver_gen.go",
    "chars": 25,
    "preview": "package graphql_resolver\n"
  },
  {
    "path": "app/graphql_resolver/user.go",
    "chars": 1623,
    "preview": "package graphql_resolver\n\nimport (\n\t\"context\"\n\n\t\"github.com/aristat/golang-example-app/app/common\"\n\n\tgraphql1 \"github.co"
  },
  {
    "path": "app/graphql_resolver/user_test.go",
    "chars": 2192,
    "preview": "package graphql_resolver_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/spf13/cast\"\n\n\t\"golang.org/x/crypto/bcrypt\"\n\n"
  },
  {
    "path": "app/graphql_resolver/wire_gen.go",
    "chars": 6760,
    "preview": "// Code generated by Wire. DO NOT EDIT.\n\n//go:generate go run github.com/google/wire/cmd/wire\n//go:build !wireinject\n// "
  },
  {
    "path": "app/grpc/connection.go",
    "chars": 641,
    "preview": "package grpc\n\nimport (\n\t\"sync\"\n\n\t\"google.golang.org/grpc\"\n)\n\nvar (\n\tsrvMu   sync.Mutex\n\tpoolSrv = map[string]*Pool{}\n)\n\n"
  },
  {
    "path": "app/grpc/manager.go",
    "chars": 2033,
    "preview": "package grpc\n\nimport (\n\t\"context\"\n\t\"errors\"\n\n\t\"go.opentelemetry.io/otel/propagation\"\n\n\t\"go.opentelemetry.io/contrib/inst"
  },
  {
    "path": "app/grpc/pool.go",
    "chars": 2169,
    "preview": "package grpc\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/pkg/errors\"\n\tgrpcpool \"github.com/processout/grpc-go-poo"
  },
  {
    "path": "app/grpc/provider.go",
    "chars": 1327,
    "preview": "package grpc\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n\n\ttracesdk \"go.opentelemetry.io/otel/sdk/trace\"\n\n\t\"github.com/aristat/"
  },
  {
    "path": "app/http/http.go",
    "chars": 1177,
    "preview": "package http\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"sync\"\n\n\t\"github.com/go-chi/chi/v5\"\n\n\t\"github.com/go-session/session\"\n\n\t\""
  },
  {
    "path": "app/http/injector.go",
    "chars": 712,
    "preview": "// +build wireinject\n\npackage http\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/auth\"\n\t\"github.com/aristat/gola"
  },
  {
    "path": "app/http/logger.go",
    "chars": 701,
    "preview": "package http\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/go-chi/chi/"
  },
  {
    "path": "app/http/provider.go",
    "chars": 1885,
    "preview": "package http\n\nimport (\n\t\"context\"\n\n\t\"github.com/riandyrn/otelchi\"\n\n\t\"github.com/aristat/golang-example-app/app/dataloade"
  },
  {
    "path": "app/http/wire_gen.go",
    "chars": 7770,
    "preview": "// Code generated by Wire. DO NOT EDIT.\n\n//go:generate go run github.com/google/wire/cmd/wire\n//go:build !wireinject\n// "
  },
  {
    "path": "app/http_routers/products-router/injector.go",
    "chars": 369,
    "preview": "// +build wireinject\n\npackage products_router\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/provider\"\n\t\"github.c"
  },
  {
    "path": "app/http_routers/products-router/manager.go",
    "chars": 726,
    "preview": "package products_router\n\nimport (\n\t\"context\"\n\n\t\"github.com/aristat/golang-example-app/app/grpc\"\n\t\"github.com/aristat/gol"
  },
  {
    "path": "app/http_routers/products-router/provider.go",
    "chars": 923,
    "preview": "package products_router\n\nimport (\n\t\"context\"\n\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/google/wi"
  },
  {
    "path": "app/http_routers/products-router/router.go",
    "chars": 2482,
    "preview": "package products_router\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/nats-io/stan.go\"\n\n\t\"gith"
  },
  {
    "path": "app/http_routers/products-router/router_test.go",
    "chars": 1902,
    "preview": "package products_router_test\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"os\"\n\t\"strconv\"\n\t\"stri"
  },
  {
    "path": "app/http_routers/products-router/wire_gen.go",
    "chars": 3857,
    "preview": "// Code generated by Wire. DO NOT EDIT.\n\n//go:generate go run github.com/google/wire/cmd/wire\n//go:build !wireinject\n// "
  },
  {
    "path": "app/logger/injector.go",
    "chars": 523,
    "preview": "// +build wireinject\n\npackage logger\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/config\"\n\t\"github.com/aristat/"
  },
  {
    "path": "app/logger/logger.go",
    "chars": 3148,
    "preview": "package logger\n\ntype (\n\tFields map[string]interface{}\n)\n\n// Level represent RFC5424 logger severity\ntype Level int8\n\n// "
  },
  {
    "path": "app/logger/middleware.go",
    "chars": 2890,
    "preview": "package logger\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"time\"\n\n\t\"google.golang.org/grpc\"\n)\n\n// UnaryClientInterceptor wrapper t"
  },
  {
    "path": "app/logger/mock.go",
    "chars": 3089,
    "preview": "package logger\n\nimport (\n\t\"context\"\n)\n\n// Entity represent log struct with all assets\ntype Entity struct {\n\tLevel  Level"
  },
  {
    "path": "app/logger/provider.go",
    "chars": 1290,
    "preview": "package logger\n\nimport (\n\t\"context\"\n\n\t\"github.com/google/wire\"\n\t\"github.com/spf13/viper\"\n)\n\n// ProviderCfg returns confi"
  },
  {
    "path": "app/logger/wire_gen.go",
    "chars": 1423,
    "preview": "// Code generated by Wire. DO NOT EDIT.\n\n//go:generate go run github.com/google/wire/cmd/wire\n//go:build !wireinject\n// "
  },
  {
    "path": "app/logger/zap.go",
    "chars": 3836,
    "preview": "package logger\n\nimport (\n\t\"context\"\n\n\t\"go.uber.org/zap/zapcore\"\n\n\t\"go.uber.org/zap\"\n)\n\n// Zap is uber/zap logger impleme"
  },
  {
    "path": "app/provider/provider.go",
    "chars": 753,
    "preview": "package provider\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/casbin\"\n\t\"github.com/aristat/golang-example-app/a"
  },
  {
    "path": "app/tracing/jaeger.go",
    "chars": 1245,
    "preview": "package tracing\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/exporters/jaeger\"\n\t\"go.opentelemetry.io/otel/sdk/resour"
  },
  {
    "path": "app/tracing/provider.go",
    "chars": 1094,
    "preview": "package tracing\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/propagation\"\n\n\t\"github.com/google/wire\"\n\t\"github.com/sp"
  },
  {
    "path": "cmd/daemon/daemon.go",
    "chars": 1794,
    "preview": "package daemon\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"os/signal\"\n\t\"sync\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/aristat/golang-example-a"
  },
  {
    "path": "cmd/health-check-service/health_check_service.go",
    "chars": 3104,
    "preview": "package health_check_service\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"math/rand\"\n\t\"net\"\n\t\"time\"\n\n\t\"go.opentelemetry.io/otel/propaga"
  },
  {
    "path": "cmd/jwt/jwt.go",
    "chars": 226,
    "preview": "package jwt\n\nimport \"github.com/spf13/cobra\"\n\nvar Cmd = &cobra.Command{\n\tUse:           \"jwt\",\n\tShort:         \"Tools fo"
  },
  {
    "path": "cmd/jwt/token.go",
    "chars": 2410,
    "preview": "package jwt\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/spf13/cast\"\n\n\t\"github.com/golang-"
  },
  {
    "path": "cmd/migrate/migrate.go",
    "chars": 2236,
    "preview": "package migrate\n\nimport (\n\t\"database/sql\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/aristat/golang-example-app/app/entrypoint\"\n\t_ \"gith"
  },
  {
    "path": "cmd/product-service/nats_service.go",
    "chars": 311,
    "preview": "package product_service\n\nimport (\n\t\"github.com/aristat/golang-example-app/app/logger\"\n\t\"github.com/nats-io/stan.go\"\n)\n\nt"
  },
  {
    "path": "cmd/product-service/product_service.go",
    "chars": 4803,
    "preview": "package product_service\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"log\"\n\t\"net\"\n\t\"time\"\n\n\t\"go.opentelemetry.io/otel/propagation\"\n\n\t"
  },
  {
    "path": "cmd/root.go",
    "chars": 2640,
    "preview": "package cmd\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/signal\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"syscall\"\n\n\t\"gith"
  },
  {
    "path": "dbconfig.yml",
    "chars": 153,
    "preview": "development:\n    dialect: postgres\n    datasource: dbname=golang_example_development sslmode=disable\n    dir: resources/"
  },
  {
    "path": "docker/app/Dockerfile",
    "chars": 516,
    "preview": "FROM golang:1.17.9-alpine3.15 as builder\n\nRUN apk add --update make \\\n    && rm -rf /tmp/* \\\n    && rm -rf /var/cache/ap"
  },
  {
    "path": "docker/app/files/docker/bin/entrypoint.sh",
    "chars": 35,
    "preview": "#!/usr/bin/env sh\n\nexec ./bin \"$@\"\n"
  },
  {
    "path": "docker-compose.yml",
    "chars": 2050,
    "preview": "version: '3.7'\nservices:\n  jaeger:\n    image: jaegertracing/all-in-one:latest\n    networks:\n      - intranet\n    ports:\n"
  },
  {
    "path": "generated/graphql/generated.go",
    "chars": 99100,
    "preview": "// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.\n\npackage graphql\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n"
  },
  {
    "path": "generated/graphql/models_gen.go",
    "chars": 2653,
    "preview": "// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.\n\npackage graphql\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\n\t\"git"
  },
  {
    "path": "generated/resources/proto/health_checks/health_checks.pb.go",
    "chars": 8533,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.27.1\n// \tprotoc        v3.17.3\n// sou"
  },
  {
    "path": "generated/resources/proto/health_checks/health_checks_grpc.pb.go",
    "chars": 3668,
    "preview": "// Code generated by protoc-gen-go-grpc. DO NOT EDIT.\n\npackage health_checks\n\nimport (\n\tcontext \"context\"\n\tgrpc \"google."
  },
  {
    "path": "generated/resources/proto/products/products.pb.go",
    "chars": 12199,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.27.1\n// \tprotoc        v3.17.3\n// sou"
  },
  {
    "path": "generated/resources/proto/products/products_grpc.pb.go",
    "chars": 3504,
    "preview": "// Code generated by protoc-gen-go-grpc. DO NOT EDIT.\n\npackage products\n\nimport (\n\tcontext \"context\"\n\tgrpc \"google.golan"
  },
  {
    "path": "go.mod",
    "chars": 1703,
    "preview": "module github.com/aristat/golang-example-app\n\nrequire (\n\tgithub.com/99designs/gqlgen v0.12.2\n\tgithub.com/agnivade/levens"
  },
  {
    "path": "go.sum",
    "chars": 92294,
    "preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1"
  },
  {
    "path": "gqlgen.yml",
    "chars": 596,
    "preview": "schema:\n  - \"resources/graphql/*.graphql\"\n\nexec:\n  filename: generated/graphql/generated.go\n\nmodel:\n  filename: generate"
  },
  {
    "path": "main.go",
    "chars": 97,
    "preview": "package main\n\nimport \"github.com/aristat/golang-example-app/cmd\"\n\nfunc main() {\n\tcmd.Execute()\n}\n"
  },
  {
    "path": "prototool.yaml",
    "chars": 211,
    "preview": "protoc:\n  version: 3.8.0\n\ngenerate:\n  go_options:\n    import_path: github.com/aristat/golang-example-app\n\n  plugins:\n   "
  },
  {
    "path": "resources/casbin/model.conf",
    "chars": 224,
    "preview": "[request_definition]\nr = sub, obj, act\n\n[policy_definition]\np = sub, obj, act\n\n[role_definition]\ng = _, _\n\n[policy_effec"
  },
  {
    "path": "resources/casbin/policy.csv",
    "chars": 85,
    "preview": "p, reader, users, read\np, owner, users, write\n\ng, reader, anonymous\ng, owner, reader\n"
  },
  {
    "path": "resources/configs/development.yaml",
    "chars": 957,
    "preview": "session:\n  redisUrl: localhost:6379\n  redisDB: 10\ndb:\n  url: postgresql://localhost:5432/golang_example_development?sslm"
  },
  {
    "path": "resources/configs/docker_development.yaml",
    "chars": 969,
    "preview": "session:\n  redisUrl: redis:6379\n  redisDB: 10\ndb:\n  url: postgres://postgres@postgres:5432/golang_example_development?ss"
  },
  {
    "path": "resources/graphql/products.graphql",
    "chars": 236,
    "preview": "type ProductsQuery {\n    list: ProductsListOut!\n}\n\ntype Product {\n    id: ID!\n    name: String!\n    productItems: [Produ"
  },
  {
    "path": "resources/graphql/root.graphql",
    "chars": 109,
    "preview": "type Query {\n    users: UsersQuery\n    products: ProductsQuery\n}\n\ntype Mutation {\n    users: UsersMutation\n}\n"
  },
  {
    "path": "resources/graphql/user.graphql",
    "chars": 583,
    "preview": "type UsersOneOut {\n    id: ID!\n    email: String!\n}\n\ntype UsersQuery {\n    one(email: String!): UsersOneOut! @hasUsersPe"
  },
  {
    "path": "resources/keys/local/private_key.pem",
    "chars": 1679,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEA0yucnZD57YJ5bPjdZfltW1sObqjT89R6fiHJRkwtA29COZro\nH+I2ZNtXJ6Y5zOuE4DVgeCR"
  },
  {
    "path": "resources/keys/local/public_key.pem",
    "chars": 451,
    "preview": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0yucnZD57YJ5bPjdZflt\nW1sObqjT89R6fiHJRkwtA29COZro"
  },
  {
    "path": "resources/migrations/20181215164636-create_users.sql",
    "chars": 248,
    "preview": "\n-- +migrate Up\n\nCREATE TABLE users(\n    id SERIAL PRIMARY KEY,\n    email VARCHAR(255) NOT NULL DEFAULT '',\n    encrypte"
  },
  {
    "path": "resources/migrations/20181216210607-records.sql",
    "chars": 245,
    "preview": "\n-- +migrate Up\n\n-- password: 123456789\nINSERT INTO users (email, encrypted_password) VALUES ('test@gmail.com', '$2a$10$"
  },
  {
    "path": "resources/proto/health_checks/health_checks.proto",
    "chars": 358,
    "preview": "syntax = \"proto3\";\n\npackage health_checks;\n\nimport \"google/protobuf/empty.proto\";\n\noption go_package=\"github.com/aristat"
  },
  {
    "path": "resources/proto/products/products.proto",
    "chars": 452,
    "preview": "syntax = \"proto3\";\n\npackage products;\n\noption go_package=\"github.com/aristat/golang-example-app/products\";\n\nmessage Prod"
  },
  {
    "path": "resources/templates/helpers/errors.html",
    "chars": 165,
    "preview": "{{ define \"errors\" }}\n    {{if .errors }}\n        {{range .errors}}\n            <h1>\n                {{ . }}\n           "
  },
  {
    "path": "scripts/docker-compose-start.sh",
    "chars": 136,
    "preview": "#!/bin/bash\n\ndocker-compose rm\nREMOVE_CONTAINERS=on DOCKER_IMAGE=golang-example-app TAG=development make docker-image\ndo"
  },
  {
    "path": "scripts/remove_docker_containers.sh",
    "chars": 324,
    "preview": "#!/bin/bash\n\necho \"Start removing containers\"\n\nif [ \"$REMOVE_CONTAINERS\" == ON ]; then\n  docker_containers=$(docker ps -"
  }
]

About this extraction

This page contains the full source code of the Aristat/golang-example-app GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 106 files (354.4 KB), approximately 132.3k tokens, and a symbol index with 527 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!