A cloud-native SaaS web application for peer-to-peer second-hand trading within the CUHK community, built with Ruby on Rails.
Live Demo: https://cuhk-marketplace-csci3100-6b82f95ad3ac.herokuapp.com/
- Tech Stack
- Prerequisites
- Setup Guide
- Running Tests
- Implemented Features
- Feature Ownership
- Test Coverage
- Project Structure
| Component | Technology |
|---|---|
| Framework | Ruby on Rails 7.2 |
| Language | Ruby 3.3.8 |
| Database | PostgreSQL (with pg_trgm) |
| Real-time | ActionCable (WebSocket) |
| Background Jobs | Sidekiq + Redis |
| Payments | Stripe API |
| AI | OpenAI GPT-3.5-turbo |
| Frontend | Hotwire (Turbo + Stimulus), TailwindCSS |
| Testing | RSpec (unit/integration), Cucumber (BDD) |
| CI/CD | GitHub Actions, Heroku |
- OS: Linux or macOS (WSL2 Ubuntu 22.04+ on Windows)
- Ruby: 3.3.8 (via
rbenvorrvm) - Node.js: v18+ (for asset compilation)
- PostgreSQL: 14+
- Redis: 6+ (required for Sidekiq background jobs; ActionCable uses async adapter in development)
git clone https://github.com/yukariyukaro/CSCI3100.git
cd CSCI3100# Install system libraries (Ubuntu/Debian)
sudo apt update && sudo apt install -y libpq-dev build-essential
# Install Ruby gems
bundle install# Start PostgreSQL service
sudo service postgresql start
# Create a database superuser (if not yet created)
sudo -u postgres createuser -s $(whoami)
# Create and migrate the database
bin/rails db:prepareCreate a .env file in the project root (never commit this file):
# Required for Stripe payment integration
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
# Required for AI summarization
OPENAI_API_KEY=sk-...
# Payment provider: "stripe" or "fake" (default: "fake" for development)
PAYMENT_PROVIDER=fake# Option A: Rails server only
bin/rails server
# Option B: Rails + TailwindCSS watcher (recommended)
bin/devVisit http://localhost:3000 to see the application.
bundle exec sidekiqbin/rails demo:resetDemo accounts:
- Seller:
[email protected]/password123 - Buyer:
[email protected]/password123
bundle exec rspecbundle exec cucumberbundle exec rubocopbundle exec bundle-audit --updatebundle exec rubocop && bundle exec rspec && bundle exec cucumber| # | Feature | Description |
|---|---|---|
| 1 | User Authentication | Secure registration and login with bcrypt. Session-based auth with login protection on all routes. |
| 2 | Product Listing & Management | Sellers can create, view, and unlist products. Image upload via ActiveStorage (JPEG/PNG, ≤5 MB). |
| 3 | Product Browsing & Sorting | Browse all visible products with sorting by price (asc/desc) and time. |
| # | Feature | Description |
|---|---|---|
| 1 | Payment Integration (Stripe) | Full Stripe Checkout flow with webhook signature verification, idempotent event processing (PaymentWebhookEvent + row-level locking), amount reconciliation, and manual intervention for mismatches. Includes a Fake provider for development/testing. |
| 2 | Real-Time Chat (ActionCable) | WebSocket-based live messaging between buyer and seller per product. Conversations are scoped to authorized participants only. Messages are broadcast in real time via ActionCable. |
| 3 | Fuzzy Search & Autocomplete | Full-text search powered by PostgreSQL pg_search with tsvector and pg_trgm (trigram) for typo-tolerant matching. Autocomplete endpoint with server-side caching (5-minute TTL). |
| 4 | AI Smart Summarization (OpenAI) | Automatic product description summarization using OpenAI GPT-3.5-turbo. Triggered on product view, processed asynchronously via AiSummarizationJob. Summaries reset when description is edited. |
| 5 | Automated Background Processing (Sidekiq) | Sidekiq + Redis infrastructure for async job execution. Includes AiSummarizationJob for AI processing and ListingMaintenanceJob for auto-archiving listings older than 30 days. |
| Feature | Description |
|---|---|
| Transaction State Machine | Product lifecycle: active → pending → sold/unlisted. All state transitions use with_lock for concurrency safety. |
| Theme Toggle (Day/Night) | Client-side dark/light mode toggle with persistent preference. |
| Demo Data System | Rake tasks (demo:reset, demo:seed) for reproducible demo data with avatar/image restoration. |
| CI/CD Pipeline | GitHub Actions: RuboCop linting, bundle-audit security scan, RSpec, Cucumber. Auto-deploy to Heroku on merge to main. |
| Feature | Lead | Assist |
|---|---|---|
| Payment & Stripe Integration | TAN Yihao | DENG Zhen |
| Real-Time Chat (ActionCable) | YANG Longji | |
| Fuzzy Search & Autocomplete | TAN Yihao | |
| AI Smart Summarization (OpenAI) | JIAO Haonan | LI Peijin |
| Background Processing (Sidekiq) | LI Peijin | |
| User Auth, Profile, Listings & UI | JIAO Haonan |
| Name | Student ID | GitHub Handle |
|---|---|---|
| YANG Longji | 1155191588 | @LifeBeginner-ylj |
| TAN Yihao | 1155211107 | @sty0000 |
| LI Peijin | 1155211221 | @DOR09 |
| JIAO Haonan | 1155211226 | @yukariyukaro |
| DENG Zhen | 1155233370 | @DengZhen21 |
SimpleCov is configured in spec/rails_helper.rb and generates an HTML report after each RSpec run.
To generate the coverage report:
bundle exec rspecAfter the test suite completes, open coverage/index.html in a browser to view the report.
SimpleCov Report:
app/
├── channels/ # ActionCable channels (ChatChannel)
├── controllers/ # Request handlers (Products, Payments, Conversations, etc.)
├── helpers/ # View helpers
├── javascript/ # Stimulus controllers, Turbo config
├── jobs/ # Background jobs (AiSummarizationJob, ListingMaintenanceJob)
├── mailers/ # (reserved)
├── models/ # ActiveRecord models + concerns (ProductSearch)
├── services/ # Business logic layer
│ ├── ai/ # AI summarizer (OpenAI integration)
│ ├── payments/ # Payment providers (Stripe, Fake), webhook processor
│ ├── pricing/ # (reserved)
│ └── search/ # (reserved)
└── views/ # ERB templates
config/ # Rails configuration, routes, initializers
db/ # Schema, migrations, seeds
spec/ # RSpec tests (models, requests, services, system, views)
features/ # Cucumber BDD scenarios
.github/workflows/ # CI (ci.yml) and deployment (deploy.yml)
This project is developed for CSCI3100 Software Engineering (Spring 2026) at The Chinese University of Hong Kong. All rights reserved.
