System Architecture

How EquiPassr Works

A deep dive into the core data flows, expiration rules engine, offline architecture, and security model powering EquiPassr's real-time horse show verification system.

Core User Flows

Owner Flow
1
Create Account
2
Add Horse Profile
3
Upload Documents
4
View QR Pass
5
Check Event Requirements
6
Show QR at Gate
Secretary Flow
1
Create Event
2
Set Doc Requirements
3
Open QR Scanner
4
Scan Horse QR
5
Server Verifies Docs
6
Green / Red Result
Admin Flow
1
Manage Doc Types
2
Set Expiry Rules
3
Monitor Platform
4
Manage Users
5
View Analytics
6
Configure System

QR Verification Flow

Owner's Phone

QR code displayed

Secretary Scans

Camera reads token

Server Query

Live DB lookup

Document Check

Rules engine evaluates

Result Shown

Green/Red on secretary

Why server-side verification?

The QR code on the owner's phone contains only a signed token. No document data is ever on-device. Secretaries cannot be shown fake screenshots — the server always queries live data.

Anti-fraud design

Results appear only on the secretary's device. Owners never see pass/fail, preventing screenshot fraud. Tokens are cryptographically signed with rotation on each login.

Expiry Rules Engine

All rules are stored in the database and managed via admin panel — no code deployment required

Coggins Test

Health
365 days

Equine Infectious Anemia

Health Certificate

Health
30 days

Issued by licensed vet

Rabies Vaccination

Vaccination
365 days

Annual requirement

Flu/Rhino Vaccination

Vaccination
180 days

Bi-annual

USEF Membership

Membership
365 days

Calendar year

Brand Inspection

Registration
730 days

State-specific

Rules Engine Logic

function verifyDocuments(horse, event) {
  const results = [];
  
  for (const requirement of event.requirements) {
    if (!requirement.required) continue;
    
    const doc = horse.documents.find(
      d => d.documentTypeId === requirement.documentTypeId
    );
    
    if (!doc) {
      results.push({ pass: false, reason: `Missing: ${requirement.name}` });
      continue;
    }
    
    const daysOld = differenceInDays(new Date(), doc.expirationDate);
    
    if (daysOld < 0) {
      results.push({ pass: false, reason: `${doc.name} expired ${Math.abs(daysOld)}d ago` });
    } else {
      results.push({ pass: true });
    }
  }
  
  return {
    pass: results.every(r => r.pass),
    reasons: results.filter(r => !r.pass).map(r => r.reason)
  };
}

Offline-First Architecture

Offline Mode

  • Owners view horse profiles + documents
  • QR passes displayed offline
  • Secretaries scan and cache results
  • Check-ins queued for sync

Background Sync

  • Detects connectivity restored
  • Flushes queued check-ins to server
  • Pulls latest doc updates
  • Conflict resolution with server wins

Data Flow Diagram

Service Worker (Workbox)

Caches assets, intercepts requests

IndexedDB (Dexie.js)

Local horse, doc, event data

Sync Queue

Pending mutations waiting to sync

Background Sync API

Triggered on reconnect

REST API Server

Authoritative source of truth

Technology Stack

Frontend

Next.js 14 + TypeScript

App Router, SSR

State

Zustand + localStorage

Offline-first persistence

Auth

JWT + Role-based

Owner / Secretary / Admin

Offline

Workbox + Dexie.js

IndexedDB local storage

Sync

Background Sync API

Auto-sync when online

QR

Signed tokens (server)

Anti-screenshot fraud

Storage

AWS S3 / Cloudflare R2

Document file storage

Database

PostgreSQL + Prisma

Relational, type-safe

Security Model

Role-Based Access Control
  • Owner: own horses only
  • Secretary: assigned events only
  • Admin: full platform access
  • JWT tokens with role claims
QR Token Security
  • Server-signed HMAC tokens
  • Tokens rotate on session change
  • No document data in QR payload
  • Server-only verification
Data Integrity
  • Server-authoritative verification
  • Offline results reconciled
  • Immutable check-in logs
  • Audit trail for all scans