Bricked Up is a full-stack web app that aggregates and analyzes LEGO deals 🧩 scraped from public sources. Users can browse deals, filter and sort listings, save favorites, and gain insights with interactive price indicators.
🌐 Live Demo: Visit Bricked Up
Bricked Up solves the challenge of finding the best LEGO deals in a user-friendly, responsive, and automated way. By leveraging scraping, APIs, and automation, it ensures LEGO enthusiasts never miss out on a great deal. 🧱✨
- 🛒 View Deals: Browse through aggregated LEGO offers.
- 📊 Relevance Score:
- Each deal is scored based on its popularity, discount, freshness, and resalability metrics.
- Relevance helps users prioritize the best deals.
- 🔍 Interactive Filters:
- 🏆 Best Discount
- 🔥 Hot Deals
- 📈 Popular Deals
- Relevance-based sorting
- 📊 Deal Insights:
- Average and percentile price indicators.
- Expiration countdown for time-sensitive offers.
- ❤️ Save Favorites: Mark and revisit your favorite deals.
- 🌗 Dark Mode: Toggle between light and dark themes.
- 🔄 Automated Refresh: Deals update daily at 5 AM and 6 PM UTC+2.
- 📱 Responsive Design: Works seamlessly on all devices, with optimized modals and layouts.
- 🛠️ How It Works Accordion: Guides users on searching, sorting, and understanding the scores.
- Frontend: HTML, CSS (Bootstrap 5) 🎨, JavaScript ⚡
- Backend: Node.js with Express.js 🚀
- Database: MongoDB Atlas 🗄️
- Web Scraping: Puppeteer 🕷️, Cheerio 🌿
- Deployment: Vercel 🛠️
- Automation: GitHub Actions 🕒

A clean, interactive homepage for LEGO enthusiasts.

Key price insights with visual indicators.
The Relevance Score is a calculated metric that helps users identify the best deals. It evaluates:
- Discount: The percentage off the original price.
- Popularity: Based on the number of comments and likes.
- Freshness: How recently the deal was published.
- Resalability: Resale potential based on average resale prices and listing activity.
- Temperature: A deal’s popularity among community users.
- Expiry: Whether the deal is expiring soon. The score ranges from 0% (low relevance) to 100% (high relevance).
The Relevance Score is a metric (ranging from 0 to 1) used to rank LEGO deals based on their value and appeal. It evaluates multiple factors with assigned weights to provide a comprehensive score.
Where:
-
$W$ : Weight assigned to each factor -
$S$ : Scaled score of each factor - Subscripts:
-
$d$ : Discount -
$p$ : Popularity -
$f$ : Freshness -
$e$ : Expiry -
$h$ : Heat -
$r$ : Resalability
-
-
Discount Score (
$S_d$ ): Percentage discount ($S_d = \min(\frac{\text{Discount}}{100}, 1)$ ). -
Popularity Score (
$S_p$ ): Community engagement ($S_p = \min(\frac{\text{Comments}}{\text{MAX COMMENTS}}, 1)$ ). -
Freshness Score (
$S_f$ ): Time since publication ($S_f = \max(1 - \frac{\text{Days}}{\text{MAX AGE DAYS}}, 0)$ ). -
Expiry Score (
$S_e$ ): Penalizes deals expiring soon ($S_e = 0.5$ if expiring soon,$S_e = 1$ otherwise). -
Heat Score (
$S_h$ ): Based on temperature ($S_h = \min(\frac{\text{Temperature}}{\text{MAX TEMPERATURE}}, 1)$ ). -
Resalability Score (
$S_r$ ): Combines:-
Profitability: (
$\max(\frac{\text{Resale Price} - \text{Price}}{\text{Price}}, 0)$ ), -
Demand: (
$\min(\frac{\text{Resale Listings}}{\text{MAX LISTINGS}}, 1)$ ), -
Velocity: (
$\min(\frac{\text{Weekly Resales}}{\text{MAX WEEKLY SALES}}, 1)$ ).
-
Profitability: (
- Discount: 20%
- Popularity: 20%
- Freshness: 15%
- Expiry: 5%
- Heat: 10%
- Resalability: 30%
- Profitability: 50%
- Demand: 30%
- Velocity: 20%
The Relevance Score provides a quick, data-driven insight into the best LEGO deals available.
- Data Collection: 🕷️ Deals are scraped from public sources like Dealabs and Vinted.
- Backend API: 📡 Data is stored in MongoDB Atlas and served through an Express.js API.
- Scheduled Updates: ⏰ GitHub Actions refresh the data automatically twice a day.
- Client Rendering: 🌟 The deals are displayed interactively with filtering, sorting, and responsive design.
The data refreshes automatically:
⏰ Daily at 5 AM and 6 PM UTC+2
Using GitHub Actions to ensure users always get the latest deals.
bricked-up/
├── client/
│ └── v2/
│ ├── index.html # Main client HTML file
│ ├── styles.css # Custom CSS styles
│ ├── portfolio.js # Client-side logic
│ ├── assets/ # Images and other assets
│ └── utils.js # Utility functions
│
├── server/
│ ├── api.js # Main server file (Express routes)
│ ├── refresh_database.js # Script to refresh MongoDB
│ ├── dealabs.js # Scraping script for Dealabs
│ ├── vinted.js # Scraping script for Vinted
│ └── node_modules/ # Installed dependencies
│
├── .github/
│ └── workflows/
│ └── database-refresh.yml # GitHub Actions for scheduled scraping
│
├── vercel.json # Vercel deployment configuration
├── package.json # Dependencies for server and client
└── README.md # Project documentation
- Public data sources: Dealabs and Vinted
- Frameworks & Tools: Bootstrap, Puppeteer, Node.js, MongoDB
- Icons: Flaticon
Developed by: Joyce Lapilus
Project Repository: GitHub
For inquiries, feel free to contact via joyce.lapilus@gmail.com.
This website aggregates publicly available data for educational and informational purposes only.
🔒 No malicious intent is associated with data scraping. For any concerns, feel free to contact me.
🎉 Thank you for visiting Bricked Up! 🧱✨

