AttendEx is a modern, high-performance, and offline-first event attendance tracking system designed for reliable scanning and insightful analytics. The system enables Organizers to manage event logistics and rosters through a beautiful web dashboard, Scanners to capture check-ins/check-outs instantly on site via a smart Android mobile app, and Stewards to manage multi-tenant platforms.
graph TD
subgraph Client Applications
A[Next.js Web Portal<br/><i>Organizers</i>] -->|REST API & JWT| C[Spring Modulith Backend<br/><i>Platform</i>]
B[Android Capture App<br/><i>Scanners</i>] -->|Offline Sync & JWT| C
end
subgraph Data & Storage
C -->|JPA & Flyway| D[(PostgreSQL Database)]
B -->|SQLite| E[(Local Room DB)]
end
A modular monolithic application built with Java 21 and Spring Boot 3.5.7, leveraging Spring Modulith 1.4.4 to enforce domain-driven architectural boundaries.
- Modular Architecture: Isolated business domains (
admin,analytics,attendee,audit,capture,event,identity,notification,organization,report) which keeps boundaries clean and testing focused. - Performance Engineered: Optimized connection pooling via HikariCP, transactional performance tuning with
open-in-view=false, and batched database writes for sub-millisecond response rates. - Robust Security: Stateless API authentication using HS512 JWT tokens.
- Migration-Driven Schema: Automated database scheme evolutionary steps utilizing Flyway.
- Rich Integrations: Dynamic template rendering with Thymeleaf, high-fidelity PDF report compilation using OpenHTMLtoPDF, and efficient CSV imports/exports via Apache Commons CSV.
- Test Isolation: Thorough integration testing backed by Testcontainers for live PostgreSQL environments.
A beautiful, highly interactive dashboard built with Next.js 15 (Turbopack), TypeScript, and Tailwind CSS.
- Visual Polish: Crafted with curated harmonic color palettes, subtle micro-animations via
tw-animate-css, smooth gradients, and components backed by shadcn/ui and Radix UI. - Fluid UX: State management driven by Zustand and server-state caching powered by TanStack React Query.
- Advanced Analytics: Dynamic data visualizations, timelines, and statistics using Recharts to track attendee punctuality, session capacity, and overall engagement.
- Data Grid Engine: Powerful searching, filtering, paginating, and sorting of attendee rosters using TanStack React Table.
An offline-first Android application developed in Kotlin leveraging Jetpack Compose for a modern declarative interface.
- Offline-First Sync Engine: Scanners can operate with 100% functionality without cellular/Wi-Fi coverage. Local states are backed by a structured Room (SQLite) database.
- Idempotent Background Synchronization: Chronological entries are queued locally and synced back to the platform asynchronously using Android's WorkManager and Hilt injection, ensuring perfect data deduplication.
- Smart Barcode & OCR Scanner: High-speed, on-device barcode and QR-code scanning integrated through Google ML Kit Barcode Scanning and CameraX.
- On-Device OCR Integration: Features Google ML Kit Text Recognition (OCR) to parse and recognize student/employee IDs from standard text-based identity cards directly in real time.
AttendEx operates on strict Bounded Contexts aligned with Domain-Driven Design (DDD):
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β AttendEx Domain β
ββββββββββββββββββββββββ¬βββββββββββββββββββββββββ¬βββββββββββββββββββββββββ€
β π‘οΈ Admin Context β ποΈ Organization Contextβ πΈ Capture Context β
β Steward manages β Organizers configure β Scanners execute β
β platform tenants, β Events, Sessions, β Offline-First Scans, β
β organizations & β Grace windows, and β creating timestamped β
β subscriptions. β rosters of Attendees. β Entries. β
ββββββββββββββββββββββββ΄βββββββββββββββββββββββββ΄βββββββββββββββββββββββββ
For a comprehensive definition of the domain architecture, Bounded Context rules, and terms, refer to the Ubiquitous Language & Model Guide.
attendex/
βββ capture/ # Android Mobile Application (Kotlin, Jetpack Compose)
β βββ app/ # Main application source code
β βββ build.gradle.kts# Root build scripts
βββ platform/ # Modular Spring Boot Backend (Java 21, Spring Modulith)
β βββ src/ # Source code and resource templates
β βββ pom.xml # Maven configuration
βββ web/ # Next.js Web Dashboard (TypeScript, Tailwind, shadcn/ui)
β βββ app/ # App router, pages & views
β βββ components/ # Reusable UI component library
β βββ package.json # Next.js package config
βββ compose.yaml # Development services setup (PostgreSQL)
βββ model.md # Domain model & vocabulary documentation
βββ .env.example # Shared environment configuration templateEnsure you have the following installed on your system:
- Docker (with Docker Compose)
- Java Development Kit (JDK) 21 or higher
- Node.js v20.x or higher
- Android Studio (for mobile development)
Clone the repository and copy the sample environment file to create your local variables:
cp .env.example .env(Adjust the variables in .env if you have specific port or credentials requirements).
Spin up the development PostgreSQL instance via Docker Compose:
docker compose up -dThe database will run on the port defined in your .env (default is 5432) with a container health check.
Navigate to the platform directory and run the Spring Boot application using the Maven wrapper:
cd platform
./mvnw spring-boot:run- The API Server will start on
http://localhost:8080. - Flyway automatically runs database migrations on boot.
- Spring Modulith validates modules boundaries automatically.
Open a new terminal, navigate to the web directory, install dependencies, and start the development server:
cd web
npm install
npm run dev- The dashboard will spin up on
http://localhost:3000. - Any edits will instantly hot-reload using Next.js Turbopack.
Import the capture directory into Android Studio.
- Local Backend Endpoint: By default, the app is configured to look at the IP specified in
capture/app/build.gradle.kts(e.g.192.168.106.218:8080). UpdateAPI_BASE_URLinbuild.gradle.ktsto point to your development server's network-accessible local IP address. - Connect an Android device or launch an emulator.
- Build and run the project (
Shift + F10in Android Studio) or run using Gradle wrapper:cd capture ./gradlew installDebug
To run automated checks across the components:
Run Modulith validation, integration tests, and mock assertions inside the platform container:
cd platform
./mvnw clean testTestcontainers will launch an ephemeral Postgres instance to run deep integration tests automatically.
Check TypeScript types and run ESLint code formatting checks:
cd web
npm run lintThis project is proprietary and confidential. All rights reserved.