Nova-Rewards

Code Style Guide

This document defines the coding standards for Nova Rewards. Consistent style keeps the codebase readable and maintainable for everyone.


Table of Contents


General Principles


TypeScript & JavaScript

Language

Syntax

// ✅ Good
const getUserBalance = async (userId: string): Promise<number> => {
  const user = await db.users.findById(userId);
  if (!user) throw new Error(`User not found: ${userId}`);
  return user.balance;
};

// ❌ Avoid
async function getBalance(id) {
  const u = await db.users.findById(id);
  return u.balance;
}

Imports

// External
import express from 'express';

// Internal
import { rewardUser } from '@/services/rewardService';

// Types
import type { Campaign } from '@/types';

Rust / Soroban Contracts

/// Issues reward tokens to a user after a qualifying action.
pub fn issue_reward(env: Env, recipient: Address, amount: i128) -> Result<(), Error> {
    recipient.require_auth();
    // ...
}

Naming Conventions

Context Convention Example
Variables & functions camelCase getUserRewards, tokenAmount
React components PascalCase RewardCard, CampaignList
Constants UPPER_SNAKE_CASE MAX_REWARD_LIMIT
Files (TS/JS) kebab-case reward-service.ts
Files (React) PascalCase RewardCard.tsx
Rust functions snake_case issue_reward, get_balance
Rust types/structs PascalCase RewardPool, AdminRole
Database columns snake_case user_id, created_at
Environment vars UPPER_SNAKE_CASE STELLAR_SECRET_KEY

File & Folder Structure


Linting & Formatting

The project uses ESLint and Prettier. Run before every commit:

# Backend / Frontend (Node.js)
npm run lint
npm run format

# Contracts (Rust)
cargo fmt --all
cargo clippy -- -D warnings

Comments & Documentation

/**
 * Calculates the reward multiplier for a given campaign tier.
 * @param tier - Campaign tier level (1–5)
 * @returns Multiplier value between 1.0 and 3.0
 */
export const getMultiplier = (tier: number): number => { ... };