Architecture

Technical architecture and system design of the Snek platform

System Overview

Snek follows a layered architecture pattern with clear separation of concerns. The system is built on Python's aiohttp framework for asynchronous HTTP and WebSocket handling.

Frontend Layer
Vanilla JavaScript ES6 Modules | Custom Elements | WebSocket Client
View Layer
HTTP Handlers | WebSocket RPC | Template Rendering | Form Processing
Service Layer
Business Logic | Caching | Event Broadcasting | Authentication
Mapper Layer
Data Access | CRUD Operations | Soft Delete | Query Building
Database Layer
SQLite | Dataset ORM | Schema Management

Backend Architecture

aiohttp Framework

The backend is built on aiohttp, a high-performance asynchronous HTTP client/server framework. Key features:

Service Layer Pattern

Services encapsulate business logic and are accessed via a singleton registry:

user = await app.services.user.get(uid=user_uid)
channel = await app.services.channel.create(label="#general")

Available services include: user, channel, channel_member, channel_message, chat, socket, container, db, and more.

Mapper Pattern

Mappers provide data access abstraction with consistent CRUD operations:

await mapper.get(uid=uid)
await mapper.find(field=value)
await mapper.save(model)
async for record in mapper.query(sql, params): ...

All mappers support soft delete via the deleted_at field.

Caching Strategy

The service layer implements UID-based caching for frequently accessed data. Cache invalidation occurs on model updates.

Frontend Architecture

Vanilla JavaScript Philosophy

The frontend uses pure ES6 JavaScript modules without any frameworks. This ensures:

Module Structure

src/snek/static/
  app.js           # Main Application class (singleton)
  socket.js        # WebSocket RPC client
  chat-window.js   # Chat interface component
  message-list.js  # Message rendering
  chat-input.js    # Input handling
  ...

Custom Elements

UI components are implemented as Custom Elements:

<chat-window></chat-window>
<message-list></message-list>
<channel-menu></channel-menu>
<nav-menu></nav-menu>

Each component has its own CSS file (no Shadow DOM per project guidelines).

Database Design

Dataset ORM

Snek uses Dataset, a simple database abstraction layer built on SQLAlchemy. It provides:

Core Tables

user           # User accounts
channel        # Chat channels
channel_member # Channel membership
channel_message# Chat messages
session        # User sessions
...

Soft Delete Pattern

Records are never physically deleted. Instead, the deleted_at timestamp is set. All queries filter by deleted_at IS NULL by default.

Real-time Communication

WebSocket RPC System

Real-time features use a JSON-RPC style protocol over WebSocket:

{
  "callId": "1",
  "method": "send_message",
  "args": ["channel_uid", "Hello world", true]
}

The server responds with:

{
  "callId": "1",
  "success": true,
  "data": "message_uid"
}

Event Broadcasting

Server-initiated events are broadcast to channel subscribers:

{
  "channel_uid": "...",
  "event": "new_message",
  "data": { ... }
}

Channel Subscription Model

Users automatically subscribe to all their channels on WebSocket connection. The socket service manages subscriptions and delivers messages to the appropriate clients.

Directory Structure

src/snek/
  __main__.py      # CLI entry point
  app.py           # Application setup and routing
  view/            # HTTP/WebSocket handlers
    index.py       # Landing page
    rpc.py         # WebSocket RPC
    settings/      # Settings views
  service/         # Business logic layer
  mapper/          # Data persistence
  model/           # Data models
  form/            # Form definitions
  system/          # Core infrastructure
    view.py        # BaseView class
    service.py     # BaseService class
    mapper.py      # BaseMapper class
    model.py       # BaseModel class
  static/          # Frontend JavaScript and CSS
  templates/       # Jinja2 templates