Merge branch 'develop' into feature/product-app

This commit is contained in:
hossein 2026-04-29 05:03:01 +00:00
commit f021c559bb
31 changed files with 458 additions and 0 deletions

View File

View File

View File

View File

@ -0,0 +1,11 @@
package mysql
import "git.gocasts.ir/ebhomengo/niki/repository/mysql"
type DB struct {
conn *mysql.DB
}
func New(db *mysql.DB) *DB {
return &DB{conn: db}
}

View File

@ -0,0 +1 @@
package mysql

View File

@ -0,0 +1,8 @@
package service
type Service struct {
repo Repo
}
type Repo interface {
}

View File

@ -0,0 +1,28 @@
package entity
import "time"
type Transaction struct {
ID uint64
UserID uint64
Amount float64
Currency Currency
ActionType TransactionType
Timestamp time.Time
}
type TransactionType string
const (
TransactionTypeDeposit TransactionType = "deposit"
TransactionTypeWithdraw TransactionType = "withdraw"
TransactionTypeRefund TransactionType = "refund"
TransactionTypeDonate TransactionType = "donate"
)
type Currency string
const (
IRR Currency = "IRR"
USD Currency = "USD"
)

View File

@ -0,0 +1,23 @@
package entity
import "time"
type Wallet struct {
ID uint64
UserID uint64 // user unique ID
Balance float64
Currency Currency
UpdatedAt time.Time
Status WalletStatus // "active", "frozen", "closed"
}
type WalletStatus string
const (
Frozen WalletStatus = "frozen" // when need to check , approve ,validate , solve sth (but deposit is possible)
Active WalletStatus = "active" // when everything is ok
// ??
// Closed WalletStatus = "closed" // when need to check , approve ,validate , solve sth (exp : security problem)
)

View File

@ -0,0 +1,15 @@
package param
import (
"git.gocasts.ir/ebhomengo/niki/domain/wallet/entity"
)
type CreateTransactionRequest struct {
UserID uint64 `json:"user_id"`
Amount float64 `json:"amount"`
Currency entity.Currency `json:"currency"`
ActionType entity.TransactionType `json:"action_type"`
}
type InsertTransactionResponse struct {
}

View File

@ -0,0 +1,24 @@
package param
import (
"time"
"git.gocasts.ir/ebhomengo/niki/domain/wallet/entity"
)
type TransactionRequest struct {
UserID uint64 `json:"user_id"`
}
type TransactionResponse struct {
Transaction []TransactionInfo `json:"transaction"`
}
type TransactionInfo struct {
ID uint64 `json:"id"`
UserID uint64 `json:"user_id"`
Amount float64 `json:"amount"`
Currency entity.Currency `json:"currency"`
ActionType entity.TransactionType `json:"action_type"`
Timestamp time.Time `json:"timestamp"`
}

View File

@ -0,0 +1,21 @@
package param
import (
"time"
"git.gocasts.ir/ebhomengo/niki/domain/wallet/entity"
)
type WalletRequest struct {
UserID uint64 `json:"user_id"`
}
type WalletResponse struct {
Wallet WalletInfo `json:"wallet"`
}
type WalletInfo struct {
Balance float64 `json:"balance"`
UpdatedAt time.Time `json:"updated_at"`
Status entity.WalletStatus `json:"status"`
}

View File

@ -0,0 +1,11 @@
package postgres
import "git.gocasts.ir/ebhomengo/niki/pkg/database/postgres"
type DB struct {
conn *postgres.DB
}
func New(conn *postgres.DB) *DB {
return &DB{conn: conn}
}

View File

@ -0,0 +1,5 @@
production:
dialect: postgres
datasource: "host=127.0.0.1 port=5432 user=wallet password=wallet2123 dbname=wallet_db sslmode=disable"
dir: domain/wallet/repository/postgres/migrations
table: wallet_migrationsns

View File

@ -0,0 +1,31 @@
package service
import (
"context"
"time"
"git.gocasts.ir/ebhomengo/niki/domain/wallet/entity"
"git.gocasts.ir/ebhomengo/niki/domain/wallet/param"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
func (s Service) CreateTransaction(ctx context.Context, request param.CreateTransactionRequest) (param.InsertTransactionResponse, error) {
const op = richerror.Op("wallet.service.CreateTransaction")
transaction := entity.Transaction{
ID: 0,
UserID: request.UserID,
Amount: request.Amount,
Currency: request.Currency,
ActionType: request.ActionType,
Timestamp: time.Now(),
}
err := s.repo.InsertTransaction(ctx, transaction)
if err != nil {
return param.InsertTransactionResponse{}, err
}
return param.InsertTransactionResponse{}, nil
}

View File

@ -0,0 +1,27 @@
package service
import (
"context"
"git.gocasts.ir/ebhomengo/niki/domain/wallet/entity"
)
type Repository interface {
GetTransactionListByUserID(ctx context.Context, UserID uint64) ([]entity.Transaction, error)
GetWalletByUserID(ctx context.Context, UserID uint64) (entity.Wallet, error)
InsertTransaction(ctx context.Context, transaction entity.Transaction) error
}
type Config struct {
}
type Service struct {
repo Repository
cfg Config
}
func New(repo Repository, cfg Config) Service {
return Service{repo: repo, cfg: cfg}
}

View File

@ -0,0 +1,39 @@
package service
import (
"context"
"git.gocasts.ir/ebhomengo/niki/domain/wallet/entity"
"git.gocasts.ir/ebhomengo/niki/domain/wallet/param"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
func (s Service) GetUserTransactionHistory(ctx context.Context, request param.TransactionRequest) (param.TransactionResponse, error) {
const op = richerror.Op("wallet.service.GetUserTransactionHistory")
transactionList, err := s.repo.GetTransactionListByUserID(ctx, request.UserID)
if err != nil {
return param.TransactionResponse{}, err
}
return param.TransactionResponse{Transaction: transactionEntityToTransactionInfo(transactionList)}, nil
}
func transactionEntityToTransactionInfo(TransactionList []entity.Transaction) []param.TransactionInfo {
transactionInfoList := make([]param.TransactionInfo, len(TransactionList))
for i, transaction := range TransactionList {
transactionInfoList[i] = param.TransactionInfo{
ID: transaction.ID,
UserID: transaction.UserID,
Amount: transaction.Amount,
Currency: transaction.Currency,
ActionType: transaction.ActionType,
Timestamp: transaction.Timestamp,
}
}
return transactionInfoList
}

View File

@ -0,0 +1,27 @@
package service
import (
"context"
"git.gocasts.ir/ebhomengo/niki/domain/wallet/param"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
func (s Service) GetUserWallet(ctx context.Context, request param.WalletRequest) (param.WalletResponse, error) {
const op = richerror.Op("wallet.service.GetUserWallet")
wallet, err := s.repo.GetWalletByUserID(ctx, request.UserID)
if err != nil {
return param.WalletResponse{}, err
}
return param.WalletResponse{
Wallet: param.WalletInfo{
Balance: wallet.Balance,
UpdatedAt: wallet.UpdatedAt,
Status: wallet.Status,
},
}, nil
}

11
gamificationapp/app.go Normal file
View File

@ -0,0 +1,11 @@
package gamificationapp
type Application struct {
Config Config
}
func setUp(cnf Config) *Application {
return &Application{
cnf,
}
}

View File

@ -0,0 +1,4 @@
package gamificationapp
type Config struct {
}

View File

@ -0,0 +1,15 @@
package gamification
import (
gamification "git.gocasts.ir/ebhomengo/niki/domain/gamification/service"
)
type Handler struct {
GamificationSvc gamification.Service
}
func New(gamificationSvc gamification.Service) *Handler {
return &Handler{
GamificationSvc: gamificationSvc,
}
}

View File

@ -0,0 +1,7 @@
package gamification
import "github.com/labstack/echo/v4"
func (h Handler) SetRoutes(e *echo.Echo) {
}

View File

@ -0,0 +1,13 @@
package http
import "git.gocasts.ir/ebhomengo/niki/gamificationapp/delivery/http/gamification"
type Server struct {
gamificationHandler *gamification.Handler
}
func New(handler gamification.Handler) *Server {
return &Server{
gamificationHandler: &handler,
}
}

View File

@ -0,0 +1,97 @@
package postgres
import (
"context"
"database/sql"
"fmt"
"sync"
"time"
querier "git.gocasts.ir/ebhomengo/niki/pkg/query_transaction/sql"
_ "github.com/jackc/pgx/v5/stdlib"
)
type Config struct {
Host string `koanf:"host"`
Port int `koanf:"port"`
User string `koanf:"user"`
Password string `koanf:"password"`
DbName string `koanf:"dbName"`
SSLMode string `koanf:"sslMode"`
MaxIdleConn int `koanf:"maxIdleConns"`
MaxOpenConn int `koanf:"maxOpenConns"`
ConnMaxLifetime int `koanf:"connMaxLifetime"`
PathOfMigrations string `koanf:"pathOfMigrations"`
}
type DB struct {
config Config
db *querier.SQLDB
mu sync.Mutex
statements map[statementKey]*sql.Stmt
}
func (db *DB) Conn() *querier.SQLDB {
return db.db
}
func New(config Config) *DB {
dsn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s",
config.Host, config.Port, config.User, config.Password, config.DbName, config.SSLMode)
db, err := sql.Open("pgx", dsn)
if err != nil {
panic(fmt.Errorf("can't open postgres db: %w", err))
}
maxIdle := config.MaxIdleConn
maxOpen := config.MaxOpenConn
lifetime := time.Duration(config.ConnMaxLifetime) * time.Second
db.SetMaxIdleConns(maxIdle)
db.SetMaxOpenConns(maxOpen)
db.SetConnMaxLifetime(lifetime)
return &DB{
config: config,
db: &querier.SQLDB{DB: db},
statements: make(map[statementKey]*sql.Stmt),
}
}
func (db *DB) PrepareStatement(ctx context.Context, key statementKey, query string) (*sql.Stmt, error) {
db.mu.Lock()
defer db.mu.Unlock()
if stmt, ok := db.statements[key]; ok {
return stmt, nil
}
stmt, err := db.db.PrepareContext(ctx, query)
if err != nil {
return nil, fmt.Errorf("prepare statement %q: %w", key, err)
}
db.statements[key] = stmt
return stmt, nil
}
func (db *DB) CloseStatements() error {
db.mu.Lock()
defer db.mu.Unlock()
var lastErr error
for key, stmt := range db.statements {
if err := stmt.Close(); err != nil {
lastErr = err
}
delete(db.statements, key)
}
return lastErr
}
func (db *DB) Close() error {
return db.db.DB.Close()
}

View File

@ -0,0 +1 @@
package migrator

View File

@ -0,0 +1,9 @@
package postgres
type statementKey uint
const (
StatementKeyAWalletGetTransactionHistory statementKey = iota + 1
StatementKeyWalletInsertTransaction
StatementKeyWalletGetUserWallet
)

12
walletapp/app.go Normal file
View File

@ -0,0 +1,12 @@
package walletapp
type Application struct {
}
func SetUp() {
}
func (app Application) StartServer() {}
func (app Application) StopServer() {}

15
walletapp/config.go Normal file
View File

@ -0,0 +1,15 @@
package walletapp
import (
"git.gocasts.ir/ebhomengo/niki/adapter/redis"
"git.gocasts.ir/ebhomengo/niki/domain/shoppingbasket/repository"
"git.gocasts.ir/ebhomengo/niki/pkg/httpserver"
logger "git.gocasts.ir/ebhomengo/niki/pkg/logger"
)
type Config struct {
Redis redis.Config `koanf:"redis" json:"redis"`
Repo repository.Config `koanf:"repo" json:"repo"`
HTTPServer httpserver.Config `koanf:"http_server" json:"http_server"`
Logger logger.Config `koanf:"logger" json:"logger"`
}

View File

@ -0,0 +1 @@
package httpserver

View File

@ -0,0 +1 @@
package httpserver

View File

@ -0,0 +1 @@
package transaction