This commit is contained in:
Alex Shevchuk
2025-08-18 17:12:04 +03:00
commit d84487d238
157 changed files with 160686 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
package constants
import "errors"
var (
ErrInternalServerError = errors.New("internal server error")
ErrBadRequest = errors.New("bad request")
ErrForbidden = errors.New("forbidden")
ErrNotFound = errors.New("not found")
ErrUnauthorized = errors.New("unauthorized")
ErrConflict = errors.New("conflict")
ErrRequestTimeout = errors.New("request timeout")
ErrNotImplemented = errors.New("not implemented")
ErrBadGateway = errors.New("bad gateway")
ErrServiceUnavailable = errors.New("service unavailable")
ErrIntOutOfRange = errors.New("value is out of range for int32")
)

View File

@@ -0,0 +1,11 @@
package constants
const (
FeedEventsTableName = "feed_events"
ClientTableName = "client"
SubmissionTableName = "submission"
)
const (
DefaultFeedFilterLimit = 20
)

View File

@@ -0,0 +1,182 @@
package constants
const (
EmailNotificationMessageType = "email"
RegistrationNotificationMessageSubject = "Регистрация пользователя в системе приложения Molva"
RegistrationNewUserAdmin = "Зарегистрирован новый пользователь приложения"
EmailVerificationMessageSubject = "Подтверждение адреса электронной почты"
TextNotificationContentType = "text/plain"
HTMLNotificationContentType = "text/html"
RegistrationNotificationText = `
Добро пожаловать в Molva!
Здравствуйте, %s!
Спасибо за регистрацию в Molva. Мы рады видеть вас в нашем сообществе.
Теперь вы можете:
- Получать персонализированные уведомления.
- Настраивать свои предпочтения.
- Использовать все возможности платформы.
Если у вас есть вопросы, не стесняйтесь обращаться в нашу службу поддержки!
После проверки аккаунта наш администратор с вами свяжется
С уважением, команда Molva.
Это письмо отправлено автоматически, пожалуйста, не отвечайте на него.
`
//nolint:gosec // there are no [potentially hardcoded] credentials in this message
ForgotPasswordNotificationMessageSubject = "Восстановление пароля в системе приложения Molva"
//nolint:gosec // there are no [potentially hardcoded] credentials in this message
ForgotPasswordNotificationText = `
Ваш код восстановления пароля: %s. Его можно использовать, чтобы сбросить пароль и зайти в свой аккаунт в Molva.
Если Вы не запрашивали восстановление доступа к аккаунту, пожалуйста, проигнорируйте это письмо.
С уважением, команда Molva.
`
)
const EmailVerificationTemplate = `<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body style="margin: 0; padding: 20px; font-family: Arial, sans-serif; background-color: #f5f5f5;">
<div style="max-width: 600px; margin: 0 auto; background-color: #ffffff; padding: 40px; border-radius: 8px;">
<h1 style="color: #333; font-size: 24px; margin: 0 0 30px 0;">MOLVA</h1>
<h2 style="color: #333; font-size: 20px; margin: 0 0 20px 0;">Подтвердите email</h2>
<p style="color: #555; font-size: 16px; line-height: 24px; margin: 0 0 10px 0;">
Здравствуйте, %s!
</p>
<p style="color: #555; font-size: 16px; line-height: 24px; margin: 0 0 30px 0;">
Для завершения регистрации подтвердите ваш email адрес.
</p>
<a href="%s" style="display: inline-block; padding: 12px 30px; background-color: #4A90E2; color: #ffffff; text-decoration: none; border-radius: 4px; font-size: 16px;">
Подтвердить email
</a>
<p style="color: #999; font-size: 14px; line-height: 20px; margin: 30px 0 10px 0;">
Или скопируйте ссылку:
</p>
<p style="color: #4A90E2; font-size: 14px; line-height: 20px; word-break: break-all; margin: 0 0 30px 0;">
%s
</p>
<p style="color: #999; font-size: 13px; line-height: 18px; margin: 0;">
Ссылка действительна 24 часа.
</p>
</div>
</body>
</html>`
const EmailConfirmationPage = `<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Подтверждение Email</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f5f5f5;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.container {
background: #ffffff;
padding: 40px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
text-align: center;
max-width: 400px;
width: 100%;
}
.title {
color: #333;
margin-bottom: 20px;
font-size: 22px;
}
.message {
color: #555;
font-size: 16px;
margin-bottom: 30px;
}
.close-note {
color: #777;
font-size: 14px;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="title" id="status-title">Идёт подтверждение...</div>
<div class="message" id="status-message">Пожалуйста, подождите.</div>
<div class="close-note" id="close-note" style="display:none;">
Вы можете закрыть это окно.
</div>
</div>
<script>
(function() {
fetch("{{.VerificationURL}}", {
method: "PATCH",
headers: {
"Content-Type": "application/json"
}
})
.then(response => {
const titleEl = document.getElementById("status-title");
const msgEl = document.getElementById("status-message");
const closeEl = document.getElementById("close-note");
if (response.ok) {
titleEl.innerText = "Email успешно подтверждён!";
msgEl.innerText = "Спасибо за подтверждение. Теперь вы можете вернуться на сайт MOLVA!";
msgEl.style.color = "green";
} else if (response.status === 400 || response.status === 404) {
titleEl.innerText = "Неверная ссылка или токен";
msgEl.innerText = "Проверьте правильность ссылки или запросите новую.";
msgEl.style.color = "red";
} else {
titleEl.innerText = "Ошибка сервера";
msgEl.innerText = "Попробуйте повторить позднее.";
msgEl.style.color = "red";
}
closeEl.style.display = "block";
})
.catch(() => {
const titleEl = document.getElementById("status-title");
const msgEl = document.getElementById("status-message");
const closeEl = document.getElementById("close-note");
titleEl.innerText = "Не удалось подключиться";
msgEl.innerText = "Проверьте интернет-соединение и попробуйте снова.";
msgEl.style.color = "red";
closeEl.style.display = "block";
});
})();
</script>
</body>
</html>`
const EmailNewUserRegistrationAdminMessage = `
Зарегистрирован новый пользователь. Email подтверждён
Email: %s
Name: %s
Type: %s
`

View File

@@ -0,0 +1,38 @@
package constants
type PermissionType string
const (
Balance PermissionType = "balance"
Vacancies PermissionType = "vacancies"
Employees PermissionType = "employees"
Profile PermissionType = "profile"
Company PermissionType = "company"
Submissions PermissionType = "submissions"
)
func (p PermissionType) String() string {
return string(p)
}
type PermissionValue string
const (
NoPermission PermissionValue = "no_permission"
CanView PermissionValue = "can_view"
CanEdit PermissionValue = "can_edit"
)
func (p PermissionValue) String() string {
return string(p)
}
var PermissionLevels = map[PermissionValue]int{
NoPermission: 1,
CanView: 2,
CanEdit: 3,
}
var AllPermissions = []PermissionType{
Vacancies, Balance, Company, Submissions, Profile, Employees, Submissions,
}

27
internal/constants/s3.go Normal file
View File

@@ -0,0 +1,27 @@
package constants
import "time"
const (
LogoLinkTTL = 55 * time.Minute
LogoMaxSize = 10 << 20 // 10 MB
BytesToDetectContentType = 512
ParseMultipartFormAllFile = 0
TempDirPermission = 0750
TempLogoFilePattern = "logo-*.tmp"
)
const (
DefaultFileTTL = 30 * 24 * time.Hour //30 days
)
var ValidImageTypes = map[string]bool{
"image/png": true,
"image/jpeg": true,
"image/jpg": true,
"image/webp": true,
}
const (
RefreshLogoCacheAsyncTimeout = 10 * time.Second
)

View File

@@ -0,0 +1,31 @@
package constants
import "time"
const (
EmailVerificationServiceURL = "https://emailvalidation.abstractapi.com/v1/"
DocumentsPath = "/opt/molva/docs"
UserFilesBasePath = "/opt/molva/user_files"
DefaultRetryTimeout = time.Second * 10
DefaultContextTimeout = 30 * time.Second
DefaultPaginationPageSize = 20
DefaultPaginationPage = 1
)
const (
AdminNotificationEmail = "information@molva.io"
AdminNotificationId = 0
)
var AdminNotificationEmails = []string{AdminNotificationEmail}
const (
UserTypeAgentName = "Агент"
UserTypeDistributorName = "Дистрибьютор"
)
const (
DistributorClientType = 1
AgentClientType = 0
)