Skip to content

SAPAA Web Application Deployment Documentation

Table of Contents

  1. Overview
  2. Prerequisites
  3. Required Services and API Keys
  4. Environment Variables
  5. Local Development Setup
  6. Deploying to Vercel
  7. Database Setup
  8. Post-Deployment Configuration
  9. Security Checklist
  10. Troubleshooting
  11. API Documentation
  12. Required Libraries and Dependencies
  13. Maintenance and Updates

Overview

The SAPAA Web Application is a Next.js application that provides a web interface for stewards and administrators to view and manage protected area inspection data. The application uses:

  • Next.js - React framework with App Router
  • Supabase - Database and authentication service
  • AWS S3 - Image storage
  • Vercel - Deployment platform

Deployed URL: https://w26-project-sapaa-dev-team.vercel.app/


Prerequisites

Before deploying the application, ensure you have:

  1. Node.js (version 20.x or higher)
  2. Download from nodejs.org
  3. Verify installation: node --version

  4. npm (comes with Node.js)

  5. Verify installation: npm --version

  6. Git (for cloning the repository)

  7. Download from git-scm.com
  8. Verify installation: git --version

  9. Vercel Account (free tier available)

  10. Sign up at vercel.com

  11. Supabase Account (free tier available)

  12. Sign up at supabase.com

  13. AWS Account (for S3 image storage)

  14. Sign up at aws.amazon.com

Required Services and API Keys

1. Supabase Setup

The application requires a Supabase project for authentication and database access.

Creating a Supabase Project

  1. Go to supabase.com and sign in
  2. Click "New Project"
  3. Fill in:
  4. Project Name: sapaa-webapp (or your preferred name)
  5. Database Password: Choose a strong password (save this securely)
  6. Region: Select the closest region to your users
  7. Click "Create new project"
  8. Wait for the project to be provisioned (2–3 minutes)

Getting Supabase Credentials

  1. In your Supabase project dashboard, go to SettingsAPI
  2. You will need the following values:
  3. Project URL: found under "Project URL"
  4. anon/public key: found under "Project API keys" → anon public
  5. service_role key: found under "Project API keys" → service_roleKEEP THIS SECRET

Required Database Tables

The application expects the following tables/views in your Supabase database:

  • W26_sites-pa — Main list of protected sites
  • W26_answers — Answers to inspection reports questions
  • W26_attachments — holds links to external content types (like Images or Inaturalist)
  • W26_form_sections — Inspection section records
  • W26_form_reponses — Inspection detail records
  • W26_questions — Inspection question definitions

2. AWS S3 Setup

The application uses AWS S3 for storing and serving images uploaded through the inspection workflow.

Creating an S3 Bucket

  1. Log in to the AWS Management Console
  2. Navigate to S3 and click "Create bucket"
  3. Configure the bucket:
  4. Bucket name: Choose a globally unique name (e.g., sapaa-inspection-images)
  5. Region: Select the closest region to your users
  6. Block Public Access: Configure according to your access requirements (see CORS below)
  7. Click "Create bucket"

Configuring CORS

In your S3 bucket settings, go to PermissionsCORS and add:

[
  {
    "AllowedHeaders": ["*"],
    "AllowedMethods": ["GET", "PUT", "POST", "DELETE"],
    "AllowedOrigins": ["https://your-vercel-url.vercel.app"],
    "ExposeHeaders": []
  }
]

Creating an IAM User

  1. Navigate to IAMUsersCreate user
  2. Attach a policy granting access to your S3 bucket. Example policy:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:PutObject", "s3:GetObject", "s3:DeleteObject"],
      "Resource": "arn:aws:s3:::your-bucket-name/*"
    }
  ]
}
  1. Go to the user's Security credentials tab and click "Create access key"
  2. Save the Access Key ID and Secret Access Key securely

Environment Variables

The application requires the following environment variables.

Required Variables

Variable Name Description Where to Get It
NEXT_PUBLIC_SUPABASE_URL Your Supabase project URL Supabase Dashboard → Settings → API
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY Supabase anon/public key Supabase Dashboard → Settings → API → anon public
SUPABASE_SECRET Supabase service role key (server-side only) Supabase Dashboard → Settings → API → service_role
AWS_ACCESS_KEY_ID AWS IAM access key ID AWS IAM → Users → Security credentials
AWS_SECRET_ACCESS_KEY AWS IAM secret access key AWS IAM → Users → Security credentials
AWS_REGION AWS region of your S3 bucket AWS S3 bucket settings
AWS_S3_BUCKET S3 bucket name AWS S3 console

Environment Variable Format

Create a .env.local file in the webapp directory for local development:

NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=your_supabase_publishable_key
SUPABASE_SECRET=your_supabase_secret

AWS_ACCESS_KEY_ID=your_aws_access_key
AWS_SECRET_ACCESS_KEY=your_aws_secret_key
AWS_REGION=your_region
AWS_S3_BUCKET=your_bucket_name

Important: - Never commit .env.local to version control - The .env.local file is already in .gitignore - SUPABASE_SECRET and all AWS_* keys are server-side only — never prefix them with NEXT_PUBLIC_ - For Vercel deployment, add these variables in the Vercel dashboard (see below)


Local Development Setup

Step 1: Clone the Repository

git clone https://github.com/SAPAA-Dev/W26Project-SAPAA-Dev-Team.git
cd webapp

Step 2: Install Dependencies

npm install

This will install all required packages listed in package.json.

Step 3: Configure Environment Variables

  1. Create a .env.local file in the webapp directory:
# On Mac/Linux
touch .env.local

# On Windows (PowerShell)
New-Item -Path .env.local -ItemType File
  1. Add your environment variables to .env.local using the format from the Environment Variables section above.

Step 4: Run the Development Server

npm run dev

The application will start on http://localhost:3000.

Step 5: Verify Installation

  1. Open http://localhost:3000 in your browser
  2. You should see the login page
  3. If you see errors, check:
  4. All environment variables are set correctly
  5. Supabase project is active
  6. Database tables are created
  7. AWS S3 bucket exists and IAM credentials are valid

Available Scripts

Command Description
npm run dev Start development server on port 3000
npm run build Build production bundle
npm run start Start production server (after build)
npm run lint Run ESLint to check code quality
npm test Run Jest test suite

Deploying to Vercel

Vercel is the recommended deployment platform for Next.js applications. It provides automatic deployments, SSL certificates, and global CDN.

Option 1: Deploy via Vercel CLI

Step 1: Install Vercel CLI

npm install -g vercel

Step 2: Login to Vercel

vercel login
cd webapp
vercel link

Step 4: Configure Environment Variables

  1. Go to vercel.com/dashboard
  2. Select your project
  3. Go to SettingsEnvironment Variables
  4. Add all variables from the Environment Variables section
  5. Enable each variable for Production, Preview, and Development
  6. Click Save

Step 5: Deploy

vercel --prod

Or push to your main branch if you have connected a Git repository:

git push origin main

Option 2: Deploy via Vercel Dashboard (Web Interface)

  1. Go to vercel.com/new
  2. Import your Git repository: W26Project-SAPAA-Dev-Team
  3. Configure the project:
  4. Framework Preset: Next.js (auto-detected)
  5. Root Directory: webapp
  6. Build Command: npm run build
  7. Output Directory: .next
  8. Add all environment variables from the Environment Variables section
  9. Click Deploy

Vercel will automatically install dependencies, build the project, and deploy to a live URL.


CI/CD

Vercel provides built-in CI/CD through GitHub integration — no GitHub Actions required.

  • Push to main branch → triggers production deployment
  • Pull requests → creates preview deployments

Post-Deployment

After deployment, your app will be available at https://your-project-name.vercel.app. Test by visiting the login page, verifying authentication, checking that data loads, and confirming image uploads work.


Database Setup

Creating Database Tables

  1. Log into your Supabase Dashboard
  2. Go to SQL Editor
  3. Run the SQL scripts provided by your development team to create the required tables and views:
  4. Tables: - W26_sites-pa, W26_answers, W26_attachments, W26_form_sections, W26_form_reponses, W26_questions

Note: Contact your development team for the complete SQL schema.

Setting Up Row Level Security (RLS)

  1. Go to AuthenticationPolicies in Supabase
  2. Create policies for each table to allow:
  3. Authenticated users to read data
  4. Admins to read/write data

Example Policy:

-- Allow authenticated users to read sites
CREATE POLICY "Allow authenticated users to read sites"
ON sites_list_fnr
FOR SELECT
TO authenticated
USING (true);

User Roles Setup

The application uses Supabase Auth user_metadata to store user roles in the user_metadata.role field.

How Roles Work: - Default role: steward (assigned automatically if no role is set) - Admin role: admin (must be set manually)

Setting Admin Role:

  1. Go to Supabase Dashboard → AuthenticationUsers
  2. Click the user you want to make an admin
  3. In the Raw User Meta Data section, add or update: json { "role": "admin" }
  4. Click Save

Note: New users created through the signup page default to steward. Only admins can change user roles through the Account Management interface.


User Authorization

The application uses Supabase Auth user_metadata to also store user authorization status in the user_metadata.authenicated field.

How Authorization Works: - Upon account creation authorization is set to: False (assigned automatically as admin aproval is required for application access) - Upon admin aproval of account the value is then set to: True (Indicating an admin has allowed you access to the application)

Setting Authorization Status:

  1. Go to Admin Dashbaord
  2. Proceed to Account Management
  3. Click the user you want to Authorize
  4. Toggle their approval status to: Approved
  5. Click Save

Note: New users created through the signup page default to False. Only admins can change user authorization status through the account management interface.


Post-Deployment Configuration

1. Verify Environment Variables

  1. Go to Vercel Dashboard → Your Project → SettingsEnvironment Variables
  2. Ensure all 7 required variables are present and enabled for Production

2. Configure Supabase Redirect URLs

  1. Go to Supabase Dashboard → AuthenticationURL Configuration
  2. Add your Vercel URL to Redirect URLs:
  3. https://your-project-name.vercel.app/auth/callback
  4. https://your-project-name.vercel.app/auth/confirm
  5. Set Site URL to: https://your-project-name.vercel.app

3. Test Authentication

  1. Visit your deployed URL
  2. Verify login, signup, session persistence, and logout all work correctly

4. Test Database Connection

  1. Log in to the application
  2. Navigate to the Protected Areas page
  3. Verify sites load correctly and check the browser console for errors

5. Test Image Upload (S3)

  1. Log in and navigate to a page with image upload functionality
  2. Upload a test image and verify it appears correctly
  3. Check the browser console and network tab for any S3-related errors

6. Test Admin Features

  1. Log in with an admin account
  2. Verify the Admin Dashboard loads, charts display data, and heatmap search works

7. Test API Endpoints (See API Documentation)

# Example Test on geocoding
curl https://your-project-name.vercel.app/api/geocode?q=Alberta

Security Checklist

Before going to production, ensure:

  • [ ] All environment variables are set in Vercel — not hardcoded in source
  • [ ] SUPABASE_SECRET and all AWS_* keys are never exposed to client-side code
  • [ ] Debug/test credentials are removed
  • [ ] Default passwords are changed
  • [ ] Row Level Security (RLS) is enabled on all Supabase tables
  • [ ] S3 bucket CORS policy is restricted to your deployed domain
  • [ ] S3 IAM policy follows least-privilege (only required actions granted)
  • [ ] SSL/HTTPS is enabled (automatic with Vercel)
  • [ ] API rate limiting is configured if needed
  • [ ] Error messages don't expose sensitive information
  • [ ] Authentication is required for all protected routes
  • [ ] Admin routes are properly protected
  • [ ] No console.log statements with sensitive data in production
  • [ ] .env.local is never committed to version control (verify .gitignore)

Troubleshooting

Issue: "Unable to connect to Supabase"

Symptoms: Login fails, sites don't load, Supabase connection errors.

Solutions: 1. Verify NEXT_PUBLIC_SUPABASE_URL is correct 2. Check Supabase project is active (not paused) 3. Check status.supabase.com

Issue: "Authentication not working"

Symptoms: Users can't log in, redirect loops, "Invalid credentials" errors.

Solutions: 1. Verify Supabase redirect URLs are configured (see Post-Deployment Configuration) 2. Check NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY is correct 3. Verify Supabase Auth is enabled in your project

Issue: "No sites found" or empty data

Symptoms: Protected Areas page shows no sites, dashboard shows zero statistics.

Solutions: 1. Verify database tables exist and contain data 2. Check RLS policies allow read access for authenticated users 3. Verify SUPABASE_SECRET is set correctly for server-side queries

Issue: "S3 uploads failing"

Symptoms: Image uploads fail or images don't appear after upload.

Solutions: 1. Verify all four AWS_* environment variables are set correctly in Vercel 2. Check IAM policy grants s3:PutObject, s3:GetObject, and s3:DeleteObject on your bucket 3. Verify the bucket CORS configuration allows requests from your Vercel domain 4. Check browser console and network tab for specific error codes

Issue: "Build fails on Vercel"

Symptoms: Deployment fails during build, build logs show errors.

Solutions: 1. Check build logs in the Vercel dashboard 2. Verify all dependencies are listed in package.json 3. Run npm run build locally first to reproduce and debug the error

Issue: "App builds but fails at runtime" or blank page after deploy

Symptoms: Blank page, runtime errors in browser console.

Solutions: 1. Check environment variables are set in Vercel (not just .env.local) 2. Ensure variables are enabled for the Production environment 3. Redeploy after adding or changing variables 4. Check browser console for specific errors

Getting Help

If you encounter issues not covered here:

  1. Check Vercel deployment logs
  2. Check Supabase logs (Dashboard → Logs)
  3. Review browser console for client-side errors
  4. Check the network tab for failed API requests
  5. Contact your development team with error messages, steps to reproduce, browser/OS information, and screenshots

API Documentation

The full interactive API reference is available at /api-docs on your deployed instance (OpenAPI 3.0 / Swagger UI).

All endpoints are served from the base URL https://your-project-name.vercel.app (or http://localhost:3000 for local development).


Endpoint: GET /api/gallery

Description: Returns all uploaded inspection image attachments with metadata and signed S3 URLs. Admin only.

Authentication: Required — Admin role

Query Parameters: None

Response 200:

{
  "items": [
    {
      "id": 14,
      "response_id": 3226,
      "question_id": 27,
      "caption": "Cross Country ski trails",
      "identifier": "Ski Trails",
      "date": "2026-01-31",
      "storage_key": "inspections/207/3226/27/Riverlot56NA-2026-01-31-RaiyanaRahman-SkiTrails-aa05346a.jpg",
      "content_type": "image/jpeg",
      "file_size_bytes": 506701,
      "filename": "Riverlot56NA-2026-01-31-RaiyanaRahman-SkiTrails-aa05346a.jpg",
      "site_id": 207,
      "site_name": "Riverlot 56 (NA)",
      "imageUrl": "https://sapaa-inspection-images.s3.ca-central-1.amazonaws.com/..."
    }
  ]
}
Status Description
200 Gallery items returned successfully
401 Unauthorized
403 Forbidden — admin access required
500 Failed to load gallery

2. Get Inspection Images by Site or Response

Endpoint: GET /api/site-images

Description: Returns uploaded image attachments filtered by site ID and/or response ID. At least one query parameter must be provided.

Authentication: Required

Query Parameters:

Parameter Type Required Description
siteid integer No* Filter images by site ID
responseid integer No* Filter images by response ID

*At least one of siteid or responseid must be provided.

Example Request:

GET /api/site-images?siteid=207
GET /api/site-images?responseid=3235
GET /api/site-images?siteid=207&responseid=3235

Response 200:

{
  "items": [
    {
      "id": 14,
      "response_id": 3235,
      "question_id": 27,
      "storage_key": "inspections/207/3235/27/Riverlot56NA-2026-01-31-RaiyanaRahman-SkiTrails-aa05346a.jpg",
      "filename": "Riverlot56NA-2026-01-31-RaiyanaRahman-SkiTrails-aa05346a.jpg",
      "content_type": "image/jpeg",
      "file_size_bytes": 506701,
      "caption": "Cross Country ski trails",
      "identifier": "Ski Trails",
      "site_id": 207,
      "imageUrl": "https://sapaa-inspection-images.s3.ca-central-1.amazonaws.com/..."
    }
  ]
}
Status Description
200 Site images returned successfully
400 Provide at least one of: siteid, responseid
401 Unauthorized
500 Failed to fetch site images

Endpoint: GET /api/sites/{siteId}/gallery

Description: Returns image attachments for a specific site including signed S3 URLs. Requires authentication.

Authentication: Required

Path Parameters:

Parameter Type Required Description
siteId integer Yes Site ID

Example Request:

GET /api/sites/207/gallery

Response 200:

{
  "items": [
    {
      "id": 14,
      "caption": "Cross Country ski trails",
      "identifier": "Ski Trails",
      "filename": "Riverlot56NA-2026-01-31-RaiyanaRahman-SkiTrails-aa05346a.jpg",
      "file_size_bytes": 506701,
      "site_name": "Riverlot 56 (NA)",
      "response_id": 3235,
      "imageUrl": "https://sapaa-inspection-images.s3.ca-central-1.amazonaws.com/..."
    }
  ]
}
Status Description
200 Gallery items returned successfully
400 Invalid site ID
401 Unauthorized
500 Failed to load gallery

4. Get All Homepage Image Uploads

Endpoint: GET /api/homepage-images

Description: Returns all homepage image uploads with metadata and signed S3 URLs. Admin only.

Authentication: Required — Admin role

Query Parameters: None

Response 200:

{
  "items": [
    {
      "id": 16,
      "site_id": 207,
      "site_name": "Riverlot 56 (NA)",
      "date": "2026-01-31",
      "photographer": "Raiyana Rahman",
      "caption": "Cross Country ski trails",
      "identifier": "Ski Trails",
      "filename": "Riverlot56NA-2026-01-31-RaiyanaRahman-SkiTrails-0642088a-b29f-400a-9ce7-e1003fa1e928.jpg",
      "file_size_bytes": 506701,
      "storage_key": "homepage-image-uploads/207/6966742d-b9e7-46c1-842f-030d4a97ba39/Riverlot56NA-...",
      "imageUrl": "https://sapaa-inspection-images.s3.ca-central-1.amazonaws.com/homepage-image-uploads/..."
    }
  ]
}
Status Description
200 Homepage images returned successfully
401 Unauthorized
403 Forbidden — admin access required
500 Failed to load images

5. Get Homepage Image Uploads for a Specific Site

Endpoint: GET /api/homepage-images/{siteId}

Description: Returns homepage image uploads for a specific site including metadata and signed S3 URLs. Admin only.

Authentication: Required — Admin role

Path Parameters:

Parameter Type Required Description
siteId integer Yes Site ID

Example Request:

GET /api/homepage-images/207

Response 200: Returns the same HomepageImageItem schema as above, scoped to the given site.

Status Description
200 Homepage images for site returned successfully
400 Invalid site ID
401 Unauthorized
500 Failed to load images

Uploads

6. Generate Presigned S3 URL for Inspection Images

Endpoint: POST /api/s3/presign

Description: Generates a short-lived presigned S3 URL for uploading an inspection image attachment and returns the generated SAPAA-standardized filename.

Authentication: Required

Request Body (application/json):

{
  "filename": "tree-photo.jpg",
  "contentType": "image/jpeg",
  "fileSize": 245678,
  "responseId": 3226,
  "questionId": 27,
  "siteId": 207,
  "siteName": "Riverlot 56 (NA)",
  "date": "2026-01-31",
  "photographer": "Raiyana Rahman",
  "identifier": "Ski Trails"
}

Response 200:

{
  "uploadUrl": "https://example-bucket.s3.amazonaws.com/...",
  "key": "inspections/207/3226/27/Riverlot56NA-2026-01-31-RaiyanaRahman-SkiTrails-aa05346a.jpg",
  "generatedFilename": "Riverlot56NA-2026-01-31-RaiyanaRahman-SkiTrails-aa05346a.jpg"
}
Status Description
200 Presigned upload URL generated successfully
400 Invalid file data, missing IDs or metadata, unsupported file type, or file too large
401 Unauthorized
500 Failed to generate upload URL

7. Generate Presigned S3 URL for Homepage Images

Endpoint: POST /api/s3/presign-homepage-images

Description: Generates a short-lived presigned S3 URL for uploading a homepage image using standardized SAPAA filename metadata.

Authentication: Required

Request Body (application/json):

{
  "contentType": "image/jpeg",
  "fileSize": 688724,
  "siteId": 207,
  "siteName": "Riverlot 56 (NA)",
  "date": "2026-01-31",
  "photographer": "Zoe Prefontaine",
  "identifier": "Broken Tree Trunk"
}

Response 200:

{
  "uploadUrl": "https://example-bucket.s3.amazonaws.com/...",
  "key": "homepage-image-uploads/207/user-id/Riverlot56NA-2026-01-31-ZoePrefontaine-BrokenTreeTrunk-f6f399ce-3521-4fa4-987a-43cf356c693b.jpg"
}
Status Description
200 Presigned upload URL generated successfully
400 Invalid file data, missing metadata, unsupported type, or file too large
401 Unauthorized
500 Failed to generate upload URL

8. Get All Homepage Image Uploads (User)

Endpoint: GET /api/user-gallery/homepage-upload

Description: Returns all homepage image uploads with metadata and signed S3 URLs, ordered by date descending. Requires authentication.

Authentication: Required

Query Parameters: None

Response 200: Returns the same HomepageImageItem schema as endpoint 4, available to all authenticated users.

Status Description
200 Homepage images returned successfully
401 Unauthorized
500 Failed to load images

9. Get All Inspection Image Attachments (User)

Endpoint: GET /api/user-gallery/sir-upload

Description: Returns all inspection image attachments (JPEG, PNG, WebP) across all sites, with resolved site names and signed S3 URLs. Ordered by ID descending. Requires authentication.

Authentication: Required

Query Parameters: None

Response 200:

{
  "items": [
    {
      "id": 14,
      "response_id": 3226,
      "question_id": 27,
      "caption": "Cross Country ski trails",
      "identifier": "Ski Trails",
      "date": "2026-01-31",
      "storage_key": "inspections/207/3226/27/Riverlot56NA-2026-01-31-RaiyanaRahman-SkiTrails-aa05346a.jpg",
      "content_type": "image/jpeg",
      "file_size_bytes": 506701,
      "filename": "Riverlot56NA-2026-01-31-RaiyanaRahman-SkiTrails-aa05346a.jpg",
      "site_id": 207,
      "site_name": "Riverlot 56 (NA)",
      "imageUrl": "https://sapaa-inspection-images.s3.ca-central-1.amazonaws.com/..."
    }
  ]
}
Status Description
200 Gallery items returned successfully
401 Unauthorized
500 Failed to load gallery

PDF Export

10. Generate PDF Inspection Report

Endpoint: POST /api/pdf

Description: Generates PDF inspection reports in single, site, or multi-site mode. Admin only.

Authentication: Required — Admin role

Request Body (application/json):

{
  "mode": "single",
  "responseId": 3235,
  "options": {
    "includeImages": false,
    "maxImagesPerInspection": 5,
    "includeEmptyAnswers": false,
    "includeCoverPage": true,
    "includeNaturalnessSummary": true,
    "selectedSections": "all",
    "sortOrder": "newest",
    "pageSize": "LETTER"
  }
}

Request Body Fields:

Field Type Description
mode string Report mode: single, site, or multi-site
responseId integer Required when mode is single
options.includeImages boolean Include images in PDF (default: false)
options.maxImagesPerInspection integer Max images per inspection, 0–20 (default: 5)
options.includeEmptyAnswers boolean Include unanswered questions (default: false)
options.includeCoverPage boolean Include a cover page (default: true)
options.includeNaturalnessSummary boolean Include naturalness summary section (default: true)
options.selectedSections string all or custom (default: all)
options.sortOrder string newest or oldest (default: newest)
options.pageSize string LETTER or A4 (default: LETTER)

Response 200: Returns the generated PDF as application/pdf.

Status Description
200 PDF generated successfully (application/pdf)
401 Unauthorized
403 Forbidden — admin access required
500 Failed to generate PDF

Utility Endpoints

11. Geocoding API

Endpoint: GET /api/geocode

Description: Geocodes a location name to coordinates using the OpenCage API.

Authentication: Required

Query Parameters:

Parameter Type Required Description
q string Yes Location name to geocode

Example Request:

GET /api/geocode?q=Elk Island Provincial Park

Response 200:

{
  "latitude": 53.5731,
  "longitude": -112.8583
}
Status Description
200 Coordinates returned successfully
400 Missing q parameter
500 Geocoding failed

Rate Limits: Limited by OpenCage API quota (2,500 requests/day on free tier).


12. Heatmap API

Endpoint: GET /api/heatmap

Description: Searches for sites matching a keyword and returns visit counts for heatmap visualization.

Authentication: Required

Query Parameters:

Parameter Type Required Description
keyword string No Search term to match against site names

Example Request:

GET /api/heatmap?keyword=park

Response 200:

{
  "data": [
    { "namesite": "Elk Island Provincial Park", "count": 15 },
    { "namesite": "Writing-on-Stone Provincial Park", "count": 12 }
  ]
}
Status Description
200 Site data returned successfully
400 Invalid query or database error
500 Database query failed

Authentication Endpoints

These routes are handled internally by Next.js and Supabase. Use the frontend login/signup pages instead of calling them directly.

Route Description
POST /login User login
POST /signup User registration
GET /auth/callback OAuth callback handler
GET /auth/confirm Email confirmation handler

Data Schemas

GalleryItem

Field Type Nullable Description
id integer No Record ID
response_id integer No Associated inspection response ID
question_id integer No Associated inspection question ID
caption string Yes Image caption
identifier string Yes Short image label
date string Yes Date of inspection (YYYY-MM-DD)
storage_key string No S3 object key
content_type string No MIME type (e.g. image/jpeg)
file_size_bytes integer Yes File size in bytes
filename string No SAPAA-standardized filename
site_id integer No Associated site ID
site_name string Yes Human-readable site name
imageUrl string No Signed S3 URL for image access

HomepageImageItem

Field Type Nullable Description
id integer No Record ID
site_id integer No Associated site ID
site_name string Yes Human-readable site name
date string No Upload date (YYYY-MM-DD)
photographer string Yes Photographer name
caption string Yes Image caption
identifier string Yes Short image label
filename string No SAPAA-standardized filename
file_size_bytes integer Yes File size in bytes
storage_key string No S3 object key
imageUrl string No Signed S3 URL for image access

ErrorResponse

Field Type Description
error string Human-readable error message

Required Libraries and Dependencies

Production Dependencies

Package Purpose
next Next.js framework
react / react-dom React library and DOM rendering
@supabase/ssr Supabase server-side rendering support
@supabase/supabase-js Supabase JavaScript client
@aws-sdk/client-s3 AWS S3 SDK for image storage
@aws-sdk/s3-request-presigner Presigned URL generation for S3
@mui/material Material-UI components
@mui/icons-material Material-UI icons
chart.js Chart library
react-chartjs-2 React wrapper for Chart.js
leaflet Map library
react-leaflet React wrapper for Leaflet
leaflet.heat Heatmap plugin for Leaflet
axios HTTP client
lucide-react Icon library
react-icons Additional icons

Development Dependencies

Package Purpose
typescript TypeScript compiler
eslint Code linting
jest Testing framework
@testing-library/react React testing utilities
tailwindcss CSS utility framework

Installation

All dependencies are installed with:

npm install

Maintenance and Updates

Updating Dependencies

# Check for outdated packages
npm outdated

# Update a specific package
npm update <package-name>

# Update all packages (use with caution — test thoroughly after)
npm update

Commit package-lock.json changes after any updates.

Rollback Procedure

Option 1: Vercel Instant Rollback

  1. Go to Vercel DashboardDeployments
  2. Select a previous stable deployment
  3. Click "Promote to Production"

Option 2: Git-Based Rollback

git checkout <previous-stable-commit>
git push origin main

This triggers a new Vercel deployment from the stable commit.

Monitoring

  • Vercel Analytics: Monitor performance and errors
  • Supabase Dashboard: Monitor database usage and logs
  • AWS CloudWatch / S3 Access Logs: Monitor S3 usage and errors

Backup Strategy

  • Database: Supabase provides automatic daily backups (on paid plans)
  • Images: Enable S3 Versioning or cross-region replication for production use
  • Code: Git repository serves as the primary code backup
  • Environment Variables: Store all credentials securely using a password manager

Support and Resources

For deployment support or issues, contact your development team with error messages, reproduction steps, browser/OS information, and screenshots where applicable.


Document Version: 2.0
Last Updated: March 2026
Prepared for: Stewards of Alberta's Protected Areas Association