Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add comments to exported functions #19

Merged
merged 2 commits into from
Oct 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
linters:
enable:
- revive

linters-settings:
revive:
rules:
- name: exported
arguments:
- disableStutteringCheck

issues:
include:
- EXC0012
- EXC0014
8 changes: 8 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,22 @@ import (
"github.com/ilyakaznacheev/cleanenv"
)

// Config represents the configuration for the application.
type Config struct {
HTTPServer `yaml:"http_server"`
Database `yaml:"database"`
TelegramBot `yaml:"telegram_bot"`
LogLevel string `yaml:"log_level" env-default:"Info" env:"LOG_LEVEL"`
}

// HTTPServer represents the configuration for the HTTP server.
type HTTPServer struct {
Address string `yaml:"address" env-default:"localhost:8080"`
Timeout time.Duration `yaml:"timeout" env-default:"4s" env:"TIMEOUT"`
IdleTimeout time.Duration `yaml:"idle_timeout" env-default:"60s" env:"IDLE_TIMEOUT"`
}

// Database represents the configuration for the PostgreSQL database.
type Database struct {
Host string `yaml:"host" env-default:"localhost" env:"DB_HOST"`
Port int64 `yaml:"port" env-default:"5432" env:"DB_PORT"`
Expand All @@ -29,10 +32,15 @@ type Database struct {
Password string `yaml:"password" env-required:"true" env:"DB_PASSWORD"`
}

// TelegramBot represents the configuration for the Telegram bot.
type TelegramBot struct {
Token string `yaml:"token" env-required:"true" env:"BOT_TOKEN"`
}

// MustLoad loads the configuration from the file specified in the CONFIG_PATH environment variable.
// It returns a pointer to the loaded Config struct.
// If CONFIG_PATH is not set or the file does not exist, it logs a fatal error.
// If there is an error reading the config file, it logs a fatal error.
func MustLoad() *Config {
configPath := os.Getenv("CONFIG_PATH")
if configPath == "" {
Expand Down
7 changes: 4 additions & 3 deletions internal/entities/chat.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package entities

// Chat represents a chat entity.
type Chat struct {
Id int64 `db:"id"`
CompanyId int64 `db:"company_id"`
TelegramId int64 `db:"telegram_id"`
Id int64 `db:"id"`
CompanyID int64 `db:"company_id"`
TelegramID int64 `db:"telegram_id"`
}
11 changes: 7 additions & 4 deletions internal/entities/company.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
package entities

// Company represents a company entity.
type Company struct {
Id int64 `db:"id"`
OwnerId int64 `db:"owner_id"`
ID int64 `db:"id"`
OwnerID int64 `db:"owner_id"`
Token string `db:"token"`
Name string `db:"name"`
Email string `db:"email"`
}

// CompanyRegistrationInfo represents the information needed to register a new company.
type CompanyRegistrationInfo struct {
Name string
Email string
Owner OwnerInfo
}

// CompanyInfo represents the information about a company.
type CompanyInfo struct {
Id int64
OwnerId int64
ID int64
OwnerID int64
Token string
Name string
Email string
Expand Down
8 changes: 8 additions & 0 deletions internal/entities/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ package entities

import "strings"

// Message represents a message to be sent to one or more chats.
type Message struct {
Text string
ParseMode ParseMode
Token string
ChatIds []int64
}

// ParseMode represents the parsing mode for a message.
type ParseMode string

var (
Expand All @@ -20,12 +22,17 @@ var (
)

const (
// Undefined represents an undefined parsing mode.
Undefined ParseMode = "Undefined"
// MarkdownV2 represents the MarkdownV2 parsing mode.
MarkdownV2 ParseMode = "MarkdownV2"
// Markdown represents the Markdown parsing mode.
Markdown ParseMode = "Markdown"
// HTML represents the HTML parsing mode.
HTML ParseMode = "HTML"
)

// String returns the string representation of the ParseMode.
func (pm ParseMode) String() string {
switch pm {
case MarkdownV2:
Expand All @@ -39,6 +46,7 @@ func (pm ParseMode) String() string {
}
}

// ParseString returns the ParseMode for the given string.
func ParseString(str string) ParseMode {
c, ok := parseModeMap[strings.ToLower(str)]
if !ok {
Expand Down
8 changes: 5 additions & 3 deletions internal/entities/owner.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package entities

// Owner represents the owner of a company.
type Owner struct {
Id int64 `db:"id"`
TelegramId int64 `db:"telegram_id"`
ID int64 `db:"id"`
TelegramID int64 `db:"telegram_id"`
TelegramName string `db:"telegram_name"`
}

// OwnerInfo represents information about the owner of a company.
type OwnerInfo struct {
TelegramId int64
TelegramID int64
TelegramName string
}
5 changes: 4 additions & 1 deletion internal/lib/handlers/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,21 @@ import (
"github.com/go-playground/validator/v10"
)

// ErrorResponse represents an error response returned by the API.
type ErrorResponse struct {
Message string `json:"message"`
}

// nolint
// NewErrorResponse writes an error response to the provided http.ResponseWriter with the given status code and error message.
func NewErrorResponse(w http.ResponseWriter, status int, err string) {
w.WriteHeader(status)
// nolint:errcheck
json.NewEncoder(w).Encode(ErrorResponse{
Message: err,
})
}

// ValidationError generates a string message from the provided validation errors.
func ValidationError(errs validator.ValidationErrors) string {
var errMsgs []string

Expand Down
3 changes: 2 additions & 1 deletion internal/lib/logger/sl/sl.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import (
"golang.org/x/exp/slog"
)

// Err returns a slog.Attr with the given error message as its value and "error" as its key.
func Err(err error) slog.Attr {
return slog.Attr{
Key: "error",
Value: slog.StringValue(err.Error()),
}
}
}
11 changes: 7 additions & 4 deletions internal/lib/logger/slogdiscard/slogdiscard.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,35 @@ import (
"golang.org/x/exp/slog"
)

// NewDiscardLogger creates a new logger that discards all log records.
func NewDiscardLogger() *slog.Logger {
return slog.New(NewDiscardHandler())
}

// DiscardHandler is a logger handler that discards all log records.
type DiscardHandler struct{}

// NewDiscardHandler creates a new DiscardHandler instance.
func NewDiscardHandler() *DiscardHandler {
return &DiscardHandler{}
}

// Handle ignores the log record.
func (h *DiscardHandler) Handle(_ context.Context, _ slog.Record) error {
// Просто игнорируем запись журнала
return nil
}

// WithAttrs returns the handler itself since DiscardHandler does not use attributes.
func (h *DiscardHandler) WithAttrs(_ []slog.Attr) slog.Handler {
// Возвращает тот же обработчик, так как нет атрибутов для сохранения
return h
}

// WithGroup returns the handler itself since DiscardHandler does not use groups.
func (h *DiscardHandler) WithGroup(_ string) slog.Handler {
// Возвращает тот же обработчик, так как нет группы для сохранения
return h
}

// Enabled returns false since DiscardHandler does not enable any log levels.
func (h *DiscardHandler) Enabled(_ context.Context, _ slog.Level) bool {
// Всегда возвращает false, так как запись журнала игнорируется
return false
}
2 changes: 1 addition & 1 deletion internal/lib/random/random.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ func NewRandomString(size int) string {
}

return string(b)
}
}
2 changes: 2 additions & 0 deletions internal/lib/validator/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ var (
parseMode = []string{"html"} //"markdownv2", "markdown",
)

// ValidateParseMode checks if the provided parse mode is valid.
// Returns true if the parse mode is valid, false otherwise.
func ValidateParseMode(fl validator.FieldLevel) bool {
value := fl.Field().String()

Expand Down
9 changes: 8 additions & 1 deletion internal/storage/postgres/chat/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import (
"github.com/testit-tms/webhook-bot/internal/storage"
)

// ChatStorage is a storage implementation for chats using PostgreSQL.
type ChatStorage struct {
db *sqlx.DB
}

// New returns a new instance of ChatStorage with the given database connection.
func New(db *sqlx.DB) *ChatStorage {
return &ChatStorage{
db: db,
Expand All @@ -29,6 +31,7 @@ const (
deleteChatByCompanyId = "DELETE FROM chats WHERE company_id=$1"
)

// GetChatsByCompanyId returns a slice of entities.Chat that belong to the company with the given ID.
func (s *ChatStorage) GetChatsByCompanyId(ctx context.Context, id int64) ([]entities.Chat, error) {
const op = "storage.postgres.GetChatByCompanyId"

Expand All @@ -45,6 +48,7 @@ func (s *ChatStorage) GetChatsByCompanyId(ctx context.Context, id int64) ([]enti
return chats, nil
}

// GetChatsByCompanyToken returns a slice of entities.Chat that belong to the company with the given token.
func (s *ChatStorage) GetChatsByCompanyToken(ctx context.Context, t string) ([]entities.Chat, error) {
const op = "storage.postgres.GetChatsByCompanyToken"

Expand All @@ -61,19 +65,21 @@ func (s *ChatStorage) GetChatsByCompanyToken(ctx context.Context, t string) ([]e
return chats, nil
}

// AddChat adds a new chat to the database and returns the newly created chat entity.
func (r *ChatStorage) AddChat(ctx context.Context, chat entities.Chat) (entities.Chat, error) {
const op = "storage.postgres.AddChat"

newChat := entities.Chat{}

err := r.db.QueryRowxContext(ctx, addChat, chat.CompanyId, chat.TelegramId).StructScan(&newChat)
err := r.db.QueryRowxContext(ctx, addChat, chat.CompanyID, chat.TelegramID).StructScan(&newChat)
if err != nil {
return newChat, fmt.Errorf("%s: execute query: %w", op, err)
}

return newChat, nil
}

// DeleteChatById deletes a chat from the database by its ID.
func (r *ChatStorage) DeleteChatById(ctx context.Context, id int64) error {
const op = "storage.postgres.DeleteChatById"

Expand All @@ -85,6 +91,7 @@ func (r *ChatStorage) DeleteChatById(ctx context.Context, id int64) error {
return nil
}

// DeleteChatByCompanyId deletes all chats from the database that belong to the company with the given ID.
func (r *ChatStorage) DeleteChatByCompanyId(ctx context.Context, id int) error {
const op = "storage.postgres.DeleteChatByCompanyId"

Expand Down
28 changes: 14 additions & 14 deletions internal/storage/postgres/chat/chat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ func TestChatStorage_GetChatsByCompanyId(t *testing.T) {
chatsExp := []entities.Chat{
{
Id: 12,
CompanyId: id,
TelegramId: 123456,
CompanyID: id,
TelegramID: 123456,
},
{
Id: 13,
CompanyId: id,
TelegramId: 654321,
CompanyID: id,
TelegramID: 654321,
},
}

Expand Down Expand Up @@ -106,13 +106,13 @@ func TestChatStorage_GetChatsByCompanyToken(t *testing.T) {
chatsExp := []entities.Chat{
{
Id: 12,
CompanyId: 21,
TelegramId: 123456,
CompanyID: 21,
TelegramID: 123456,
},
{
Id: 13,
CompanyId: 21,
TelegramId: 654321,
CompanyID: 21,
TelegramID: 654321,
},
}

Expand Down Expand Up @@ -184,14 +184,14 @@ func TestChatStorage_AddChat(t *testing.T) {
defer f.Teardown()
expectedChat := entities.Chat{
Id: 12,
CompanyId: 21,
TelegramId: 123456,
CompanyID: 21,
TelegramID: 123456,
}
rows := sqlmock.NewRows([]string{"id", "company_id", "telegram_id"}).
AddRow(12, 21, "123456")

f.Mock.ExpectQuery(regexp.QuoteMeta("INSERT INTO chats (company_id, telegram_id) VALUES ($1, $2) RETURNING id, company_id, telegram_id")).
WithArgs(expectedChat.CompanyId, expectedChat.TelegramId).
WithArgs(expectedChat.CompanyID, expectedChat.TelegramID).
WillReturnRows(rows)

repo := New(f.DB)
Expand All @@ -213,12 +213,12 @@ func TestChatStorage_AddChat(t *testing.T) {
expectErr := errors.New("test error")
expectedChat := entities.Chat{
Id: 12,
CompanyId: 21,
TelegramId: 123456,
CompanyID: 21,
TelegramID: 123456,
}

f.Mock.ExpectQuery(regexp.QuoteMeta("INSERT INTO chats (company_id, telegram_id) VALUES ($1, $2) RETURNING id, company_id, telegram_id")).
WithArgs(expectedChat.CompanyId, expectedChat.TelegramId).
WithArgs(expectedChat.CompanyID, expectedChat.TelegramID).
WillReturnError(expectErr)

repo := New(f.DB)
Expand Down
Loading