Skip to content

About

Seize Platform - Backend

Resources

Stars

6 stars

Watchers

0 watching

Forks

Latest commit

 

History

6,119 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

6529SEIZE-BACKEND

This is a 2-part repository for

  1. 6529 Backend

  2. 6529 API

0. Repo Helpers

This repo includes a .envrc for direnv.

It is only used for repo-local shell helpers. Right now it adds the repo bin/ directory to your PATH, which makes commands like 6529, ghruns, and ghdeploy available anywhere inside this repository. Direct package-manager commands are blocked there; 6529 runs the npm version pinned by the current package through Corepack without replacing your machine-wide npm.

It does not load .env.local and it does not set NODE_ENV.

0.1 Setup direnv

  1. Install direnv on your machine.
  2. Enable the direnv shell hook.

For zsh, add this to ~/.zshrc:

eval "$(direnv hook zsh)"

For bash, add this to ~/.bashrc:

eval "$(direnv hook bash)"

Then reload your shell config, for example:

source ~/.zshrc

0.2 Allow this repo

From the repo root, run:

direnv allow

If .envrc changes later, run:

direnv allow

again to approve the updated file.

0.3 Verify

From the repo root, you should be able to run:

which 6529
which ghruns
ghruns

If you do not use direnv, bootstrap the same repo-scoped command once:

./bin/6529 bootstrap

See Backend Package Commands for bootstrap, command, enforcement, API, and independently packaged Lambda guidance.

ghruns is a shortcut for:

gh run list -R "6529-Collections/6529seize-backend"

In an interactive terminal, ghruns opens a live dashboard instead of printing a one-time snapshot. It refreshes automatically every 5 seconds, keeps the same repo scope, and still accepts the usual gh run list filters like --branch, --workflow, --status, and -L.

ghruns controls:

  • Up / Down moves through the recent runs

The dashboard falls back to plain gh run list output in non-interactive shells and when you use output-formatting flags like --json, --jq, or --template.

0.4 Deploy Helper

See Deployment for staging/production merges, service ordering, automatic frontend validation, and failure recovery.

ghdeploy triggers the GitHub Actions deploy workflow for this repo.

You can run it from anywhere inside this repository, but it only works in these locations:

  • In the repo root, it opens an interactive multi-select list of all deployable workflow services, including api.
  • In src/<service>, it uses the folder name as the deploy service.
  • In src/api-serverless, it maps to service api.

The single source of truth for deployable services is src/config/deploy-services.json. .github/workflows/deploy.yml is generated from it, and the API deploy UI reads the same JSON directly.

Before it triggers the GitHub workflow, it checks that:

  • the current branch is not detached
  • the working tree is fully clean, including no untracked files
  • the current branch has an upstream
  • the current branch is exactly in sync with its upstream after a fetch

0.4.1 Use ghdeploy from repo root

From the repo root, run:

ghdeploy

This opens:

  • a single-select environment picker for staging or prod
  • then a multi-select service picker with all deployable services

Environment picker controls:

  • Up / Down moves between staging and prod
  • Enter confirms the highlighted environment
  • q cancels

Service picker controls:

  • Up / Down moves through the service list
  • Space toggles the current service
  • Enter confirms the selected services
  • q cancels

The list scrolls automatically as you move beyond the visible items. j / k and x also work as fallback keys if your terminal handles arrows or space oddly.

Root mode supports staging batches. Production services are deployed one at a time from their service folders so each successful workflow can either hold the PR release note for another service or publish it.

0.4.2 Use ghdeploy from a service folder

If you only want to deploy one service, cd into that service folder and run:

cd src/tdhLoop
ghdeploy

Single-service mode opens the same environment picker and resolves the service from the current folder. For production it also asks for the merged PR number and whether this successful deploy should hold or publish the release note. Use hold while more services for that PR remain, then choose publish for the final service. The published note includes every successful service accumulated for that PR, even when later services deploy a descendant commit. For staging, it triggers:

gh workflow run "Deploy a service" \
  --ref <current-branch> \
  -f environment=<selected-environment> \
  -f service=<resolved-service> \
  -R 6529-Collections/6529seize-backend

Examples:

  • src/tdhLoop deploys service tdhLoop
  • src/api-serverless deploys service api

If you run ghdeploy from an unsupported folder, it fails with a clear error instead of guessing.

0.5 CI Pipeline Alerts

Deploy and WEB E2E workflows post signed outcomes to the CI waves through the backend API. Message formats, reply correlation, rerun behavior, and the backend-first rollout contract are documented in CI Pipeline Alerts.

0.6 Staging DB Local Sync

This repo includes local tooling to build a resumable staging MySQL dump and restore it into the local Docker MySQL service.

Common commands:

6529 run db:staging:resume
6529 run db:staging:fresh

See docs/staging-db-local-sync.md for setup, AWS credential behavior, restore-only usage, restart recovery, and troubleshooting.

1. Backend

1.1 Install

6529 ci

Use 6529 add <package> only when intentionally changing dependencies or regenerating package-lock.json. Direct npm, npx, and Corepack npm project commands are rejected.

1.2 Build

6529 run build

1.3 Environment

To run the project you need a .env file.

The name of your .env file must include the environment you want to run like .env.local / .env.development / .env.production

Sample .env file

1.4 Run

Before running anything, either manually run 6529 run migrate:up or make sure dbMigrationsLoop is run.

1.4.1 using the 6529 wrapper

6529 run backend:local

1.4.2 using PM2

pm2 start bash --name=6529backend -- -lc 'cd /path/to/6529seize-backend && ./bin/6529 run backend:local'

For the built development or production modes, use 6529 run backend:dev or 6529 run backend:prod respectively.

1.4.3 using AWS Lambda

This repository is configured to be runnable through AWS Lambdas. Each 'loop' folder in the code represents a lambda function and can be built and deployed on AWS individually. * Note: additional setup is required within AWS in order to configure environment variables and triggers for each lambda.

* Note: env can be one of: local / dev / prod

1.5 Notes

  • Running database for development: You can use docker and docker-compose for this. Run docker-compose up -d in project root and configure your .env exactly as DB part in .env.sample.

  • Database and ORM: Backend service is using TYPEORM. When starting a service, if the database is successful then the ORM will take care of synchronising the schema for the database and creating the necessary tables. * Note: You will need to create the database and user and provide them in the .env file. Only thing TypeORM doesn't take care of, are views. Those are created with migrations. So you should either run 6529 run migrate:up or make sure dbMigrationsLoop is run to be sure that all migrations are applied.

  • CRON: When starting the service, there are several scheduled cron jobs running at specific intervals which will consume data from the chain, process and save the result to the database. e.g. discovering NFTs - there is a scheduled cron job to run every 3 minutes which detects new nfts minted on the chain or any changes to existing nfts.

  • S3 and Video Compression: S3Uploader. The s3Uploader persists compressed versions of the nft images and videos on AWS S3. This worker is configured to only run in prod mode. Video compression requires ffmpeg installed on the running machine. Download instructions at: https://ffmpeg.org/

  • Creating new migrations: Run 6529 run migrate:new name-of-the-migration. Three new files are created in migrations folder. A javascript file and 2 SQL files. Find the "up" SQL file and write the SQL for new migration there. Then run 6529 run migrate:up to apply the new migration. You can write reverse migration if you wish in the "down" SQL file.

2. API

PORT: 3000

PATH: src/api-serverless

See The Memes submission signatures for the EIP-712 contract used to submit a Meme Card to Main Stage.

2.1 Install

cd src/api-serverless
6529 ci

2.2 Build

cd src/api-serverless
6529 run build

2.2.1 OpenAPI Contract Synchronization

Every change to src/api-serverless/openapi.yaml must be synchronized to the frontend repository in the same task, even when no frontend call site changes. First regenerate the backend artifacts:

cd src/api-serverless
6529 run generate:openapi

If the task's backend worktree is locally available on the backend feature branch containing the final spec, copy that exact spec to the frontend worktree's root openapi.yaml and regenerate the frontend client:

cp <backend_worktree>/src/api-serverless/openapi.yaml openapi.yaml
6529 run generate

If that backend worktree is not locally available, commit and push the final spec, then run bash scripts/refresh-api.sh <backend_feature_branch> from the frontend worktree before 6529 run generate. Pass the exact backend feature branch that contains the OpenAPI change, never the frontend branch. Do not omit the argument for unmerged feature work: omission defaults to backend main, which may not contain the change. Commit the frontend openapi.yaml and generated/ changes. Treat an unfinished frontend synchronization as a blocker, not as completed backend OpenAPI work.

2.3 Environment

To run the project you need a .env file.

The name of your .env file must include the environment you want to run like .env.local / .env.development / .env.production

Sample .env file

2.4 Run

From src/api-serverless:

6529 run dev

The API package's dev script runs with NODE_ENV=local. Staging and production API processes are built and deployed through the repository workflows.

2.5 RUN USING PM2

pm2 start bash --name=6529api -- -lc 'cd /path/to/6529seize-backend/src/api-serverless && ../../bin/6529 run dev'

Use the matching deployed-process command when configuring PM2 outside local development.

2.6 RUN USING AWS Lambda

The API is also configured to run as an AWS lambda and can be built and deployed on AWS on its own. * Note: additional setup is required within AWS in order to configure environment variables and API Gateway.

2.7 Rate Limiting

The API implements rate limiting to protect against abuse and ensure fair usage. Rate limiting is applied to all API requests and uses Redis for distributed rate limit tracking.

Important: Rate limiting requires Redis to be available. If Redis is not available, rate limiting will be automatically disabled even if API_RATE_LIMIT_ENABLED is set to true.

2.7.1 How It Works

Rate limiting uses a two-tier approach:

  1. Burst Limit: Maximum requests per second (short-term burst protection)
  2. Sustained Limit: Maximum requests per second averaged over a time window (long-term protection)

Both limits are checked for each request. If either limit is exceeded, the request is rejected with a 429 Too Many Requests response.

2.7.2 User Identification Priority

The rate limiter identifies users in the following priority order:

  1. Authenticated Wallet (highest priority)

    • Uses the wallet address from JWT authentication
    • Gets higher rate limits (authenticated config)
    • Format: wallet:{walletAddress}
  2. Signed Internal Request (for SSR requests)

    • Used for server-side requests from the web app (e.g., AWS Elastic Beanstalk)
    • Requires signed headers to prevent spoofing
    • Skips rate limiting entirely (bypasses all rate limit checks)
    • The signature ensures only the web app (with the secret) can generate valid requests
  3. IP Address (fallback)

    • Used when no authentication or internal request headers are present
    • Uses unauthenticated rate limits
    • Format: ip:{ipAddress}

2.7.3 Internal Request Signing (SSR Requests)

For server-side requests from the web app, you can bypass IP-based rate limiting by sending signed headers. This is necessary when all requests appear to come from the same IP (e.g., AWS Elastic Beanstalk).

Required Headers:

  • X-6529-Internal-Id: The internal ID (must match API_RATE_LIMIT_INTERNAL_ID env var)
  • X-6529-Internal-Timestamp: Unix timestamp in seconds
  • X-6529-Internal-Signature: HMAC-SHA256 signature

Signature Generation: The signature is calculated as:

HMAC-SHA256(secret, `${internalId}\n${timestamp}\n${method}\n${path}`)

Where:

  • secret = API_RATE_LIMIT_INTERNAL_SECRET (shared secret)
  • internalId = API_RATE_LIMIT_INTERNAL_ID (from env)
  • timestamp = Current Unix timestamp in seconds
  • method = HTTP method (GET, POST, etc.)
  • path = Request path (e.g., /api/nfts)

Security Features:

  • Timestamp tolerance: 5 minutes (prevents replay attacks)
  • Timing-safe comparison (prevents timing attacks)
  • Request method and path included in signature (prevents signature reuse)

Example (Node.js):

const crypto = require('crypto');

const internalId = process.env.API_RATE_LIMIT_INTERNAL_ID;
const secret = process.env.API_RATE_LIMIT_INTERNAL_SECRET;
const method = 'GET';
const path = '/api/nfts';
const timestamp = Math.floor(Date.now() / 1000);

const payload = `${internalId}\n${timestamp}\n${method}\n${path}`;
const signature = crypto
  .createHmac('sha256', secret)
  .update(payload)
  .digest('hex');

// Send headers
headers: {
  'X-6529-Internal-Id': internalId,
  'X-6529-Internal-Timestamp': timestamp.toString(),
  'X-6529-Internal-Signature': signature
}

2.7.4 Configuration

Rate limiting is configured via environment variables (see .env.sample):

Enable/Disable:

  • API_RATE_LIMIT_ENABLED: Must be set to 'true' to enable rate limiting (default: disabled)
    • Rate limiting also requires Redis to be available
    • If Redis is not available, rate limiting will be disabled even if this is set to 'true'

Authenticated Users:

  • API_RATE_LIMIT_AUTH_BURST: Burst limit per second (default: 30)
  • API_RATE_LIMIT_AUTH_SUSTAINED_RPS: Sustained requests per second (default: 10)
  • API_RATE_LIMIT_AUTH_SUSTAINED_WINDOW_SECONDS: Time window for sustained limit (default: 60)

Unauthenticated Users:

  • API_RATE_LIMIT_UNAUTH_BURST: Burst limit per second (default: 20)
  • API_RATE_LIMIT_UNAUTH_SUSTAINED_RPS: Sustained requests per second (default: 5)
  • API_RATE_LIMIT_UNAUTH_SUSTAINED_WINDOW_SECONDS: Time window for sustained limit (default: 60)

Internal Requests (SSR):

  • API_RATE_LIMIT_INTERNAL_ID: Internal ID for signed requests (required)
  • API_RATE_LIMIT_INTERNAL_SECRET: Shared secret for signing requests (required)

2.7.5 Response Headers

All responses include rate limit headers:

  • X-RateLimit-Limit: Maximum requests allowed
  • X-RateLimit-Remaining: Remaining requests in current window
  • X-RateLimit-Reset: Unix timestamp when the rate limit resets

When rate limited (429 response):

  • Retry-After: Seconds to wait before retrying

2.7.6 Implementation Details

  • Storage: Uses Redis sorted sets for efficient sliding window tracking
  • Redis Required: Rate limiting requires Redis to be available. If Redis is not available, rate limiting is automatically disabled at startup
  • Fail Open: If rate limiting middleware encounters an error during request processing, requests are allowed (fail open behavior)
  • Distributed: Works across multiple API instances using shared Redis
  • Efficient: Uses sorted sets with automatic expiration for memory management

3. Admin Panel (Optional)

Currently 6529.io uses an Admin Panel to manage:

  • distribution lists and presentations
  • team members
  • royalties

The admin panel repo is located here.

* Note: Please bear in mind that in the near future the admin panel will be deprecated and all functionality will be moved to the 6529SEIZE-BACKEND repo.

About

Seize Platform - Backend

Resources

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages