Handlers, DB, Cache
This commit is contained in:
39
internal/service/cache/cache_service.go
vendored
Normal file
39
internal/service/cache/cache_service.go
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/jellydator/ttlcache/v3"
|
||||
|
||||
"payouts/internal/service/database/orm"
|
||||
)
|
||||
|
||||
type cacheService struct {
|
||||
cache *ttlcache.Cache[string, orm.User]
|
||||
}
|
||||
|
||||
func NewSessionCache(ttl time.Duration) (Service, error) {
|
||||
return &cacheService{
|
||||
cache: ttlcache.New(ttlcache.WithTTL[string, orm.User](ttl)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// PutSession implements [Service].
|
||||
func (c *cacheService) PutSession(sessionID string, user orm.User) {
|
||||
c.cache.Set(sessionID, user, ttlcache.DefaultTTL)
|
||||
}
|
||||
|
||||
// GetUserFromSession implements [Service].
|
||||
func (c *cacheService) GetSession(sessionId string) (orm.User, error) {
|
||||
if !c.cache.Has(sessionId) {
|
||||
return orm.User{}, NoSessionFound
|
||||
}
|
||||
cachedItem := c.cache.Get(sessionId)
|
||||
|
||||
return cachedItem.Value(), nil
|
||||
}
|
||||
|
||||
// StartBackground implements [Service].
|
||||
func (c *cacheService) StartBackground() {
|
||||
c.cache.Start()
|
||||
}
|
||||
7
internal/service/cache/config/cache.go
vendored
Normal file
7
internal/service/cache/config/cache.go
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
package config
|
||||
|
||||
import "time"
|
||||
|
||||
type Cache struct {
|
||||
TTL time.Duration
|
||||
}
|
||||
50
internal/service/cache/module.go
vendored
Normal file
50
internal/service/cache/module.go
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"go.uber.org/fx"
|
||||
|
||||
"payouts/internal/config"
|
||||
"payouts/internal/service/database/orm"
|
||||
)
|
||||
|
||||
var Module = fx.Options(
|
||||
fx.Provide(New),
|
||||
|
||||
fx.Invoke(StartCache),
|
||||
)
|
||||
|
||||
var NoSessionFound = errors.New("no session found")
|
||||
|
||||
type Service interface {
|
||||
PutSession(string, orm.User)
|
||||
GetSession(string) (orm.User, error)
|
||||
StartBackground()
|
||||
}
|
||||
|
||||
type Params struct {
|
||||
fx.In
|
||||
|
||||
AppConfig *config.App
|
||||
}
|
||||
|
||||
func New(p Params) (Service, error) {
|
||||
return NewSessionCache(p.AppConfig.Cache.TTL)
|
||||
}
|
||||
|
||||
// RegisterRoutes registers the api routes and starts the http server
|
||||
func StartCache(s Service, lc fx.Lifecycle) {
|
||||
lc.Append(fx.Hook{
|
||||
OnStart: func(c context.Context) error {
|
||||
go func() {
|
||||
s.StartBackground()
|
||||
}()
|
||||
return nil
|
||||
},
|
||||
OnStop: func(ctx context.Context) error {
|
||||
return nil
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
package config
|
||||
|
||||
type Database struct {
|
||||
Type string
|
||||
Connection string
|
||||
LogLevel string
|
||||
Type string
|
||||
Connection string
|
||||
LogLevel string
|
||||
TraceRequests bool
|
||||
}
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
|
||||
slogGorm "github.com/orandin/slog-gorm"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"payouts/internal/service/database/config"
|
||||
"payouts/internal/service/database/orm"
|
||||
)
|
||||
|
||||
type dbService struct {
|
||||
@@ -14,31 +19,67 @@ type dbService struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewDatabaseService(dbType, connection, logLevel string) (DatabaseService, error) {
|
||||
func NewDatabaseService(conf config.Database) (Service, error) {
|
||||
|
||||
var dialector gorm.Dialector
|
||||
switch dbType {
|
||||
switch conf.Type {
|
||||
case "sqlite":
|
||||
dialector = sqlite.Open(connection)
|
||||
dialector = sqlite.Open(conf.Connection)
|
||||
case "postgres":
|
||||
dialector = postgres.Open(connection)
|
||||
dialector = postgres.Open(conf.Connection)
|
||||
default:
|
||||
return nil, errors.New("unknown dbType")
|
||||
}
|
||||
|
||||
level := slog.LevelInfo
|
||||
level.UnmarshalText([]byte(conf.LogLevel))
|
||||
|
||||
slogGormOpts := []slogGorm.Option{
|
||||
slogGorm.SetLogLevel(slogGorm.DefaultLogType, level),
|
||||
}
|
||||
if conf.TraceRequests {
|
||||
slogGormOpts = append(slogGormOpts, slogGorm.WithTraceAll())
|
||||
}
|
||||
|
||||
slogGorm := slogGorm.New(slogGormOpts...)
|
||||
|
||||
db, err := gorm.Open(dialector, &gorm.Config{
|
||||
Logger: slogGorm.New(),
|
||||
Logger: slogGorm,
|
||||
})
|
||||
|
||||
if err == nil {
|
||||
db.DB()
|
||||
db.AutoMigrate()
|
||||
// db.LogMode(true)
|
||||
db.AutoMigrate(&orm.User{})
|
||||
}
|
||||
result := &dbService{}
|
||||
result.dbType = dbType
|
||||
result.dbType = conf.Type
|
||||
result.db = db
|
||||
|
||||
return result, err
|
||||
|
||||
}
|
||||
|
||||
func getParams(options ...Optional) *params {
|
||||
params := ¶ms{
|
||||
ctx: context.Background(),
|
||||
}
|
||||
for _, opt := range options {
|
||||
opt(params)
|
||||
}
|
||||
return params
|
||||
}
|
||||
|
||||
// AddUser implements [Service].
|
||||
func (d *dbService) CreateUser(userModel orm.User, opts ...Optional) error {
|
||||
p := getParams(opts...)
|
||||
|
||||
return gorm.G[orm.User](d.db).Create(p.ctx, &userModel)
|
||||
}
|
||||
|
||||
// GetUser implements [Service].
|
||||
func (d *dbService) GetUser(userModel orm.User, opts ...Optional) (orm.User, error) {
|
||||
p := getParams(opts...)
|
||||
|
||||
userResp, err := gorm.G[orm.User](d.db).Where(&userModel).First(p.ctx)
|
||||
return userResp, err
|
||||
}
|
||||
|
||||
@@ -1,16 +1,32 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"payouts/internal/config"
|
||||
"context"
|
||||
|
||||
"go.uber.org/fx"
|
||||
|
||||
"payouts/internal/config"
|
||||
"payouts/internal/service/database/orm"
|
||||
)
|
||||
|
||||
var Module = fx.Options(
|
||||
fx.Provide(New),
|
||||
)
|
||||
|
||||
type DatabaseService interface {
|
||||
type params struct {
|
||||
ctx context.Context
|
||||
}
|
||||
type Optional func(*params)
|
||||
|
||||
func WithContext(ctx context.Context) Optional {
|
||||
return func(p *params) {
|
||||
p.ctx = ctx
|
||||
}
|
||||
}
|
||||
|
||||
type Service interface {
|
||||
CreateUser(user orm.User, opts ...Optional) error
|
||||
GetUser(user orm.User, opts ...Optional) (orm.User, error)
|
||||
}
|
||||
|
||||
// Params represents the module input params
|
||||
@@ -21,6 +37,6 @@ type Params struct {
|
||||
}
|
||||
|
||||
// NewPersistence instantiates the persistence module
|
||||
func New(p Params) (DatabaseService, error) {
|
||||
return NewDatabaseService(p.AppConfig.Database.Type, p.AppConfig.Database.Connection, p.AppConfig.Database.LogLevel)
|
||||
func New(p Params) (Service, error) {
|
||||
return NewDatabaseService(p.AppConfig.Database)
|
||||
}
|
||||
|
||||
10
internal/service/database/orm/user.go
Normal file
10
internal/service/database/orm/user.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package orm
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type User struct {
|
||||
gorm.Model
|
||||
TIN string
|
||||
Phone string `gorm:"uniqueIndex:idx_phone"`
|
||||
PasswdHash string
|
||||
}
|
||||
10
internal/service/yookassa/config/yookassa.go
Normal file
10
internal/service/yookassa/config/yookassa.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package config
|
||||
|
||||
type YooKassa struct {
|
||||
BaseUrl string
|
||||
|
||||
ApiBaseKey string
|
||||
ApiBaseSecret string
|
||||
ApiPaymentKey string
|
||||
ApiPaymentSecret string
|
||||
}
|
||||
37
internal/service/yookassa/module.go
Normal file
37
internal/service/yookassa/module.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package yookassa
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.uber.org/fx"
|
||||
|
||||
"payouts/internal/config"
|
||||
)
|
||||
|
||||
var Module = fx.Options(
|
||||
fx.Provide(New),
|
||||
)
|
||||
|
||||
type params struct {
|
||||
ctx context.Context
|
||||
}
|
||||
type Optional func(*params)
|
||||
|
||||
func WithContext(ctx context.Context) Optional {
|
||||
return func(p *params) {
|
||||
p.ctx = ctx
|
||||
}
|
||||
}
|
||||
|
||||
type Service interface {
|
||||
}
|
||||
|
||||
type Param struct {
|
||||
fx.In
|
||||
|
||||
AppConfig *config.App
|
||||
}
|
||||
|
||||
func New(p Param) (Service, error) {
|
||||
return NewYookassaService(p.AppConfig.YooKassa)
|
||||
}
|
||||
13
internal/service/yookassa/yookassa_service.go
Normal file
13
internal/service/yookassa/yookassa_service.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package yookassa
|
||||
|
||||
import "payouts/internal/service/yookassa/config"
|
||||
|
||||
type yookassaService struct {
|
||||
conf config.YooKassa
|
||||
}
|
||||
|
||||
func NewYookassaService(conf config.YooKassa) (Service, error) {
|
||||
return &yookassaService{
|
||||
conf: conf,
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user