Welcome to the HOA Community Hub, a modern, full-stack web application designed to be the central digital point of contact for a Homeowners' Association and its residents. This platform streamlines communication, simplifies document access, manages community events, and provides essential administrative tools.
- Production: https://sandersoncreekhoa.com/
- API base: https://sandersoncreekhoa.com/api/
- Health: https://sandersoncreekhoa.com/api/health
Notes
- Nginx enforces HTTPS and redirects
www.sandersoncreekhoa.com→sandersoncreekhoa.com. - Turnstile is enabled on Registration; SendGrid handles outbound email.
- Vision & Purpose
- Core Features
- Technology Stack
- Project Structure
- Getting Started
- Running the Application
- Running Tests
- API Documentation
- CI/CD Pipeline
- Deployment (Production)
- Contributing & Security
The goal of the HOA Community Hub is to replace fragmented communication channels like email chains and paper notices with a single, secure, and user-friendly platform. It empowers community administrators with the tools they need to manage the HOA efficiently while providing residents with easy access to information and a forum for discussion.
User Personas:
- Administrator: Manages users, content, site configuration, and feature rollouts via flags.
- Resident (Member): Accesses information, participates in discussions, votes in polls, and searches vendor directory.
- Guest: Views public-facing information about the HOA and public vendor categories.
Recent Enhancements (Iteration 5):
- Finalized CI/CD automation with health gate validation before registry pushes
- Enhanced health monitoring endpoints (
/healthz,/metrics) with diagnostics payloads - Completed cross-module QA and accessibility suite verification (WCAG 2.1 AA compliance)
- Comprehensive documentation and knowledge transfer artifacts
- Release communications templates and feature flag operational runbooks
| Feature | Administrator (admin) |
Resident (member) |
Guest (Unauthenticated) |
|---|---|---|---|
| Authentication | ✅ Login/Logout | ✅ Login/Logout, Register, Email Verify, Password Reset | ❌ |
| User Management | ✅ View, Approve/Reject, Change Role, Delete Users | ✅ Manage Own Profile | ❌ |
| Announcements / HOA Messages | ✅ Create, Edit, Delete, Optional Email Notify to All Members | ✅ View | ❌ |
| Events | ✅ Create, Edit, Delete | ✅ View | ❌ |
| Documents | ✅ Upload, Manage, Set Visibility | ✅ View & Download Approved Docs | ✅ View & Download Public Docs |
| Discussions | ✅ Delete Threads/Replies | ✅ Create/View Threads, Post Replies | ❌ |
| Site Configuration | ✅ Edit Site Name/Description | ❌ | ❌ |
| Audit Logs | ✅ View all administrative actions | ❌ | ❌ |
| ✅ SendGrid provider, approval/rejection, announcements, password reset, email verification | — | — | |
| CAPTCHA | — | ✅ Registration protected by Turnstile | — |
| Accessibility | ✅ Configure default high-vis mode | ✅ Toggle high-visibility theme, keyboard navigation | ✅ High-vis mode support |
| Feature Flags | ✅ Runtime configuration, staged rollouts | ❌ | ❌ |
- Backend:
- Framework: Node.js with Express.js
- Database: SQLite3 (for simplicity and portability)
- ORM: Sequelize
- Authentication: JSON Web Tokens (JWT) + Email verification
- Testing: Jest & Supertest
- Email: SendGrid (adapter-based service)
- CAPTCHA: Cloudflare Turnstile (registration)
- Frontend:
- Framework: React.js with TypeScript
- UI Library: Material-UI (MUI)
- Routing: React Router
- State Management: React Context API
- Form Handling: Formik & Yup
- API Client: Axios
The project is a monorepo containing distinct backend and frontend applications.
- Node.js (v18.x or later recommended)
- npm (v10.x or later recommended)
-
Navigate to the backend directory:
cd backend -
Install dependencies:
npm install
-
Set up environment variables: Create a
.envfile in thebackend/directory by copying the example.# You can manually create a .env file and add the following: # A strong, secret key for signing JWTs JWT_SECRET=your_super_secret_key_here_123! JWT_EXPIRES_IN=8h # Default admin credentials for the initial database seed ADMIN_EMAIL=admin@example.com ADMIN_PASSWORD=AdminPassword123! # Email provider (SendGrid) EMAIL_PROVIDER=sendgrid EMAIL_FROM=no-reply@your-domain.com EMAIL_FROM_NAME=HOA Community Hub SENDGRID_API_KEY=your_sendgrid_api_key # Frontend base (for email links) FRONTEND_BASE_URL=http://localhost:3000 # Password reset cooldown (minutes) PASSWORD_RESET_COOLDOWN_MINUTES=60 # CAPTCHA (Cloudflare Turnstile) TURNSTILE_SECRET_KEY=your_turnstile_secret
-
Run database migrations and seeders: This command will create the database schema and populate it with an initial admin user and default site configuration.
npm run db:migrate npm run db:seed
-
Navigate to the frontend directory:
# from the project root cd frontend
-
Install dependencies:
npm install
-
Create
.env(optional but recommended):VITE_API_BASE_URL=http://localhost:3001/api # Turnstile site key (if protecting registration locally) VITE_TURNSTILE_SITE_KEY=your_turnstile_site_key VITE_APP_VERSION=1.0.0 # App name for document.title VITE_APP_NAME=Sanderson Creek HOA
You will need two separate terminal windows to run the backend and frontend servers concurrently.
-
Start the Backend Server:
# In a terminal, from the backend/ directory npm startThe API will be running on
http://localhost:3001. -
Start the Frontend Development Server:
# In a second terminal, from the frontend/ directory npm run devThe React application will open in your browser, usually at
http://localhost:3000. (CI uses anpm run dev:screenshotsvariant that binds to0.0.0.0:3000when generating automated screenshots.)
Notes
- Registration requires email verification. Users must click the link sent via email. Admin approval is also required to access member features.
- “Forgot password” is limited to once per hour per account (configurable via
PASSWORD_RESET_COOLDOWN_MINUTES). - Admins can optionally email an announcement to all approved, verified members by checking the “Email this announcement…” box in the admin UI.
The project includes comprehensive test coverage for both backend and frontend components, enforced by CI/CD pipelines.
-
Integration tests with coverage:
# From the backend/ directory npm run test:integration -- --coverageThis includes tests for password reset rate limiting, announcement email notifications (mocked), and vote hashchain integrity.
-
Specific test file (debugging):
# From the backend/ directory npm run test:debugging -- test/debugging/users.test.js -
Hashchain integrity tests:
npx jest --testPathPattern=poll.test.js --testNamePattern="(integrity|hashchain|tamper)"
-
Unit tests with coverage:
# From the frontend/ directory npm run test:coverage -
Accessibility tests (WCAG 2.1 AA compliance):
npm run test -- src/tests/*.a11y.test.tsx
-
Interactive test UI:
npm run test:ui
-
E2E screenshot generation for user guides:
# From the repository root npm run --prefix frontend generate-screenshotsThat command sets
GENERATE_SCREENSHOTS=trueso Playwright captures every page, and our CI workflow (.github/workflows/generate-screenshots.yml) mirrors the same steps, starts both dev servers (backend on 5000, frontend on 3000), and publishes the screenshots as workflow artifacts.
For repeatable deployments to a remote server via SSH (backups, code sync, Docker image build, minimal downtime restarts, and verification), use the helper scripts in deploy/:
deploy/deploy.local.sh– run locally; syncs code to the remote and invokes the remote routine.deploy/remote.deploy.sh– runs on the server; creates backups, builds, restarts, runs migrations (optional), and verifies.deploy/config.example.env– copy todeploy/config.envand setDEPLOY_HOST,DEPLOY_USER,SSH_KEY,REMOTE_DIR,DOMAIN,BACKEND_IMAGE,FRONTEND_IMAGE, and flags likeRUN_MIGRATIONS.deploy/DEPLOY.md– full details and quick start.
Environment (production highlights)
- Backend:
JWT_SECRET,JWT_EXPIRES_IN,EMAIL_PROVIDER=sendgrid,EMAIL_FROM,EMAIL_FROM_NAME,SENDGRID_API_KEY,FRONTEND_BASE_URL,PASSWORD_RESET_COOLDOWN_MINUTES,TURNSTILE_SECRET_KEY. - Frontend build:
VITE_API_BASE_URL,VITE_APP_NAME,VITE_TURNSTILE_SITE_KEY,VITE_APP_VERSION(the release workflow injects the git tag).
The deployment pipeline implements a health gate pattern where Docker images are validated before being pushed to the container registry:
-
Build Phase:
- Publish a GitHub release (or dispatch the workflow manually) to trigger automated build
- Workflow builds backend and frontend images with
docker buildx - Images tagged as
ghcr.io/<owner>/hoa-backend:<tag>andghcr.io/<owner>/hoa-frontend:<tag>
-
Health Gate Validation:
- Images loaded locally on GitHub Actions runner (not pushed yet)
- Temporary containers started with test database
- Database migrations executed and validated
- Health endpoints (
/api/health,/api/metrics) verified with retries - Container logs captured as workflow artifacts (
health-gate-dry-run-logs)
-
Registry Push (Only After Health Gate Pass):
- Images pushed to GHCR using built-in
GITHUB_TOKEN - Failed health checks prevent bad images from reaching production
- Artifacts retained for 30 days for troubleshooting
- Images pushed to GHCR using built-in
-
Deployment to Linode:
- SSH orchestration pulls verified images from GHCR
- Automated backups (database, uploads, code) before deployment
- Zero-downtime restarts via Docker Compose
- Post-deploy verification of health endpoints
Required repository secrets: DEPLOY_HOST, DEPLOY_USER, DEPLOY_DIR, DEPLOY_DOMAIN, DEPLOY_SSH_KEY, VITE_TURNSTILE_SITE_KEY
Detailed Documentation:
- Deployment Runbook – Complete deployment procedures, health gate details, rollback steps
- Release Checklist – Pre-deploy, deploy, and post-deploy verification checklists
- Feature Flags Runbook – Runtime configuration and staged rollout procedures
- Release Communications – Stakeholder communication templates
- Example site config lives on the server; ensure HTTPS, redirect
www→ apex, and a strict CSP that allowshttps://challenges.cloudflare.comfor Turnstile. - The app's Docker Compose publishes backend on
127.0.0.1:3001and frontend on127.0.0.1:3000; Nginx proxieshttps://<domain>/api/to backend and/to frontend.
The HOA Message feature allows administrators to send important communications to all HOA members via email. This is implemented through the announcements system with email notification capabilities.
When creating an announcement, administrators can enable the "Notify Members" option to send the announcement via email to all approved, verified, and active HOA members.
API Endpoint: POST /api/announcements
Request Body:
{
"title": "Important HOA Update",
"content": "<p>This is an important message for all members.</p>",
"notify": true,
"expiresAt": "2025-12-31T23:59:59Z"
}Notification Behavior:
- Emails are sent to all users with:
status: 'approved'email_verified: trueis_system_user: false
- Uses the
announcement.htmlemail template - Emails are sent sequentially with error handling
- Failed emails don't prevent announcement creation
- Admin logs in to the system
- Navigate to Announcements section
- Click "Create Announcement"
- Fill in announcement details:
- Title: Subject of the message
- Content: HTML-formatted message body
- Expires At: Optional expiration date
- Notify Members: Check this box to send emails
- Submit the announcement
Members will receive an email with the announcement content and a link to view it on the website.
Backend: backend/src/services/announcement.service.js (lines 54-85)
The email sending logic:
- Queries all eligible recipients from the database
- Renders the announcement email template
- Sends individual emails via SendGrid
- Continues on email failures (graceful degradation)
Email Template: backend/src/emails/templates/announcement.html
Mass email sending is not currently rate-limited, but individual announcement creation follows standard API rate limits (100 requests per 15 minutes per IP).
Potential improvements for a dedicated HOA Message feature:
- Recipient targeting (specific user groups, roles)
- Message scheduling
- Delivery tracking and read receipts
- Template management
- Message history and archive
- Background job processing for large recipient lists
The HOA Management System includes comprehensive production-ready features for monitoring, security, and operations.
- Rate Limiting:
- Global API rate limiting (100 req/15min)
- Login attempts: 5 per IP+email per 15 minutes
- Registration: 3 per IP per hour
- Password reset: 3 per IP+email per hour
- CORS Protection: Configurable allowed origins
- Input Validation: Joi validation on all endpoints
- SQL Injection Prevention: Parameterized queries via Sequelize
- XSS Protection: DOMPurify content sanitization
- JWT Authentication: Secure token-based auth
- CAPTCHA: Cloudflare Turnstile on registration
- Audit Logging: All admin actions logged
- HTTP request rates and durations
- Error rates by endpoint
- Authentication attempts
- Email sending metrics
- System resources (CPU, memory)
- Database query performance
Endpoint: GET /api/metrics
- Real-time performance visualization
- Response time percentiles (p50, p90, p95, p99)
- Error tracking
- Business metrics
Access: http://your-server:3002 (default: admin/admin)
- Winston logger with JSON format
- Daily log rotation
- Separate log levels (error, warn, info, http, debug)
- Log files in
backend/logs/
Start Monitoring Stack:
docker-compose -f docker-compose.yml -f docker-compose.monitoring.yml up -d- Sentry integration for automatic error reporting
- Stack traces and user context
- Performance monitoring
- Configure via
SENTRY_DSNenvironment variable
Documentation: See docs/MONITORING.md
Comprehensive backup script (scripts/backup.sh) that backs up:
- Database (SQLite, compressed)
- Uploaded documents
- Application logs
- Git commit information
- Configuration (secrets redacted)
Setup Automated Backups:
# Test the backup script
./scripts/backup.sh
# Add to crontab for daily backups at 2 AM
crontab -e
# Add: 0 2 * * * /path/to/hoa-management-system/scripts/backup.shConfiguration:
BACKUP_DIR: Backup location (default:/root/hoa-backups)BACKUP_RETENTION_DAYS: Keep backups for N days (default: 30)BACKUP_NOTIFICATION_EMAIL: Optional email notifications
Interactive restore script (scripts/restore.sh):
# Interactive mode
./scripts/restore.sh
# Restore specific backup
./scripts/restore.sh 20250111_020000Documentation: See docs/BACKUP_AND_RESTORE.md
Comprehensive runbook for handling common incidents:
- Application downtime
- Database issues
- Performance degradation
- Security incidents
- Email service failures
- Disk space issues
Documentation: See docs/INCIDENT_RESPONSE.md
cd frontend
npm test # Run tests
npm run test:coverage # Generate coverage report
npm run test:ui # Open Vitest UIFramework: Vitest + React Testing Library
cd frontend
npm run test:e2e # Run E2E tests
npm run test:e2e:ui # Open Playwright UI
npm run test:e2e:debug # Debug modeFramework: Playwright
cd backend
npm run test:integration
npm run test:debuggingFramework: Jest + Supertest
# Security
JWT_SECRET=your-secret-here
ALLOWED_ORIGINS=https://yourdomain.com
# Email
EMAIL_PROVIDER=sendgrid
SENDGRID_API_KEY=your-api-key
EMAIL_FROM=no-reply@yourdomain.com
EMAIL_FROM_NAME=Your HOA Name
FRONTEND_BASE_URL=https://yourdomain.com
# Turnstile CAPTCHA
TURNSTILE_SECRET_KEY=your-secret-key
VITE_TURNSTILE_SITE_KEY=your-site-key
VITE_APP_VERSION=1.0.0# Monitoring
SENTRY_DSN=https://your-sentry-dsn
SENTRY_TRACES_SAMPLE_RATE=0.1
APP_VERSION=1.0.0
# Logging
LOG_LEVEL=info
ENABLE_FILE_LOGGING=true
LOGS_DIR=./logs
# Backup
BACKUP_DIR=/root/hoa-backups
BACKUP_RETENTION_DAYS=30
BACKUP_NOTIFICATION_EMAIL=admin@yourdomain.com
# Grafana
GRAFANA_ADMIN_USER=admin
GRAFANA_ADMIN_PASSWORD=your-secure-passwordSee .env.example for complete list.
The project uses GitHub Actions for continuous integration and deployment. All pull requests must pass comprehensive quality gates before merging.
The CI workflow (.github/workflows/ci.yml) runs 10 parallel jobs:
Backend Quality Checks:
- Lint: ESLint with strict error enforcement
- Tests: Jest integration tests with 80% coverage threshold
- Hashchain Integrity: Vote tampering detection and integrity validation
- Security Audit: npm audit with critical vulnerability blocking
Frontend Quality Checks:
- Lint: ESLint + TypeScript type checking
- Tests: Vitest unit tests with 75% coverage threshold
- Accessibility: WCAG 2.1 AA compliance via axe-core
- Security Audit: npm audit with critical vulnerability blocking
Security & Hygiene:
- Hygiene: Prevents
.envfile commits and scans for hardcoded secrets - Aggregate: Final summary job ensuring all checks passed
Status Badge: The CI badge at the top of this README shows current pipeline status.
Artifacts: Failed runs produce downloadable artifacts (30-day retention):
- Coverage reports (HTML + JSON)
- Lint logs (JSON format)
- Security audit reports
- Accessibility violation reports
- Test results
Troubleshooting: For detailed troubleshooting guides, see docs/runbooks/ci-pipeline.md.
Replicate CI checks locally before pushing:
# Backend
cd backend
npm ci
npx eslint .
NODE_ENV=test npx sequelize-cli db:migrate
npm run test:integration -- --coverage
npm audit --audit-level=critical
# Frontend
cd frontend
npm ci
npm run lint
npm run test:coverage -- --run
npm run test -- --run src/tests/*.a11y.test.tsx
npm audit --audit-level=critical- Backend: 80% lines, statements, functions, branches
- Frontend: 75% lines, statements, functions, branches
Coverage below thresholds blocks merge. Download coverage artifacts to identify untested code paths.
- Critical vulnerabilities block CI immediately
- Dependabot alerts must be triaged within 48 hours
- No
.envfiles may be committed to the repository - Secret scanning runs on every push
- See CONTRIBUTING for guidelines.
- Review our SECURITY policy for responsible disclosure.
- License: MIT.
See docs/INFRASTRUCTURE.md for:
- Cloud/OS details, domains, and TLS
- Nginx proxying (ports, logs, CSP)
- Docker/Compose service layout and persistence paths
- Health endpoints and backup locations
Comprehensive operational documentation is maintained to support volunteer HOA board members and system operators. All documentation follows anchor-based cross-referencing for traceability to architectural decisions and implementation plans.
Core Operational Procedures:
- Deployment Runbook – Health gate validation, rollback procedures, troubleshooting
- Release Checklist – Pre-release, deployment, and post-deployment verification steps
- Feature Flags Runbook – Runtime configuration, staged rollouts, emergency kill switches
- Release Communications – Stakeholder communication templates and timelines
- CI Pipeline Runbook – Continuous integration troubleshooting and local replication
- Health Monitor Runbook – Health endpoint diagnostics and monitoring setup
Module-Specific Runbooks:
- Vendor Moderation – Vendor approval workflows and moderation queue management
- Notification Log – Email audit logging and retention policies
- Pilot Instructions – Feature pilot program procedures
Accessibility & UI/UX:
- Accessibility Suite Design – WCAG 2.1 AA compliance, high-visibility mode, component specifications
- Accessibility Theme Tokens – Complete design token specifications for standard and high-vis modes
For New System Operators and Board Members:
- Knowledge Transfer Checklist – System overview, operational ownership handoff, routine procedures
- Architecture Documentation – Canonical system architecture and operational rationale
- Plan Manifest – Traceability from requirements to implementation
Key Resources:
- All runbooks reference architecture document anchors (e.g.,
04_Operational_Architecture.md#3-12) - Video walkthroughs for UI operations (generated screenshots in CI artifacts)
- Regular lunch-and-learn sessions for board transitions (documented in meeting notes)
Documentation Maintenance:
- Living documentation reviewed quarterly or after major releases
- Every release requires documentation diff review before merging
- Feedback loops allow residents to request clarifications (2-week update SLA)
For Technical Handoffs:
- Comprehensive inline code comments for complex business logic
- Automated test suites verify expected behaviors (>80% backend, >75% frontend coverage)
- Deployment logs maintain historical record of all production changes