Web and mobile (PWA) application for comparing product prices in Croatian stores, creating shopping lists, storing digital loyalty cards, and getting deal alerts with barcode scanning and AI suggestions.
Deployed and available on: disscount.me
Created by: Jakov Jakovac
Big thanks to Cijene API for providing access to their API for data about products and store chains :)
This work is licensed under the Business Source License 1.1 (BUSL-1.1).
License parameters used in this repository:
- Licensor: Jakov Jakovac
- Additional Use Grant: None
- Change Date: Five (5) years from the date the Licensed Work is published
- Change License: GPL-3.0-or-later
Under BUSL-1.1 terms, each version converts on the Change Date or on the fourth anniversary of first publicly available distribution of that version, whichever comes first.
Commercial use is restricted unless covered by an Additional Use Grant or separate commercial terms from the Licensor.
The quickest way to run the full stack (frontend + backend + PostgreSQL) locally is with Docker Compose:
cp example.env .env # then fill in the values
docker compose up -d --build
# frontend: http://localhost:3000To run the services manually instead, follow the steps below.
- Node.js 22 LTS+ and pnpm
- Java 21 and Maven 3.9+
- PostgreSQL 14+ (17 in production)
- Docker + Docker Compose (only for the quick-run path above)
The backend and frontend share one PostgreSQL database: the backend owns the app tables (Hibernate ddl-auto), the frontend owns the better-auth tables (drizzle). Create the database, run the backend, then the frontend.
Create a database and user (example), and reuse these values in both env files below:
sudo -u postgres psql -c "CREATE USER disscount WITH PASSWORD 'secret';"
sudo -u postgres psql -c "CREATE DATABASE disscount OWNER disscount;"cd backend
cp .env.example .envSet in backend/.env:
SPRING_DATASOURCE_URL(e.g.jdbc:postgresql://localhost:5432/disscount)SPRING_DATASOURCE_USERNAMEandSPRING_DATASOURCE_PASSWORDBETTER_AUTH_JWKS_URI(e.g.http://localhost:3000/api/auth/jwks)
Build and run with the local Spring profile (it supplies local better-auth defaults, the JWKS URL and issuer at http://localhost:3000, so the app starts without extra config):
mvn clean install
mvn spring-boot:run -Dspring-boot.run.profiles=localThe backend runs on port 8080. Swagger UI: http://localhost:8080/api-docs
cd frontend
cp .env.local.example .env.localSet in frontend/.env.local (see the file for the full list):
DATABASE_URL(same Postgres DB, e.g.postgresql://disscount:secret@localhost:5432/disscount)BETTER_AUTH_SECRET(strong random string) andBETTER_AUTH_URL=http://localhost:3000NEXT_PUBLIC_API_URL=http://localhost:8080andNEXT_PUBLIC_APP_URL=http://localhost:3000- Google OAuth (
NEXT_PUBLIC_GOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET) and Facebook (FACEBOOK_CLIENT_ID,FACEBOOK_CLIENT_SECRET) RESEND_API_KEY+EMAIL_FROM, andCIJENE_API_URL+CIJENE_API_TOKEN
Install dependencies, create the better-auth tables, then run:
pnpm install
pnpm drizzle-kit migrate # creates the better-auth tables in the shared DB
pnpm devThe frontend runs on http://localhost:3000
Disscount is self-hosted on a Hetzner VPS using Dokploy (Docker Compose), with Traefik for routing and automatic Let's Encrypt TLS, and Cloudflare in front for DNS, CDN, and proxying. Production deploys automatically from the master branch, and a staging environment deploys from the dev branch, on every push.
See docs/DEPLOYMENT.md for the full infrastructure reference: architecture, environment variables, DNS and SSL, security, backups and restore, monitoring, and how to add more apps to the server.
Contributions are welcome — whether it's a bug report, feature idea, documentation improvement or code change. Below are guidelines to make the process smooth for everyone.
- Search existing issues before opening a new one to avoid duplicates.
- Create a new issue and include:
- A clear title and description of the problem or idea.
- Steps to reproduce (for bugs) and expected vs actual behavior.
- Environment details (OS, Java/Maven/Node versions, Postgres version, browser) if relevant.
- Attach screenshots, logs or example requests/responses when helpful.
- Use labels if available (bug, enhancement, question, docs).
- Fork the repository and create a feature branch from
master:- Branch name example:
feat/add-search-by-barcodeorfix/shopping-list-null-pointer.
- Branch name example:
- Follow project coding style:
- Backend: Java 21, use existing package structure and formatting.
- Frontend: follow existing TypeScript/React patterns, use Prettier extension and linting rules.
- Run tests and build locally before creating a PR:
- Backend:
cd backend && mvn clean install(use-DskipTestsonly for quick local debugging). - Frontend:
cd frontend && pnpm install && pnpm dev(and run any available tests/lint scripts).
- Backend:
- Commit messages should be concise and descriptive. Reference related issue numbers in the PR or commit message.
- Open a pull request against the
masterbranch and include:- A summary of changes, why they were made, and any migration steps.
- Screenshots or short recordings for UI changes.
- Links to related issues.
- Code builds and tests pass locally.
- Linting/formatting applied.
- No sensitive data (passwords, secrets) included.
- Other improvements such as translations, UI & UX suggestions, icons and designs are welcome. Open issues or PRs just like for code.
- Propose larger ideas in an issue first so maintainers can provide feedback before an implementation.
- Maintainers will review PRs, request changes if necessary, and merge when ready.
- Code Rabbit (an automated code-review tool) runs on pull requests and posts suggestions. Please review and address its recommendations before requesting a final review; if you disagree with a suggestion, explain why in the PR comments. Maintainers may require resolving important warnings before merging.
- Please be responsive to review comments - small follow-ups are common.
- Be respectful and constructive. This project follows the license in the repository; if a Code of Conduct is added later, contributors must follow it.
Thank you for helping improve Disscount - every contribution helps!








