Skip to content

blxxdclxud/li-acc

Repository files navigation

li-acc

Сервис автоматизации рассылки платёжных квитанций для бухгалтерии школы.

Постановка задачи

Бухгалтерский отдел школы ежемесячно формировал квитанции об оплате услуг вручную: вносил данные в шаблон PDF по одному ученику, печатал и передавал родителям. Около 300 квитанций в месяц. Сервис развёрнут и используется бухгалтерией с 2025 года.

Требовалось автоматизировать:

  • Парсинг реестра зачислений из Excel (ФИО ученика, лицевой счёт, сумма, реквизиты организации)
  • Сопоставление учеников с email-адресами родителей (отдельный Excel-файл)
  • Генерацию персональных PDF-квитанций с QR-кодом для оплаты через СБП
  • Массовую рассылку через SMTP с сохранением копий в папке «Отправленные» (IMAP)

Интерфейс — веб-страница, доступная бухгалтеру в браузере.

Архитектура

┌─────────────────────────────────────────────────────────┐
│                        Browser (UI)                     │
│          HTML-страницы + multipart file upload          │
└───────────────────────────┬─────────────────────────────┘
                            │ HTTP
┌───────────────────────────▼─────────────────────────────┐
│                    Handler Layer                        │
│  MainHandler   HistoryHandler   SettingsHandler         │
│  UIHandler     APIClient                                │
│                                                         │
│ (Gin framework, multipart parsing, response DTOs)       │
└───────────────────────────┬─────────────────────────────┘
                            │ interfaces
┌───────────────────────────▼─────────────────────────────┐
│                    Service Layer                        │
│                                                         │
│  Manager                                                │
│  │ ProcessPayersFile()                                  │
│  │   ├── validate settings                              │
│  │   ├── store uploaded file                            │
│  │   ├── parse payers (XLS)                             │
│  │   ├── parse org (XLS)                                │
│  │   ├── record history                                 │
│  │   ├── formPersonalReceipts()                         │
│  │   │     ├── prepareReceiptTemplate (XLS → PDF)       │
│  │   │     ├── for each payer: generate QR + fill PDF   │
│  │   │     └── map email → pdf path                     │
│  │   └── SendMails()                                    │
│  │                                                      │
│  ├── MailService    (concurrent SMTP + IMAP store)      │
│  ├── HistoryService (file history CRUD)                 │
│  └── SettingsService(email mappings, in-memory cache)   │
└───────────────────────────┬─────────────────────────────┘
                            │ interfaces
┌───────────────────────────▼─────────────────────────────┐
│                  Repository Layer                       │
│         HistoryRepository   SettingsRepository          │
│                   PostgreSQL (pgx/v5)                   │
└─────────────────────────────────────────────────────────┘

         ┌─────────────────────────────────┐
         │       Utility Packages          │
         │  pkg/pdf      – PDF generation  │
         │  pkg/sender   – SMTP + IMAP     │
         │  pkg/xls      – Excel parsing   │
         │  pkg/qr       – QR code (СБП)   │
         │  pkg/converter– Excel → PDF     │
         └─────────────────────────────────┘

Технический стек

Компонент Выбор Обоснование
HTTP Gin Минимальные аллокации, встроенный multipart, удобный роутинг
Excel excelize Зрелая Go-библиотека с поддержкой .xls + .xlsx
PDF pdft Наложение текста и изображений на готовый PDF-шаблон без перегенерации
QR go-qrcode Простой API; формат СБП-строки собирается вручную
SMTP gomail Вложения, MIME, TLS из коробки
IMAP go-imap/v2 Активно поддерживаемый Go IMAP-клиент; lazy connect + mutex для reuse
БД PostgreSQL + pgx/v5 История файлов и email-маппинги; pgx — без ORM, низкие накладные расходы
Логирование zap Структурированные логи, нет аллокаций в hot path
Метрики Prometheus Latency обработки файла и рассылки (histogram); счётчики успешных/упавших операций по типу (payers_file, emails_file); количество сгенерированных квитанций (gauge)
Рейт-лимитер golang.org/x/time/rate Token bucket 5 писем/сек; не перегружает SMTP-сервер школы

Тестовое покрытие

Слой Покрытие Метод
Repository 84.6% Интеграционные тесты (testcontainers — PostgreSQL поднимается автоматически)
Service 66.2% Unit с testify/mock; happy path ProcessPayersFile — E2E
Handler (бизнес-хэндлеры) ~95% Unit, httptest
Handler (весь пакет включая ui.go) 51.7% ui.go — HTML-рендеринг, не тестируется
pkg/sender 40.7% Unit; SendEmail с реальным SMTP — интеграционный
pkg/pdf 22.8% Unit (utils, layout); Canvas — интеграционный
pkg/xls ~60% Unit + интеграционные
pkg/qr ~75% Unit

Canvas.Fill, GeneratePersonalReceipt, converter.ExcelToPdf покрыты интеграционными тестами в pkg/pdf/integration/ и tests/e2e/.

Запуск

Требования

  • Go 1.24+
  • docker compose

Конфигурация

cp .env.example .env
# Заполнить: DB_DSN, SMTP_HOST, SMTP_PORT, SMTP_EMAIL, SMTP_PASSWORD,
#            IMAP_HOST, IMAP_PORT, IMAP_SENT_FOLDER

Запуск

docker compose up --build
# Сервер на :8080

Тесты

# Unit-тесты (без Docker)
go test ./internal/handler/... ./internal/service/... \
        ./pkg/pdf/... ./pkg/sender/... ./pkg/qr/... ./pkg/xls/...

# Интеграционные — testcontainers поднимает PostgreSQL автоматически
go test ./internal/repository/... ./pkg/converter/... ./pkg/pdf/integration/...

# E2E — валидируют полный pipeline: Excel → PDF → QR → рассылка.
# Для запуска необходим реальный SMTP-аккаунт (см. .env.example)
go test ./tests/e2e/...

# Покрытие по слою
go test ./internal/handler/... -cover
go test ./internal/service/... -cover

Тестовые данные

  • e2e/testdata/ — пример реестра зачислений и файла email-маппинга

Структура проекта

cmd/app/           — точка входа
internal/
  handler/         — HTTP-хэндлеры, UI, API-клиент
  service/         — бизнес-логика (Manager, Mail, History, Settings)
  repository/      — репозитории PostgreSQL
  model/           — внутренние модели (Mail, Settings, File, пути)
  mocks/           — testify-моки для unit-тестов
  errs/            — типизированные ошибки (System/User/Validation)
  metrics/         — Prometheus-метрики
pkg/
  pdf/             — наложение данных на PDF-шаблон квитанции
  sender/          — SMTP-рассылка + IMAP-хранение
  xls/             — парсинг и редактирование Excel
  qr/              — генерация QR-кода для СБП
  converter/       — Excel → PDF через LibreOffice
  model/           — публичные модели (Payer, Organization)
templates/         — HTML-шаблоны страниц
static/            — шрифты, CSS
e2e/testdata/      — тестовые Excel-файлы

About

Сервис рассылки квитанций для школ: автоматический парсинг платёжных реестров из Excel, генерация персональных квитанций в PDF с QR-кодами СБП и массовая рассылка по SMTP

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors