This one didn't start as a portfolio project — a friend needed a system to manage users and license keys for software he was distributing, and I ended up building the whole backend for him. It grew into a full RESTful API handling user registration, login, license key distribution, product downloads, hardware-ID binding, and ban management.
He wasn't comfortable with databases, so the whole thing runs on JSON files that can be opened and edited by hand if something needs fixing manually. That constraint shaped a lot of the design: storage had to be simple and inspectable, but the rest of the system still needed to behave like a proper backend.
Because development happened in my free time, the system went into production incrementally — long before all planned features were finished. That practical constraint influenced several design decisions: JSON-based storage allows direct file edits for anything the admin tooling doesn't cover yet, and the modular architecture lets me add features gradually without disrupting the running system. It's the only project of mine that's been deployed in a real production environment, and it has been serving real users and handling actual license distribution since.
network): the HTTP Server, an abstract RequestHandler (with an AdminRequestHandler variant for admin-only endpoints), and 20+ specialized request handlers — login, register, redeemKey, showProducts, download, banUser, unbanUser, resetHWID, createKeys, getKeys, deleteKey, getUsers, getActiveSessions, getProducts, and more.logic): UserManager, SessionManager, KeyManager, ProductManager, BanManager, LogManager, and ConfigManager — each owning one slice of the system's behavior.data): a DataManager as the central access point, an IDataStorage abstraction with a DefaultDataStorage file-based implementation, a MountedDataStorage for virtual directory mounting, and an optional BufferedDataStorage caching layer.utils): BCrypt password hashing, a custom JSON parser, bidirectional map implementations for fast lookups, centralized logging, and a type-safe Result wrapper for error handling.src/
├── de/lukas/eternalUserManager/
│ ├── Main.java # Application entry point
│ ├── data/ # Data persistence layer
│ ├── logic/ # Business logic
│ │ ├── banList/ # Ban management
│ │ ├── changelog/ # Version logging
│ │ ├── config/ # User configs
│ │ ├── key/ # License keys
│ │ ├── product/ # Product management
│ │ ├── session/ # Session tracking
│ │ └── user/ # User management
│ ├── network/ # HTTP server & API
│ │ └── requests/ # Public API endpoints
│ └── utils/ # Helper utilities
└── META-INF/
└── MANIFEST.MF
Design-wise, managers act as facades over their subsystems, storage and hashing are pluggable via a strategy pattern, request handlers are created and routed through an abstract-factory-style setup, and the logger and configuration are singletons.
Because new features kept landing on top of a system that was already serving real users, this project forced me to think about safe, incremental changes for real — not just as a theoretical best practice. That's very different from building something end-to-end and shipping it once.
It's also the only project I've written a proper test suite for, and that wasn't an accident. Once real people depend on something, "it works on my machine" stops being good enough. The tests focus on authentication and session handling, license key generation and redemption, and data persistence and integrity — and they've been essential for maintaining stability while adding features incrementally during active production use.