<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Андрей Перминов</title>
    <description>The latest articles on DEV Community by Андрей Перминов (@__3929a5991).</description>
    <link>https://dev.to/__3929a5991</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3222837%2Ff3cdb7d9-d1c0-4a3c-84fe-7714a691720f.jpg</url>
      <title>DEV Community: Андрей Перминов</title>
      <link>https://dev.to/__3929a5991</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/__3929a5991"/>
    <language>en</language>
    <item>
      <title>Building Pultsnab — a Tender &amp; Procurement Platform with Spring Boot 3 and Java 21</title>
      <dc:creator>Андрей Перминов</dc:creator>
      <pubDate>Mon, 09 Mar 2026 05:42:03 +0000</pubDate>
      <link>https://dev.to/__3929a5991/building-pultsnab-a-tender-procurement-platform-with-spring-boot-3-and-java-21-i7k</link>
      <guid>https://dev.to/__3929a5991/building-pultsnab-a-tender-procurement-platform-with-spring-boot-3-and-java-21-i7k</guid>
      <description>&lt;p&gt;How we built a full-featured tender management system — from requests and proposals to contracts, deliveries, and reporting.&lt;/p&gt;

&lt;p&gt;Pultsnab is currently available in Russian only; localization (i18n) is planned for future releases. Website: &lt;a href="https://pultsnab.ru/?utm_source=dev&amp;amp;utm_medium=statya&amp;amp;utm_campaign=sale" rel="noopener noreferrer"&gt;pultsnab.ru&lt;/a&gt; (UTF-8).&lt;/p&gt;

&lt;p&gt;Why we built it&lt;br&gt;
Procurement and tender processes are often scattered across spreadsheets, email, and legacy tools. We wanted a single platform where customers could publish tenders, suppliers could submit proposals, and managers could run the full cycle: evaluation, contract award, delivery tracking, invoicing, and reporting — all with proper roles and audit trails.&lt;/p&gt;

&lt;p&gt;So we built Pultsnab: a Spring Boot backend that powers exactly that.&lt;/p&gt;

&lt;p&gt;Tech stack at a glance&lt;br&gt;
Layer   Choice&lt;br&gt;
Runtime Java 21&lt;br&gt;
Framework   Spring Boot 3.5&lt;br&gt;
Database    PostgreSQL + JPA/Hibernate&lt;br&gt;
Migrations  Liquibase&lt;br&gt;
Auth    Spring Security + JWT (access + refresh)&lt;br&gt;
Validation  Hibernate Validator 8&lt;br&gt;
Mapping MapStruct&lt;br&gt;
Files   AWS S3–compatible (e.g. MinIO)&lt;br&gt;
Documents   Apache POI (Excel), OpenPDF (PDF)&lt;br&gt;
Mail    Spring Boot Mail (notifications)&lt;br&gt;
Nothing exotic — just a solid, maintainable stack that's easy to deploy and reason about.&lt;/p&gt;

&lt;p&gt;What the system does&lt;br&gt;
Tenders — Create, publish, and manage tenders with statuses: Draft → Published → Bidding → Evaluation → Awarded (or Cancelled). Each tender has items, deadlines, and terms.&lt;br&gt;
Supplier proposals — Suppliers submit proposals per tender; the system supports comparison and price analysis.&lt;br&gt;
Contracts — Awarded tenders turn into contracts with items, delivery and payment terms.&lt;br&gt;
Deliveries &amp;amp; warehouses — Track deliveries against contract items and warehouses.&lt;br&gt;
Invoicing — Invoices linked to contracts, with PDF generation (e.g. bank payment slips) and payment tracking.&lt;br&gt;
Companies &amp;amp; contacts — Customers and suppliers as companies with contacts, bank details, and requisites.&lt;br&gt;
Requests — Internal requests that can be turned into tenders (request → tender → contract flow).&lt;br&gt;
Dashboard &amp;amp; reports — Dashboards by period and role, plus operational/financial reports and Excel export.&lt;br&gt;
Alerts &amp;amp; notifications — Email notifications for key events (tender published, proposal submitted, tender awarded/cancelled, reminders).&lt;br&gt;
Security &amp;amp; audit — Role-based access (e.g. Admin, Manager, Supplier, Viewer), JWT auth, and audit logs for important actions.&lt;br&gt;
So the backend is a full tender-to-contract-to-delivery-to-invoice pipeline, not just a CRUD API.&lt;/p&gt;

&lt;p&gt;App preview (generated data)&lt;br&gt;
Below is a mockup of the main screens with sample data: dashboard, tenders, contracts, and deliveries. Switch tabs to explore.&lt;/p&gt;

&lt;p&gt;Pultsnab — основные экраны (демо-данные)&lt;/p&gt;

&lt;p&gt;Architecture highlights&lt;br&gt;
REST API — Dozens of controllers under /api/*: tenders, proposals, contracts, deliveries, invoices, companies, users, reports, etc. We use @PreAuthorize for role checks so each endpoint is explicitly protected.&lt;/p&gt;

&lt;p&gt;Layered structure — Controllers → Services → Repositories, with DTOs and MapStruct mappers so we don't expose entities. Validation on DTOs with &lt;a class="mentioned-user" href="https://dev.to/valid"&gt;@valid&lt;/a&gt; and Hibernate Validator keeps invalid data out of the core.&lt;/p&gt;

&lt;p&gt;Database — PostgreSQL with Liquibase for versioned migrations. We use ddl-auto: none and rely on Liquibase for schema changes. Hibernate is tuned for batching and fetch depth to avoid N+1 and lazy-load issues.&lt;/p&gt;

&lt;p&gt;File storage — AWS S3–compatible API (e.g. MinIO in dev). Uploads go to a configurable bucket; documents and exports can be generated (e.g. PDF bank invoices) and stored or streamed back.&lt;/p&gt;

&lt;p&gt;Scheduled jobs — An alert scheduler runs periodic checks (e.g. tender deadlines, reminders) and triggers email notifications. Spring's @Scheduled keeps this simple.&lt;/p&gt;

&lt;p&gt;What we'd share in follow-up posts&lt;br&gt;
JWT setup — Access + refresh tokens, storage, and how we plug them into Spring Security.&lt;br&gt;
Role-based access — How we map roles (Admin, Manager, Supplier, Viewer) to endpoints and UI capabilities.&lt;br&gt;
From request to tender to contract — How one entity drives the next and how we keep data consistent.&lt;br&gt;
Generating PDFs — OpenPDF + Cyrillic fonts for bank invoices and other documents.&lt;br&gt;
Excel import/export — Apache POI for bulk data and report export with configurable column mapping.&lt;br&gt;
Takeaways&lt;br&gt;
Spring Boot 3 + Java 21 — Smooth experience; no need for the latest experimental features, just stable LTS and framework support.&lt;br&gt;
Liquibase — Versioned migrations made schema evolution and multi-environment deploys predictable.&lt;br&gt;
MapStruct — Kept mapping logic out of services and made it easy to add new DTOs without boilerplate.&lt;br&gt;
S3-compatible storage — One integration (AWS SDK v2) works with MinIO locally and AWS in production.&lt;br&gt;
Clear API boundaries — REST + DTOs + validation made it easier to add a frontend and later mobile clients without touching core logic.&lt;br&gt;
Try it or contribute&lt;br&gt;
The project is Pultsnab (tender management backend). You can run it with Java 21, PostgreSQL, and an S3-compatible store (e.g. MinIO); see the repo for configuration and optional Docker/local setup. Visit the app at pultsnab.ru.&lt;/p&gt;

&lt;p&gt;If you're building something similar — procurement, contracts, or document-heavy backends — we're happy to go deeper on any part (auth, workflows, PDF/Excel, or deployment) in future posts.&lt;/p&gt;

&lt;p&gt;What would you like to read about next: JWT + Spring Security, the tender→contract flow, or PDF/Excel generation?&lt;/p&gt;

&lt;p&gt;Tags: pultsnab java springboot postgresql backend rest-api jwt spring-security liquibase mapstruct&lt;/p&gt;

</description>
      <category>backend</category>
      <category>java</category>
      <category>showdev</category>
      <category>springboot</category>
    </item>
  </channel>
</rss>
