Restructured project

- backend moved to backend directory
- added and initialized frontend with vue
- moved infrastructure files to infra directory
This commit is contained in:
2026-04-01 22:27:26 +03:00
parent 48ef7217eb
commit 9d845c8899
96 changed files with 1591 additions and 118 deletions
+34
View File
@@ -0,0 +1,34 @@
package utils
import (
"errors"
"strings"
"time"
)
const issuedAtLayout = "02/01/2006, 15:04:05"
var knownDateFormats = []string{
"02.01.2006", // 21.01.2026
"02.01.06", // 21.01.2026
"02-01-2006", // 21-01-2026
"02/01/2006", // 21/01/2026
//"2006/01/02", // 2026/01/21
//"2006-01-02", // 2026-01-21
//"2006.01.02", // 2026.01.21
}
func NormalizeDateToISO(input string) (string, error) {
input = strings.TrimSpace(input)
for _, layout := range knownDateFormats {
if t, err := time.Parse(layout, input); err == nil {
return t.Format("2006-01-02"), nil
}
}
return "", errors.New("unsupported date format")
}
func ParseIssuedAt(value string) (time.Time, error) {
return time.Parse(issuedAtLayout, value)
}
+25
View File
@@ -0,0 +1,25 @@
package utils
import (
"time"
"github.com/golang-jwt/jwt/v5"
)
type JWTManager struct {
secret string
}
func NewJWTManager(secret string) *JWTManager {
return &JWTManager{secret: secret}
}
func (j *JWTManager) Generate(userID int64) (string, error) {
claims := jwt.MapClaims{
"user_id": userID,
"exp": time.Now().Add(time.Hour * 24 * 7).Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte(j.secret))
}
+11
View File
@@ -0,0 +1,11 @@
package utils
import (
"strconv"
"strings"
)
func ParseFloat(value string) (float64, error) {
value = strings.ReplaceAll(value, ",", ".")
return strconv.ParseFloat(value, 64)
}
+33
View File
@@ -0,0 +1,33 @@
package utils
import "regexp"
type ReceiptMeta struct {
Date string
ReceiptID string
}
func ExtractReceiptMeta(text string) ReceiptMeta {
result := ReceiptMeta{}
// --- ДАТА ---
datePatterns := []string{
`(\d{2}[./-]\d{2}[./-]\d{4})`, // 25.01.2026
`(\d{2}[./-]\d{2}[./-]\d{2})`, // 25.01.26
`(\d{4}[./-]\d{2}[./-]\d{2})`, // 2026-01-25
}
for _, pattern := range datePatterns {
re := regexp.MustCompile(pattern)
if match := re.FindString(text); match != "" {
result.Date = match
break
}
}
// --- НОМЕР ЧЕКА (24 символа) ---
receiptRe := regexp.MustCompile(`\b[A-Za-z0-9]{24}\b`)
result.ReceiptID = receiptRe.FindString(text)
return result
}
+30
View File
@@ -0,0 +1,30 @@
package utils
import (
"bytes"
"image"
_ "image/jpeg"
_ "image/png"
"github.com/liyue201/goqr"
)
func DecodeQR(imageBytes []byte) ([]string, error) {
img, _, err := image.Decode(bytes.NewReader(imageBytes))
if err != nil {
return nil, err
}
codes, err := goqr.Recognize(img)
if err != nil {
return nil, err
}
println(codes)
var result []string
for _, code := range codes {
result = append(result, string(code.Payload))
}
return result, nil
}