Skip to main content

Architecture Overview

GenLayer Points is a full-stack web application built with a Django REST API backend and a Svelte 5 frontend, connected through RESTful APIs. The system uses blockchain integration for authentication and validator data.

Technology Stack

Frontend

Svelte 5

Modern reactive UI framework with runes mode for optimal performance and developer experience.

Vite

Fast build tool with hot module replacement and optimized production builds.

Tailwind CSS

Utility-first CSS framework for rapid UI development with consistent styling.

Axios

HTTP client for API communication with interceptors for auth and error handling.

Backend

Django 4.2+

Robust web framework with ORM, admin interface, and extensive ecosystem.

Django REST Framework

Powerful toolkit for building Web APIs with serialization and viewsets.

PostgreSQL

Production database with ACID compliance and advanced features.

SIWE

Sign-In With Ethereum for decentralized authentication.

Infrastructure

  • AWS App Runner - Managed container service for backend
  • AWS Amplify - Frontend hosting with CI/CD
  • AWS RDS - Managed PostgreSQL database
  • Docker - Containerization for consistent deployments

Component Architecture

Backend Components

Django Apps Structure

Each Django app follows the Model-View-Serializer pattern:
app/
├── models.py         # Data models
├── views.py          # API viewsets
├── serializers.py    # Data serialization
├── admin.py          # Admin configuration
├── urls.py           # URL routing
├── tests/            # Test suite
└── migrations/       # Database migrations

Core Apps

Purpose: User management and authenticationKey Models:
  • User - Custom user model with email auth and Ethereum address
Responsibilities:
  • User registration and profile management
  • Ethereum address linking
  • GitHub OAuth integration
  • Referral system
API Endpoints:
  • /api/v1/users/me/ - Current user profile
  • /api/v1/users/by-address/{address}/ - User lookup

Frontend Components

Component Hierarchy

App.svelte (Root)
├── Navbar.svelte (Global navigation)
├── Sidebar.svelte (Category navigation)
├── ToastContainer.svelte (Notifications)
└── Router (Page components)
    ├── Overview.svelte
    ├── TestnetAsimov.svelte
    ├── Leaderboard.svelte
    │   └── LeaderboardTable.svelte
    ├── Profile.svelte
    │   ├── UserContributions.svelte
    │   └── ValidatorStatus.svelte
    └── SubmitContribution.svelte

State Management

Svelte Stores for global state:
  • authState - Authentication status and wallet address
  • userStore - Current logged-in user data
  • toastStore - Notification queue
Reactive State ($state) for component-local state Derived State ($derived) for computed values

Data Flow

Contribution Submission Flow

Authentication Flow

Leaderboard Calculation

Key Design Patterns

Backend Patterns

1. Base Model Pattern

All models inherit from BaseModel for automatic timestamps:
from utils.models import BaseModel

class Contribution(BaseModel):
    # Automatically includes:
    # - created_at
    # - updated_at
    pass

2. Context-Aware Serialization

Optimize API performance with light serializers:
class LightUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'email', 'name']  # Minimal fields

class UserSerializer(serializers.ModelSerializer):
    # Check context to determine which nested serializer to use
    contributions = serializers.SerializerMethodField()
    
    def get_contributions(self, obj):
        use_light = self.context.get('use_light_serializers', False)
        if use_light:
            return LightContributionSerializer(obj.contributions, many=True).data
        return ContributionSerializer(obj.contributions, many=True).data

3. Signal-Based Updates

Automatic leaderboard updates via Django signals:
@receiver(post_save, sender=Contribution)
def update_leaderboard_on_contribution(sender, instance, created, **kwargs):
    if created:
        update_user_leaderboard_entries(instance.user)
        if instance.user.referred_by:
            update_referrer_points(instance)

4. Frozen Points Pattern

Points are calculated once and frozen to prevent retroactive changes:
class Contribution(BaseModel):
    points = PositiveIntegerField()
    multiplier_at_creation = DecimalField()  # Locked at creation
    frozen_global_points = PositiveIntegerField()  # Never changes
    
    def save(self, *args, **kwargs):
        if not self.pk:  # New contribution
            multiplier = get_active_multiplier()
            self.frozen_global_points = self.points * multiplier
        super().save(*args, **kwargs)

Frontend Patterns

1. Component Composition

Reusable components with props:
// Parent
<LeaderboardTable entries={data} type="validator" />

// Child component
let { entries, type } = $props();

2. Store Pattern

Global state with Svelte stores:
// userStore.js
import { writable } from 'svelte/store';

function createUserStore() {
  const { subscribe, set, update } = writable(null);
  
  return {
    subscribe,
    loadUser: async () => {
      const user = await api.getCurrentUser();
      set(user);
    },
    updateUser: (updates) => update(u => ({ ...u, ...updates })),
    clearUser: () => set(null)
  };
}

export const userStore = createUserStore();

3. API Client Pattern

Centralized API with interceptors:
const apiClient = axios.create({
  baseURL: API_BASE_URL,
  withCredentials: true
});

// Request interceptor
apiClient.interceptors.request.use(config => {
  // Add auth headers
  return config;
});

// Response interceptor
apiClient.interceptors.response.use(
  response => response,
  error => {
    if (error.response?.status === 401) {
      // Handle auth errors
    }
    return Promise.reject(error);
  }
);

Security Architecture

Authentication

  • SIWE (Sign-In With Ethereum) for wallet-based auth
  • Session cookies (httpOnly, secure, sameSite)
  • CSRF protection for state-changing operations
  • No JWT in localStorage (security best practice)

Authorization

  • Django permissions for admin operations
  • Object-level permissions for user-owned resources
  • Steward roles for submission review

Input Validation

  • Django model validation at database level
  • DRF serializer validation at API level
  • Frontend validation for user experience
  • reCAPTCHA v2 for spam prevention

Data Protection

  • Environment variables for secrets
  • AWS Parameter Store for production config
  • HTTPS only in production
  • CORS configuration for API access control

Performance Considerations

Backend Optimizations

  1. Query Optimization
    • select_related() for ForeignKey/OneToOne
    • prefetch_related() for reverse/ManyToMany
    • Database indexing on frequently queried fields
  2. Serialization
    • Light serializers for list views
    • Full serializers for detail views
    • Conditional field inclusion
  3. Caching
    • Session caching
    • QuerySet caching where appropriate

Frontend Optimizations

  1. Code Splitting
    • Route-based lazy loading
    • Dynamic imports for large components
  2. Asset Optimization
    • Vite’s automatic code splitting
    • Image optimization
    • CSS purging with Tailwind
  3. State Management
    • Minimize store subscriptions
    • Use derived state for computed values
    • Debounce API calls

Scalability

Horizontal Scaling

  • Stateless backend - Can run multiple instances
  • Load balancer - AWS Application Load Balancer
  • Database connection pooling - pgBouncer for PostgreSQL

Vertical Scaling

  • Database optimization - Indexes, query optimization
  • App Runner auto-scaling - Based on CPU/memory
  • RDS scaling - Upgrade instance types as needed

Monitoring & Logging

Backend Logging

from tally.middleware.logging_utils import get_app_logger

logger = get_app_logger('contributions')
logger.info('Contribution created', extra={'user_id': user.id})

Error Tracking

  • Django error emails in production
  • Structured logging for debugging
  • API error responses with details

Next Steps

Data Model

Detailed database schema

Authentication Flow

SIWE implementation details

Deployment

AWS deployment guide

Environment Variables

Configuration reference

Build docs developers (and LLMs) love