Skip to content

rondagdag/audience-survey

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

52 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Audience Survey

"Snap your survey β†’ instant insights."

A Next.js application for collecting and analyzing audience feedback during speaking sessions using Azure AI Content Understanding. Attendees upload photos of their completed survey forms, and the system automatically extracts and aggregates the data for live presentation.

🌟 Features

  • Mobile-First Upload: Camera-optimized interface for quick survey photo capture
  • Azure AI Content Understanding: Automatic extraction of checkboxes, numbers, and handwritten text via Azure AI Services
  • Azure AI Foundry Integration: Connected to AI Foundry Project for advanced AI workflows
  • Live Dashboard: Real-time feedback aggregation for speakers
  • Session Management: Create and manage multiple feedback sessions
  • Rich Analytics:
    • 5-point Likert scale visualization
    • Net Promoter Score (NPS) distribution
    • Word cloud from open feedback
    • Audience breakdown by type and experience level
  • CSV Export: Download complete session data
  • Fun UX: Confetti animation on successful submission

πŸ“‹ Prerequisites

  • Node.js 20+ and npm
  • Azure Subscription with permissions to create resources
  • Azure CLI - Install here
  • (Optional) Terraform - For infrastructure automation - Install here
  • (Optional) Docker - For containerized deployment

πŸ“‚ Project Structure

audience-survey/
β”œβ”€β”€ app/                  # Next.js 16 application
β”‚   β”œβ”€β”€ src/              # Source code
β”‚   β”‚   β”œβ”€β”€ app/          # App Router pages and API routes
β”‚   β”‚   β”œβ”€β”€ components/   # React components
β”‚   β”‚   └── lib/          # Utilities and business logic
β”‚   β”œβ”€β”€ tests/            # Playwright E2E tests
β”‚   β”œβ”€β”€ public/           # Static assets
β”‚   β”œβ”€β”€ Dockerfile        # Container configuration
β”‚   └── ...               # Config files (package.json, tsconfig.json, etc.)
β”œβ”€β”€ iac/                  # Infrastructure as Code (Terraform)
β”‚   β”œβ”€β”€ main.tf           # Main Terraform configuration
β”‚   β”œβ”€β”€ variables.tf      # Variable definitions
β”‚   β”œβ”€β”€ outputs.tf        # Output values
β”‚   └── README.md         # Detailed IaC documentation
β”œβ”€β”€ setup/                # Setup scripts
β”‚   └── create-analyzer.sh # Custom analyzer creation script
β”œβ”€β”€ docs/                 # Documentation
β”‚   β”œβ”€β”€ QUICKSTART.md     # Quick setup guide
β”‚   β”œβ”€β”€ AZURE_INTEGRATION.md  # Azure setup details
β”‚   β”œβ”€β”€ ANALYZER_SCHEMA.md    # Custom analyzer schema
β”‚   β”œβ”€β”€ BLOB_STORAGE.md   # Storage implementation details
β”‚   β”œβ”€β”€ TESTING.md        # Testing guide
β”‚   └── ...               # Additional documentation
└── README.md             # This file

οΏ½πŸš€ Quick Start

1. Install Dependencies

cd app
npm install

2. Configure Environment Variables

Copy the example environment file:

cp .example.env.local .env.local

Edit .env.local and add your credentials:

# Azure AI Content Understanding
AZURE_CONTENT_ENDPOINT=https://your-resource-name.cognitiveservices.azure.com//
AZURE_CONTENT_KEY=your-api-key-here
AZURE_ANALYZER_ID=audience-survey

# Admin Secret (use a strong random string)
ADMIN_SECRET=your-secure-admin-secret-here

⚠️ Note: You must restart the development server after changing .env.local for the changes to take effect.

Getting Azure Credentials:

Option 1: Deploy with Terraform (Recommended)

  1. Follow the Infrastructure as Code guide
  2. Terraform creates all required resources including:
    • Azure AI Services (for Content Understanding)
    • Azure AI Foundry Hub and Project
    • Storage, Key Vault, and App Service
  3. Retrieve credentials from Terraform outputs

Option 2: Manual Setup

  1. Go to Azure Portal
  2. Create an Azure AI Services resource (not just "Content Understanding")
    • This provides Content Understanding + other AI capabilities
    • Note the endpoint format: https://<name>.services.ai.azure.com/
  3. (Optional but recommended) Create Azure AI Foundry Hub and Project
    • Navigate to Azure AI Studio
    • Create a new Hub and Project
    • Connect your AI Services resource to the project
  4. Navigate to AI Services β†’ "Keys and Endpoint"
  5. Copy the endpoint URL and one of the keys
  6. Create a custom analyzer in Azure AI Studio

For detailed setup instructions, see QUICKSTART.md.

3. Run Development Server

cd app
npm run dev

Open http://localhost:3000 in your browser.

πŸ“± Usage

For Speakers/Organizers:

  1. Navigate to /admin
  2. Enter your admin secret
  3. Create a new session before your presentation
  4. Share the main URL with attendees
  5. Monitor live results during/after the session
  6. Export data as CSV when complete
  7. Close the session when finished

For Attendees:

  1. Navigate to the main URL (provided by speaker)
  2. Wait for the session to be active
  3. Take a clear photo of your completed survey form
  4. Preview and submit
  5. See confirmation with confetti!

πŸ—οΈ Architecture

Technology Stack

  • Frontend: Next.js 16 (App Router with Turbopack), React 19, TypeScript
  • Styling: Tailwind CSS, mobile-first responsive design
  • State Management: Zustand
  • Charts: Recharts
  • AI Processing: Azure AI Services (Content Understanding API)
  • AI Platform: Azure AI Foundry (Hub + Project for advanced AI workflows)
  • Deployment: Vercel / Azure App Service / Azure Static Web Apps

Key Components

  • SessionGuard - Blocks access when no active session
  • SurveyUploader - Camera/file input with preview
  • SurveyMapper - Maps Azure output to survey model
  • FeedbackChart - Visualizes 1-5 Likert scales
  • NpsStrip - Shows 0-10 recommendation distribution
  • WordCloud - Renders top feedback words

API Routes

  • POST /api/sessions - Create new session (requires admin secret)
  • PATCH /api/sessions - Close active session (requires admin secret)
  • GET /api/sessions - List all sessions
  • POST /api/analyze - Upload and analyze survey image
  • GET /api/summary?sessionId=xxx - Get session aggregated results
  • GET /api/export?sessionId=xxx&adminSecret=xxx - Export CSV

🎨 Survey Format

The application expects surveys with these fields:

Structured Data:

  • Attendee Type: Student / Developer / Manager / Researcher / Hobbyist / Other
  • AI Experience Level: Beginner / Intermediate / Advanced / Expert
  • Azure AI Usage: Yes / No / Planning to

Presentation Feedback (1-5 Likert):

  • How engaging was the presentation?
  • How clear was the content?
  • Were the demos useful?
  • Was it at the right level?
  • Did you learn something new?

Recommendation Score:

  • 0-10 scale: How likely are you to recommend this session?

Open Feedback:

  • What was the best part?
  • What could be improved?
  • What topics would you like to see in the future?

πŸ”’ Security

  • Admin routes protected by shared secret
  • File type and size validation (10MB max)
  • Rate limiting recommended for production
  • HTTPS required for production deployment
  • Sensitive data stored in environment variables

πŸ“¦ Cloud Deployment

Option 1: Azure Container Apps with GitHub Actions (Recommended)

The project includes a complete CI/CD pipeline for Azure Container Apps:

Setup:

  1. Provision infrastructure with Terraform:

    cd iac
    terraform init
    terraform apply
  2. Configure GitHub repository secrets:

    • AZURE_CLIENT_ID - Service principal client ID
    • AZURE_TENANT_ID - Azure tenant ID
    • AZURE_SUBSCRIPTION_ID - Your subscription ID
    • ADMIN_SECRET - Admin secret for the application
  3. Push to main branch or manually trigger workflow:

    git push origin main

The GitHub Actions workflow (.github/workflows/deploy.yml) will:

  • Provision infrastructure (if not exists)
  • Build Docker image with commit SHA tag
  • Push to Azure Container Registry
  • Deploy to Azure Container Apps
  • Run Playwright E2E tests against deployed URL

Access deployed app:

cd iac
terraform output container_app_url

See iac/README.md for detailed infrastructure documentation.

Option 2: Azure Container Apps (Manual)

Build and push Docker image:

cd app

# Login to Azure
az login

# Get ACR name from Terraform outputs
cd ../iac
ACR=$(terraform output -raw acr_login_server)
cd ../app

# Build and push
PROJECT=audsurvey
TAG=$(git rev-parse --short HEAD)
docker build -t "$ACR/$PROJECT/web:$TAG" .

az acr login --name ${ACR%%.*}
docker push "$ACR/$PROJECT/web:$TAG"

Update Container App:

cd ../iac
terraform apply -var="container_image_tag=$TAG" -auto-approve

Option 3: Vercel

Quick deploy:

cd app
npm install -g vercel
vercel

Configure environment variables in Vercel dashboard:

  • AZURE_CONTENT_ENDPOINT - Your AI Services endpoint
  • AZURE_CONTENT_KEY - AI Services API key
  • AZURE_ANALYZER_ID - Custom analyzer ID (audience-survey)
  • AZURE_STORAGE_CONNECTION_STRING - Storage connection string
  • AZURE_STORAGE_CONTAINER_NAME - Container name (uploads)
  • ADMIN_SECRET - Admin authentication secret

Or use Vercel CLI with env vars:

vercel --env AZURE_CONTENT_ENDPOINT=https://... \
       --env AZURE_CONTENT_KEY=your-key \
       --env AZURE_ANALYZER_ID=audience-survey \
       --env AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https... \
       --env ADMIN_SECRET=your-secret

Option 4: Azure Static Web Apps

Deploy with SWA CLI:

cd app

# Install SWA CLI
npm install -g @azure/static-web-apps-cli

# Build the application
npm run build

# Deploy (follow prompts for authentication)
swa deploy

Configure environment variables in Azure Portal:

  • Navigate to Static Web App β†’ Configuration
  • Add the same environment variables as Vercel

Note: The staticwebapp.config.json is pre-configured for Next.js routing.

Environment Variables Required for All Deployments

All cloud deployments require these environment variables:

Variable Description Example
AZURE_CONTENT_ENDPOINT AI Services endpoint https://name.services.ai.azure.com/
AZURE_CONTENT_KEY AI Services API key abc123...
AZURE_ANALYZER_ID Custom analyzer ID audience-survey
AZURE_STORAGE_CONNECTION_STRING Storage connection (local/dev) DefaultEndpointsProtocol=https;...
AZURE_STORAGE_ACCOUNT_NAME Storage account (managed identity) storageaccountname
AZURE_STORAGE_CONTAINER_NAME Blob container name uploads
ADMIN_SECRET Admin authentication secret Strong random string

Note: Use AZURE_STORAGE_CONNECTION_STRING for Vercel/SWA. Container Apps uses managed identity with AZURE_STORAGE_ACCOUNT_NAME.

Post-Deployment Verification

  1. Test the deployed application:

    # Visit your deployment URL
    curl https://your-app-url.azurecontainerapps.io
  2. Create a test session:

    • Navigate to /admin
    • Login with your ADMIN_SECRET
    • Create a test session
  3. Upload a test survey:

    • Visit the main page
    • Upload a sample survey image
    • Verify Azure AI Content Understanding extracts data correctly
  4. Check logs:

    # Container Apps
    az containerapp logs show \
      --resource-group <rg-name> \
      --name <app-name> \
      --follow
    
    # Vercel
    vercel logs <deployment-url>

Cleanup Resources

To delete all Azure resources and stop charges:

cd iac
terraform destroy

⚠️ Warning: This permanently deletes all resources including uploaded images and secrets.

πŸ› οΈ Development Guide

Application Architecture

The Next.js application in app/ contains:

app/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ app/              # App Router pages and API routes
β”‚   β”‚   β”œβ”€β”€ api/          # API routes
β”‚   β”‚   β”‚   β”œβ”€β”€ analyze/  # Image analysis endpoint
β”‚   β”‚   β”‚   β”œβ”€β”€ sessions/ # Session management
β”‚   β”‚   β”‚   β”œβ”€β”€ summary/  # Aggregated results
β”‚   β”‚   β”‚   └── export/   # CSV export
β”‚   β”‚   β”œβ”€β”€ admin/        # Speaker dashboard
β”‚   β”‚   └── page.tsx      # Main audience view
β”‚   β”œβ”€β”€ components/       # React components
β”‚   └── lib/              # Utilities and business logic
β”‚       β”œβ”€β”€ types.ts      # TypeScript definitions
β”‚       β”œβ”€β”€ store.ts      # Zustand state management
β”‚       β”œβ”€β”€ data-store.ts # In-memory data storage
β”‚       β”œβ”€β”€ blob-storage.ts # Azure Blob Storage integration
β”‚       β”œβ”€β”€ azure-content-understanding.ts  # Azure AI integration
β”‚       └── survey-mapper.ts  # AI result mapping
β”œβ”€β”€ tests/                # Playwright E2E tests
β”œβ”€β”€ public/               # Static assets
β”œβ”€β”€ Dockerfile            # Container configuration
└── ...                   # Config files

Adding Features

The codebase is structured for easy extension:

  1. Add new survey fields:

    • Update src/lib/types.ts with new field definitions
    • Extend src/lib/survey-mapper.ts to extract from Azure response
    • Update src/lib/data-store.ts aggregation logic
    • Create visualization components in src/components/
  2. Add new API endpoints:

    • Create route in src/app/api/
    • Follow existing patterns for admin authentication
    • Use export const dynamic = 'force-dynamic' for real-time data
  3. Add new visualizations:

    • Create component in src/components/
    • Use Recharts for charts, Tailwind for styling
    • Import directly (no barrel exports): import X from '@/components/X'

Data Storage

Current Implementation:

  • Session data: In-memory Maps in DataStore singleton (resets on restart)
  • Image files: Azure Blob Storage with unique blob names
  • Image references: Blob URLs stored in SurveyResult.imagePath

For Production:

  • Replace app/src/lib/data-store.ts with database (MongoDB, PostgreSQL, Cosmos DB)
  • Keep same interface for minimal API route changes
  • Images already in cloud storage (Azure Blob Storage)

See docs/BLOB_STORAGE.md for storage implementation details.

🀝 Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes with clear commit messages
  4. Test thoroughly
  5. Submit a pull request

πŸ“„ License

MIT License - feel free to use this for your own presentations and events!

πŸ™ Acknowledgments

  • Built with Next.js and React
  • Powered by Azure AI Content Understanding
  • UI components styled with Tailwind CSS
  • Charts by Recharts
  • Confetti by canvas-confetti

οΏ½ Documentation

οΏ½πŸ“ž Support

For issues and questions:

πŸ”§ Troubleshooting

Local Development Issues

Port already in use (Error: listen EADDRINUSE :::3000)

# Find and kill process on port 3000
lsof -ti:3000 | xargs kill -9

# Or use a different port
npm run dev -- -p 3001

Environment variables not updating

  • Restart development server after changing .env.local
  • Verify file is named .env.local not .env.local.txt
  • Check file is in app/ directory, not project root

"Module not found" errors

# Clear Next.js cache and reinstall
rm -rf .next node_modules
npm install
npm run dev

Azure Configuration Issues

"Couldn't read survey" / Image analysis errors:

  • Image quality: Ensure good lighting, keep survey flat and in focus
  • Custom analyzer: Verify analyzer ID is audience-survey in .env.local
  • Analyzer not deployed: Check Azure AI Studio for analyzer status
  • Field mismatch: Ensure analyzer schema matches docs/ANALYZER_SCHEMA.md

Azure API authentication errors (401 Unauthorized):

  • Verify endpoint URL format: https://<name>.services.ai.azure.com/
    • Must be AI Services endpoint, not legacy cognitiveservices.azure.com
  • Check API key is correct (from AI Services β†’ Keys and Endpoint)
  • Ensure key hasn't been regenerated in Azure Portal
  • Try using Key 2 if Key 1 fails

Region/availability errors (403 Forbidden):

  • Ensure resource is in supported region: westus, swedencentral, or australiaeast
  • Verify subscription has available quota for AI Services
  • Check Content Understanding is enabled in your region

Storage errors ("Failed to upload image to storage"):

  • Verify AZURE_STORAGE_CONNECTION_STRING is correct
  • Check storage account name matches in connection string
  • Ensure uploads container exists (auto-created on first upload)
  • For Container Apps: verify managed identity has Storage Blob Data Contributor role

Session Management Issues

No active session error:

  • Admin must create a session from /admin page
  • Only one session can be active at a time
  • Session must be explicitly closed before creating new one
  • Check browser console for 401 errors (admin secret mismatch)

Admin login fails:

  • Verify ADMIN_SECRET in .env.local matches your input
  • No spaces or special characters causing encoding issues
  • Try regenerating admin secret (update in both .env.local and deployment)

Sessions not appearing in dashboard:

  • Client polls every 5 seconds - wait or refresh page
  • Check browser Network tab for failed /api/sessions requests
  • Verify server is running and accessible

Deployment Issues

Container build fails:

# Test Docker build locally
cd app
docker build -t test-build .

# Check for missing dependencies
npm run build

Terraform errors:

# Custom subdomain already exists
# Solution: Change project_name in terraform.tfvars

# State lock errors
terraform force-unlock <lock-id>

# Provider version conflicts
terraform init -upgrade

GitHub Actions deployment fails:

  • Verify all repository secrets are set correctly
  • Check Azure service principal has required permissions
  • Review workflow logs for specific error messages
  • Ensure Terraform state is not corrupted

Testing Issues

Playwright tests failing:

# Install browser dependencies
npx playwright install --with-deps

# Update Playwright
npm install -D @playwright/test@latest

# Run single test file for debugging
npm run test:headed -- tests/admin.spec.ts

Tests timeout or hang:

  • Ensure dev server is not already running on port 3000
  • Check .env.local is properly configured
  • Increase timeout in playwright.config.ts if needed

Performance Issues

Slow image analysis:

  • Azure AI Content Understanding typical response: 2-5 seconds
  • Check network latency to Azure region
  • Ensure images are not excessively large (max 10MB)
  • Consider image compression before upload

Dashboard not updating:

  • Verify polling intervals in Zustand stores (default 3-5s)
  • Check browser console for JavaScript errors
  • Clear browser cache and reload

Data Issues

Uploaded images not persisting:

  • Images stored in Azure Blob Storage (check Azure Portal)
  • In-memory session data resets on server restart
  • Export CSV before restarting server in development

CSV export empty or missing data:

  • Verify session has submitted surveys
  • Check sessionId parameter in export URL
  • Ensure adminSecret is correct

Getting Help

If issues persist:

  1. Check logs:

    # Local development
    Check terminal output
    
    # Container Apps
    az containerapp logs show --name <app-name> --resource-group <rg-name> --follow
    
    # Vercel
    vercel logs
  2. Enable debug mode: Add to .env.local:

    NODE_ENV=development
  3. Review documentation:

  4. Open an issue: Include: error messages, environment (OS, Node version), steps to reproduce


Ready to collect instant feedback? Start your session now! πŸ“Šβœ¨

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors