Skip to content

Repository files navigation

Platform

A Turborepo monorepo for a community platform built with Next.js 15, React 19, and Material UI.

Live: vuohiliitto.com (production) | Vercel deployment

This platform is in active production use by a real community, with the custom domain vuohiliitto.com configured on Vercel.

Structure

apps/hrm/        β€” HRM application (git submodule, standalone showpiece)
apps/web/        β€” Community platform (Next.js 15)
packages/ui/     β€” Shared UI components (@platform/ui)
packages/config/ β€” Shared types and config (@platform/config)

Features

Community

  • Unified Chat Box β€” WoW-inspired tabbed chat on the landing page combining guild chat and private whispers in one box:
    • Guild tab β€” Public IRC-style shoutbox with <alias> message format, optimistic updates, superuser star icons, and developer tag emoji badges (πŸ’»πŸŽ¨πŸ“–πŸ—οΈπŸ”­πŸ§ πŸ‘‘)
    • Whisper tabs β€” Private DM conversations in pink WoW whisper style (To [alias]: / [alias] whispers:) with closable tabs, unread badges, developer tag icons, and superuser indicators
    • /w alias message β€” Slash command to whisper any user from any tab, with live autocomplete suggestions and Tab key completion as you type
    • Privacy Inbox β€” Superuser gets a special locked conversation for data protection inquiries (privacy@vuohiliitto.com)
    • /help β€” Shows available chat commands (client-only, not sent to chat)
    • /motd message β€” Superuser and architects can change the welcome message
    • Tab autocomplete β€” Ghost text overlay shows completion as you type /w, Tab key accepts
  • Quick Feedback β€” Users can submit short feedback (up to 1000 chars) from the feedback page; admins can reply to individual entries; collapsible accordion view
  • Dev Log β€” Live GitHub commit feed with color-coded build status (green/red/pending), 10-minute cache, visible to all visitors
  • Issue Tracker β€” Report and resolve issues; superuser can manage issue status
  • User aliases β€” Public display names (callsigns) shown instead of real names, editable from account page
  • Themes β€” 8 switchable themes including Epic (WoW-inspired with Cinzel font, textured backgrounds, gold ornamental borders)
  • i18n β€” Multilingual support (Finnish, English, Somali, Arabic) via next-intl with cookie-based locale detection, Accept-Language fallback, and RTL support for Arabic
  • Pending user gate β€” New users complete the survey, then see a "Waiting for approval" screen until an admin assigns them a role

Gamification

  • XP System β€” Earn XP for platform actions (shouts, completing surveys, submitting feedback, login streaks, sending DMs, reporting issues)
  • 10-level progression β€” Newcomer through Mythic with XP thresholds and level-up celebrations
  • Achievements β€” 16 unlockable achievements across categories (onboarding, social, streaks, moderation) including "Demo Explorer" for completing the guided tutorial
  • Quest Log β€” Daily, weekly, and special quests with progress tracking and XP rewards
  • Leaderboard β€” Top users ranked by XP with current user highlighting
  • XP Toast notifications β€” Real-time XP award popups after actions
  • Custom Quests β€” Superuser-assigned quests with configurable XP rewards, priority levels, deadlines, and status management (open/in progress/completed)
  • Skill-targeted quests β€” Quests can target a development skill; matching users earn double XP on completion

Feedback System

  • Quick feedback β€” Free-text feedback submissions with admin reply capability, rate limited, XP reward (15 XP) and "Heard!" achievement on first feedback
  • Survey rounds β€” Superuser creates multiple simultaneous survey rounds with optional XP rewards; users take surveys from the feedback page
  • Custom themed surveys β€” Rounds can have custom questions (single select, multi select, text) defined as JSON; renders dynamically in the survey form
  • Campaign quests β€” Survey rounds with deadlines create campaign quest panels (fixed bottom-right widget) with auto-completing tasks and inline survey dialog
  • Results dashboard β€” Expandable per-round results with bar charts and text response lists; custom question results aggregate automatically
  • Quest integration β€” Survey rounds auto-create CustomQuests for all active users; completing the survey auto-completes the quest and awards XP

WoW Mythic+ Integration

  • Character tracking β€” Add WoW characters by name/realm/region; stats fetched from Raider.IO API
  • Team roster β€” Shared view at /mythic-plus showing all team characters sorted by M+ rating
  • Character cards β€” Avatar, name-realm, class/spec/race, item level badge, M+ rating badge color-coded by WoW quality tiers (gray β†’ green β†’ blue β†’ purple β†’ orange)
  • Team composition β€” Build 5-man M+ teams with role slots (Tank, Healer, DPSΓ—3); dropdown character assignment filtered from roster; team stats (avg iLvl, avg M+ rating); create/delete teams
  • Live refresh β€” Refresh individual characters or all at once from Raider.IO
  • No login required β€” Uses the free Raider.IO API (no Battle.net OAuth needed)

Multi-Tenancy

  • Two isolated services β€” "Vuohiliitto" (community) and "Platform" (general) with completely separate content
  • Tenant-scoped data β€” Shoutbox, quests, achievements, leaderboard, surveys, issues, DMs, feedback, calendar, and all gamification data are isolated per tenant
  • Role-based access β€” superuser and vuohi roles see Vuohiliitto by default; admin, user, and pending roles see only Platform
  • Tenant switcher β€” Superuser/vuohi get a toggle button in the TopBar to switch between Vuohiliitto and Platform views
  • Per-tenant settings β€” MOTD, dashboard title, and platform settings are tenant-aware (composite PK)
  • Existing data preserved β€” All existing data tagged as "vuohiliitto"; Platform starts fresh

Demo Mode

  • Zero-credential demo β€” "Try Demo" button in TopBar for unauthenticated visitors; one-click login as superuser
  • Welcome overlay β€” First-time demo users see a modal explaining the platform with dismiss and localStorage persistence
  • Isolated mock data β€” Demo sessions are fully isolated via sessionId scoping within the Vuohiliitto tenant; real community data is never exposed
  • Comprehensive seed data β€” 6 users, 2 boards, 5 posts, 12 comments, 10 shoutbox messages, 2 DM conversations, 6 calendar events, 4 issues, 5 survey responses, 4 custom quests, gamification profiles with XP/achievements/quest progress
  • Auto-cleanup β€” Stale demo sessions (>24h) are automatically cascade-deleted
  • Tutorial integration β€” Guided tour auto-activates for demo users with fresh state

Guided Tour

  • Role-based tutorial β€” 13-step guided tour with 4 tiers (Getting Started, Community Explorer, Admin Basics, Team Leader)
  • Spotlight overlay β€” Highlights target elements with pulsing border and tooltip; clicking the tooltip scrolls the target into view
  • Progress checklist β€” Fixed bottom-right panel showing completion status with XP rewards per step
  • Gamification integration β€” Tutorial quests and achievements seeded, XP awarded on step completion, "Demo Explorer" achievement on full completion
  • Auto-sync β€” Detects actions completed before the tutorial existed (alias, survey, issues, shoutbox) and backfills progress

Admin

  • User management β€” Role assignment via approval dropdown (no separate approve button), hierarchy enforcement, permission overrides, survey completion status, collapsible permission editor inside user row
  • Developer team β€” Users indicate skills via survey and account page; superuser assigns team roles (Master πŸ‘‘, Coder πŸ’», Artist 🎨, Storyteller πŸ“–, Architect πŸ—οΈ, Scout πŸ”­, Advisor 🧠); only one Master allowed; tag icons shown in chat
  • Vuohiliitto Dashboard β€” XP stats, level distribution with hover tooltips, achievement/quest completion rates (superuser/vuohi only)
  • Quest Board β€” Global view of all custom quests with filters, creation form, and status management
  • Achievement & Quest CRUD β€” Split admin editor with separate AchievementEditor and QuestEditor components, shared IconPicker
  • Audit Log β€” Searchable log of all admin actions (role changes, permission edits, quest management, survey rounds, GDPR operations) with actor, target, old/new values, action filter dropdown, and DataTable with pagination

Security

  • Authentication β€” NextAuth v5 with Google OAuth, GitHub OAuth, zero-credential demo login; JWT includes role, alias, developerTag, and permissions
  • Role-based permissions β€” Superuser, vuohi, admin, user, and pending roles with 25 granular permission keys and per-user overrides
  • Role hierarchy enforcement β€” Users can only modify lower-ranked users and assign lower-ranked roles
  • Content ownership β€” Edit actions verify the user is the author; admin routes check role in middleware
  • Pending user approval β€” New users get zero permissions until approved by an admin
  • guardedAction β€” Server action wrapper enforcing auth, permissions, and rate limiting
  • requireUser / requireAdmin β€” Shared auth helpers for consistent authentication checks across all server actions
  • DM security β€” Messages only between real registered users; demo user blocked from DM at UI, query, and backend levels; participant verification on every send
  • Rate limiting β€” PostgreSQL-based atomic sliding window with configurable per-action limits (3/min for account deletion, 10/min for alias changes, 30/min default) on all user-facing mutation actions
  • Input validation β€” UUID validation on all ID parameters, string length limits on all text inputs, enum whitelisting, URL format validation, date validation
  • Security headers β€” CSP (with object-src, media-src), HSTS, X-Frame-Options, Referrer-Policy, Permissions-Policy

GDPR Compliance

  • Account page β€” Profile with editable alias, developer tag badge, development interest toggle, gamification stats
  • Account deletion β€” Users can delete their account from /account, scrubbing all PII, anonymizing authored content, and replacing sent DMs with [deleted]
  • Data export β€” Users can download all their data as JSON from /account (profile, posts, threads, events, shouts, issues, surveys, DM conversations)
  • Privacy policy β€” Full policy at /privacy covering data collection, cookies, retention, private messaging, user rights, breach notification, data processing legal bases, demo mode handling, and contact email
  • Soft-delete cleanup β€” Weekly cron job purges records deleted more than 30 days ago and audit logs older than 1 year

Code Quality

  • Component architecture β€” Large components split into focused subcomponents (Shoutbox β†’ 6 subcomponents, ManageGamification β†’ 3, FeedbackClient β†’ 3, DirectMessages reuses shared shoutbox components)
  • Shared components β€” XpProgressCard, SurveyRoundCard, SurveyResults, IconPicker, SystemMessages, WhisperMessages, UserPicker, DevTagIcon
  • Centralized constants β€” TIER_COLORS, STATUS_COLORS, PRIORITY_COLORS, STATUS_LABELS, PRIORITY_LABELS in styles.ts β€” single source of truth used by 5+ components
  • Standardized server actions β€” All actions use safe() + ActionError pattern with requireUser()/requireAdmin() auth helpers and createStringValidator() for input validation
  • Deduplicated logic β€” Shared applyXp() core, completeSurveyQuest() helper, guardedAction test mock helper, centralized DEMO_EMAIL, WHISPER_COLOR, CRITERIA_ACTIONS constants
  • Accessibility β€” Skip-to-content link, <main> landmark, aria-label on all icon buttons, WCAG AA color contrast, keyboard-accessible expand/collapse controls
  • Production audit β€” 121-finding audit completed (106 fixed), covering security, type safety, performance, accessibility, and testing

Shared Components

  • DataTable β€” Generic sortable, paginated, searchable table with column configuration
  • XpProgressCard β€” Reusable level/XP progress card with configurable right label and optional next-level display
  • EmptyState β€” Reusable empty state with icon, description, and action button
  • SnackbarProvider β€” Context-based notification system with useSnackbar() hook
  • ConfirmDeleteDialog β€” Reusable delete confirmation dialog
  • Centralized color system β€” 36 theme-aware color tokens in styles.ts, all components reference centralized tokens

UX Polish

  • Loading skeletons β€” Skeleton loading states for all routes
  • Keyboard shortcuts β€” g+h for home, ? for help dialog, /w alias msg for whispers with Tab autocomplete
  • Welcome page β€” Animated landing page with "Try Demo" and "Sign In" for unauthenticated visitors
  • Dev Log β€” Live GitHub commit feed on the landing page showing recent changes with relative timestamps and CI build status
  • Level-up celebration β€” Confetti and overlay animation on XP level milestones
  • Vuohi promotion celebration β€” Special animation when promoted to vuohi role
  • Goat favicon β€” Custom SVG goat head icon matching the community identity

Getting started

git clone --recurse-submodules <this-repo-url>
npm install --ignore-scripts
cp apps/web/.env.example apps/web/.env.local  # Configure env vars

# Database setup (required for all features)
# Option 1: Local PostgreSQL
# Option 2: Free Neon.tech instance (https://neon.tech)
# Set DATABASE_URL in apps/web/.env.local, then:
cd apps/web && npx prisma migrate dev && cd ../..

npx turbo run dev --filter=web

Visit http://localhost:3100

Development

npx turbo run dev --filter=web   # Start the web app
npx turbo run test --filter=web  # Run tests
npx turbo run lint --filter=web  # Lint
npx turbo run build --filter=web # Production build

Testing

Unit & Integration: Approximately 1,300 tests across 148 suites covering all server actions, query functions, gamification services, and UI components (Jest + React Testing Library). Pre-push hooks enforce 100% test pass rate. Coverage threshold enforced at 70% lines/functions, 60% branches.

npx turbo run test --filter=web           # All unit/integration tests
npx turbo run test:coverage --filter=web  # With coverage

Architecture

Two apps, two databases

Platform and HRM are separate applications with separate databases. They are both portfolio showpieces:

  • Platform β€” the production community app with chat, feedback, gamification, user management
  • HRM β€” a standalone HR management showpiece (git submodule at apps/hrm/)

New features are developed in the HRM repo first, then ported to Platform as needed using the same patterns but fresh code. HRM is never modified from within this repo.

Multi-tenancy model

The platform runs two isolated services from a single deployment:

  • Vuohiliitto β€” The community service for superuser and vuohi roles. All existing data lives here.
  • Platform β€” A separate service for admin, user, and pending roles. Starts with a clean slate.

Every content model has a tenant field (default "vuohiliitto"). All queries filter by tenant, ensuring complete data isolation. Superusers can switch between tenants via the TopBar toggle. Demo users are locked to the Vuohiliitto tenant.

User access model

  1. A new user signs in with Google or GitHub OAuth (or clicks "Try Demo" for a zero-credential demo with isolated mock data)
  2. They choose a public alias (callsign) on first login β€” shown instead of real name everywhere
  3. They complete a community survey (required before approval)
  4. They get a "pending" role with zero permissions β€” shown a "Waiting for approval" screen after completing the survey
  5. An admin approves them via /admin/users by selecting a role from the dropdown (approval and role assignment in one step)
  6. The first user to sign up automatically gets superuser role (bootstrap admin)

Deployment

The web app auto-deploys to Vercel on every push to master. Vercel project settings:

  • Root Directory: apps/web
  • Framework Preset: Next.js

Required environment variables:

  • DATABASE_URL β€” PostgreSQL connection string
  • AUTH_SECRET β€” NextAuth secret (openssl rand -base64 32)
  • AUTH_GOOGLE_ID / AUTH_GOOGLE_SECRET β€” Google OAuth credentials
  • AUTH_GITHUB_ID / AUTH_GITHUB_SECRET β€” GitHub OAuth credentials (optional)
  • NEXT_PUBLIC_APP_NAME β€” App name displayed in UI
  • NEXT_PUBLIC_BASE_URL β€” Production URL for OG meta tags (default: https://vuohiliitto.com)
  • CRON_SECRET β€” Secret for authenticating cron job requests (soft-delete cleanup)
  • NEXT_PUBLIC_DEMO_LOGIN β€” Set to "false" to hide the demo button (default: enabled)
  • GITHUB_TOKEN β€” GitHub personal access token for Dev Log commit feed (optional; increases rate limit from 60 to 5000 req/hour)

CI/CD

GitHub Actions runs lint, format check, tests, and build on every push to master and pull request.

Git hooks (via Husky):

  • Pre-commit β€” lint-staged runs Prettier on staged files
  • Pre-push β€” ESLint, Prettier check, and full test suite must pass before code reaches the repository

About

A modular platform for building and managing community-driven applications, including boards, events, and shared data.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages