02 / Offer and opportunity discovery application
ThomasSeeker
A system that turns the manual trawling of scattered offers into an automated process: it collects the data, cleans it up and notifies the user when an opportunity matches their criteria.
- Client
- [TO BE PROVIDED: who the application was built for — a client or my own product]
Offer list with the filter panel
2560×1440 px, AVIF/WebP
Overview
Attractive offers share one trait: they disappear fast. Anyone tracking them by hand checks the same sources several times a day and still, regularly, learns about an opportunity after it is gone. ThomasSeeker reverses that arrangement — a system that collects offer data from [TO BE PROVIDED: the industry or type of offers] on its own, organizes it and serves it to the user in a decision-ready form.
I built the whole system: the automated data-collection mechanisms, the processing and normalization layer, the filtered search, the opportunity-notification engine and the interface where the user browses results and manages their criteria. Everything runs on a shared data model, so an offer, once collected, is instantly searchable and considered for notifications.
On the surface it is an app with a list of offers. In practice it is above all a data and automation problem: the product's value depends on collection running unattended, on the data staying fresh, and on the user receiving, out of thousands of entries, precisely the ones they care about.
Challenge
Offer data comes from multiple sources, and each has its own format, its own gaps and its own rhythm of change. The same offer can appear in several places in different variants, descriptions can be incomplete, and a source's structure can change without warning. The system had to reduce all of that to one clean model, with deduplication, validation and resilience to upstream changes. Then there is time: an opportunity discovered hours late is often worthless, so data freshness was a design requirement, not a nice-to-have.
The second challenge was relevance. A system that notifies about everything teaches the user to ignore notifications, and so defeats its own purpose. The criteria had to be precise enough that a signal only fires on a genuine match, and the whole pipeline reliable enough to run for weeks without manual intervention. Silence in a system like this means one of two things — no opportunities, or something broke — and the user has to be certain which one is true.
My role
I ran the project end to end as the sole engineer: I designed the architecture and data model, built the data collection and processing mechanisms, the backend with search and notifications, and the user interface. I was also responsible for running and maintaining the automation — the part of the system that has to work when nobody is watching it.
Solution
Automated data collection
Offer data is gathered by scheduled jobs, one per source. Each source has its own adapter, a small module that knows its quirks and translates them into a common format. Polling frequency is matched to how often each source actually changes, and stays within its limits: the system is meant to collect data effectively, but in a predictable and polite way.
Data processing and normalization
Raw data passes through a processing layer: cleaning, validation, field normalization and duplicate detection, so the same offer from two sources never shows up twice. Alongside the normalized records I keep the original source data — when processing rules change, the whole history can be recomputed without collecting anything again.
Search and filtering
The organized data feeds a search engine with filters that mirror how the user actually judges offers, from basic parameters to [TO BE PROVIDED: criteria specific to the type of offers]. A filter set can be saved as a search profile and reopened with one click; those same profiles are the foundation of the notification system.
Opportunity notifications
Every new or changed offer is compared server-side against the user's saved profiles. A match triggers a notification via [TO BE PROVIDED: the notification channel — e.g. email or push notifications], carrying the offer's key parameters and a direct link to the details. The user refreshes nothing and checks nothing; the system watches the market for them.
The user interface
The interface serves a single job: judging quickly whether an offer deserves attention. The results list surfaces the parameters that decide attractiveness, the detail view gathers the complete picture in one place, and managing search profiles requires no technical knowledge at all.
Reliability and pipeline supervision
The automation is monitored: failed jobs are retried, and a problem with a source, such as a structural change, raises an alert instead of leaving a silent gap in the data. One adapter failing stops neither the other adapters nor the application itself, so a single source may go quiet for a while, but the system as a whole keeps working.
Technology stack
Backend and application logic
- [DO UZUPEŁNIENIA / TO BE PROVIDED: język i framework backendu]
Automation and data processing
- [DO UZUPEŁNIENIA / TO BE PROVIDED: mechanizm harmonogramowania zadań]
- [DO UZUPEŁNIENIA / TO BE PROVIDED: narzędzia do pozyskiwania i przetwarzania danych]
Database and search
- [DO UZUPEŁNIENIA / TO BE PROVIDED: silnik bazy danych]
- [DO UZUPEŁNIENIA / TO BE PROVIDED: mechanizm wyszukiwania, jeśli odrębny od bazy]
User interface
- [DO UZUPEŁNIENIA / TO BE PROVIDED: technologia frontendu lub platforma aplikacji]
Engineering decisions
- 01
Data collection is separated from the user-facing part of the system, so a failing or slow source never takes the application down, and the user always works on the last consistent state of the data.
- 02
Raw data is kept alongside the normalized records. When normalization rules change or offers gain a new attribute, the history is recomputed from what is already stored instead of being collected all over again.
- 03
Criteria matching happens on the server the moment an offer arrives, not on the client through periodic polling, so notifications are fast and cheap whether or not the user has the application open.
- 04
Every data source sits behind a common adapter interface. Adding a new source means writing one module, with no changes to the system's core — a deliberate investment in the product's future.
Security & reliability
Data collection was designed responsibly: rate-limited, identifiable traffic that respects the sources' terms of use — automation must not run at the expense of the systems it draws from.
User account data is limited to the necessary minimum, access to the system requires authentication, and traffic to the backend is encrypted.
Keys and source credentials live outside the code, in environment configuration: they never enter the repository and can be rotated without touching a single line of the application.
All incoming source data is treated as untrusted: it is validated and sanitized before reaching the database and the interface, so a malformed or malicious entry threatens neither the system nor the user.
Outcome
Manually trawling scattered sources has been replaced by a single, organized view of the market, with search and filters that mirror the real decision criteria.
The time between an offer appearing and the user knowing about it has shrunk from the rhythm of manual checking to an automatic notification — and in the hunt for opportunities, that difference is what decides the outcome.
The system runs unattended and is built to be extended: further data sources and new criteria can be added without rebuilding the foundations.
Gallery
Offer detail view
2560×1440 px, AVIF/WebP
Search profile and notification setup
2560×1440 px, AVIF/WebP
Example of an opportunity notification
1170×2532 px (iPhone screen), AVIF/WebP
More work
Let's talk about your project
Happy to walk you through how a similar approach would work in your case — and what I would avoid.
- Phone
- +48 573 021 012
