Skip to content

KrisbelGV/scarlets_basement-proxy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

17 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Scarlet's Basement Proxy Logo

Node version License MIT Deploy Vercel

Scarlet's Basement β€” Proxy

Scratch public API proxy server (MIT). Provides extended user information and additional filters on basic functions, such as searching for projects and studios, plus exclusive indexing queries and a custom feed from your qualified followers.

Created by KrisbelGV as part of the educational and learning project "Scarlet's Basement" available on the Scarlet's Basement Website.

Features

  • πŸ” Extended search - Search projects and studios with additional filters (mode, profiles, discard terms)
  • πŸ‘€ User statistics - Get detailed summaries for any Scratch user
  • πŸ“‚ Studio finder - Locate studios by project ID and tags
  • πŸ“Š Indexing status - Check speculative indexing status of a project
  • πŸ‘₯ Custom feed - Curated following feed from qualified followers
  • ⚑ Rate limiting & circuit breaker - Protects Scratch API from overuse

Tech Stack

Category Technology
Runtime Node.js
Framework Express
Cache Upstash Redis
Deploy Vercel
API Source Scratch Public API

Table of contents

Installation

  1. Clone this repository

    git clone https://github.com/KrisbelGV/scarlets_basement-proxy.git
    cd scarlets_basement-proxy
  2. Ensure you have Node.js 18 or higher

    node --version  # Should be v18.x or higher
  3. Install the project dependencies

    npm install
  4. Create a .env file in the project root

    NODE_ENV=development
    PORT=300
  5. Run the development server

    npm run dev

Structure

Directories

scarlets-basement-proxy/
β”‚
β”œβ”€β”€ api/
β”‚   └── index.js
β”‚
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ controllers/
β”‚   β”‚   β”œβ”€β”€ aNewView.js
β”‚   β”‚   β”œβ”€β”€ findAStudio.js
β”‚   β”‚   β”œβ”€β”€ isItIndex.js
β”‚   β”‚   β”œβ”€β”€ search.js
β”‚   β”‚   └── userData.js
β”‚   β”‚
β”‚   β”œβ”€β”€ middleware/
β”‚   β”‚   β”œβ”€β”€ doorman.js
β”‚   β”‚   β”œβ”€β”€ errorHandler.js
β”‚   β”‚   └── validator.js
β”‚   β”‚
β”‚   β”œβ”€β”€ routes/
β”‚   β”‚   └── proxy.js
β”‚   β”‚
β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”œβ”€β”€ filterService.js
β”‚   β”‚   └── proxyService.js
β”‚   β”‚
β”‚   └── utils/
β”‚       β”œβ”€β”€ catchAsync.js
β”‚       β”œβ”€β”€ createAbortController.js
β”‚       └── upstash.js
β”‚
β”œβ”€β”€ package.json
β”œβ”€β”€ package-lock.json
└── vercel.json

Responsibilities by layer

Layer Archive Function
Entry point api/index.js Configure Express, CORS, set up routes
Routes src/routes/proxy.js Define endpoints and middleware chain
Middleware src/middleware/doorman.js Rate limiting, processing blocking, and circuit breaker
Middleware src/middleware/validator.js Input validation and sanitization
Middleware src/middleware/errorHandler.js Translates errors to HTTP responses
Controllers src/controllers/*.js They orchestrate the business logic
Services src/services/filterService.js Search, filter, statistics count
Services src/services/proxyService.js HTTPS client to Scratch
Utilities src/utils/upstash.js Lua scripts for Redis
Utilities src/utils/catchAsync.js Try/catch for async/await
Utilities src/utils/createAbortController.js Timeout for long operations

Design notes

Key technical decisionsβ€”and why certain approaches were rejected.

❌ Client-side filtering (discarded)

Using a third-party proxy to bypass CORS and filter on the browser was rejected due to privacy concerns. A browser-based solution would expose user requests and filtering patterns to external servers, whereas a server-side proxy keeps all processing under the project's control.

❌ Request queue system (discarded)

A queuing mechanism was prototyped to handle concurrent requests, but it produced an unacceptable error rate due to network latency and inter-service communication issues. It degraded user experience and consumed unnecessary resources, so it was removed.

❌ Resumable pagination (discarded)

The idea of adding mirrored endpoints to resume pagination after timeout limits was considered but rejected to preserve resources for diverse, non-exhaustive queries. The current five endpoints are sufficient, though this could be reconsidered based on user feedback.

βœ… Current approach

The proxy focuses on lightweight, stateless filtering with rate limiting and a circuit breaker to protect the Scratch API. All decisions prioritize reliability, privacy, and fair access for all users.

πŸ’‘ Open to collaboration – We remain open to working with external providers to reduce Scratch API load and develop new features, provided privacy standards are met.

Endpoints

All endpoints return a boolean abort field:

  • false β€” Complete result from Scratch API
  • true β€” Incomplete result (processing timeout or partial data)

Access policy: This API implements CORS restrictions and is only accessible from domains associated with KrisbelGV's GitHub repositories and the official Scarlet's Basement Website. You may test the API for educational or development purposes (console, browser, curl, Postman, etc.), but use in external projects is not open for discussion. Resources are limited and must be reserved to guarantee the proper functioning of this service.

GET /api/userdata/:username

Returns a summary of statistics for a given user.

Parameter Type Required Description
:username path βœ… Scratch username

GET /api/search

General search or profile-filtered search.

Parameter Type Required Description
q query βœ… Search terms
mode query ❌ Results order. Only trending accepted; popular is default
username query ❌ Specifies a user for the query
profile query ❌ Uses projects of specified profile(s) instead of general search
discard query ❌ Terms to exclude from results

GET /api/findastudio/:projectid

Returns studios associated with the given project ID.

Parameter Type Required Description
:projectid path βœ… Scratch project ID
tag query ❌ Filter by tag (without # symbol)

GET /api/isitindex/:projectid

Returns project statistics and speculative indexing status.

Parameter Type Required Description
:projectid path βœ… Scratch project ID

GET /api/anewview/:username

Returns a custom following feed for the given user.

Parameter Type Required Description
:username path βœ… Scratch username

License

This project is licensed under the MIT License. See the LICENSE file in this repository for the full terms.

How to contribute?

Contributions to the codebase are welcome! As an open-source educational project, we appreciate improvements, bug fixes, and documentation enhancements.

  1. Fork the repository
  2. Create a feature branch (git checkout -b feat/feature)
  3. Commit your changes (git commit -m 'Add feature')
  4. Push to the branch (git push origin feat/feature)
  5. Open a Pull Request
  6. After your PR is reviewed and merged by the maintainer, it will be automatically deployed

Note for contributors: Deployments are handled via GitHub Actions. All changes must go through a Pull Request. Direct pushes to main are protected and will be rejected.

For detailed tracking of bug fixes or updates, follow our news thread in the Scratch discussion forum.