Coti × Criare Hackathon 2025
1st place in a 24-hour hackathon: a platform that takes purchase quoting out of email and spreadsheets, with live negotiation between company and supplier.
- Year
- 2025
- Stack
- Java · Spring Boot · PostgreSQL · Angular · Docker · WebSocket
Context
In December 2025, Coti Informática and Criare Sistemas set a 24-hour continuous development challenge. Our three-person team, Javangers, took first place with a quoting and negotiation platform for companies and suppliers.
Anyone who has bought for a company knows the problem: quotes live in email and spreadsheets, with no history and no easy comparison. On the platform, the company publishes what it needs, suppliers compete with proposals, and both sides negotiate the final price in a chat room, with everything on record.
Technical decisions
A modular monolith with clean architecture, enforced by tests: each module (identity, purchasing, dashboard, real time) has domain, application and infrastructure layers, with dependencies pointing inward. Spring Modulith checks module boundaries and ArchUnit checks the layers; breaking a rule breaks the build. Microservices were ruled out because closing a deal touches negotiation, quote and proposals in a single transaction.
Authentication with a short-lived access token (15 minutes, kept in memory only on the front end) and an opaque, rotating refresh token in an HttpOnly cookie, with reuse detection: a stolen token works once, and if it shows up again every session for that user is revoked. Authorization in two layers, role at the controller and ownership in the service.
Live negotiation over WebSocket (STOMP), with a typing indicator, unread counters and notifications on any screen; without a connection, the front end falls back to polling every ten seconds. On the front end, Angular with signals, standalone components and custom components instead of Bootstrap, with design tokens for light and dark themes.
Tracing with OpenTelemetry: every request carries a traceId that shows up in the logs, the response header and the error body. JSON logs never record passwords, tokens, full emails or negotiation content, and a test enforces it.
Outcome
First place. After the event the project became a monorepo with CI on GitHub Actions (build, tests against a real PostgreSQL via Testcontainers, smoke test and end-to-end with Playwright), CodeQL, Dependabot and a public demo. Later phases now start from a specification before any code.
What I'd do differently
Start with the versioned database schema and the architecture tests in the first few hours. They came later and cost rework; as acceptance criteria from the start, they would have guided the rest.