Skip to main content
Back to Articles Toxic Plants

Interactive Tool Technical Specifications

| Component | Requirement |

RanchSafety Team January 20, 2026 5 min read

What This Document Covers

This document provides technical specifications for implementing the interactive tools designed in Section 4.5. These specs help development teams build consistent, accessible, and effective educational tools for the AnimalSafeRanch.com platform.

---

System Architecture

Platform Requirements

ComponentRequirement
HostingCloud-based (AWS, GCP, or Azure)
CMSHeadless CMS or WordPress with REST API
FrontendReact, Vue.js, or similar modern framework
MobileProgressive Web App (PWA) + Native apps
DatabasePostgreSQL or MongoDB
CDNCloudFlare or AWS CloudFront

Performance Targets

MetricTarget
Page load time<3 seconds (3G connection)
Time to interactive<5 seconds
Lighthouse score>90 (Performance)
Core Web VitalsPass all metrics
Offline capabilityFull quiz functionality
---

Tool 1: Plant Identification Quiz System

Reference Document

4.5.1 Plant ID Quiz Framework 4.5.3 Plant ID Quiz Questions

Data Model

#### Quiz Question Schema

```json { "question_id": "string (UUID)", "question_type": "enum: multiple_choice | image_id | matching | scenario", "category": "string", "difficulty": "enum: beginner | intermediate | advanced", "question_text": "string", "question_image": { "url": "string (URL)", "alt_text": "string", "caption": "string (optional)" }, "options": [ { "option_id": "string", "text": "string", "image_url": "string (optional)", "is_correct": "boolean", "feedback": "string" } ], "correct_option_ids": ["string"], "explanation": "string (shown after answer)", "related_content_urls": ["string"], "plant_ids": ["string (references plant database)"], "region_tags": ["string"], "seasonal_tags": ["string"], "created_at": "datetime", "updated_at": "datetime", "is_active": "boolean" } ```

#### Quiz Session Schema

```json { "session_id": "string (UUID)", "user_id": "string (optional, for registered users)", "anonymous_id": "string (browser fingerprint)", "quiz_type": "string", "started_at": "datetime", "completed_at": "datetime (nullable)", "questions": [ { "question_id": "string", "presented_at": "datetime", "answered_at": "datetime", "selected_option_ids": ["string"], "is_correct": "boolean", "time_spent_ms": "integer" } ], "score": { "correct": "integer", "total": "integer", "percentage": "float" }, "device_info": { "platform": "string", "browser": "string", "screen_size": "string" } } ```

API Endpoints

#### Quiz Management

``` GET /api/v1/quizzes

  • Returns list of available quizzes
  • Query params: category, difficulty, region
GET /api/v1/quizzes/{quiz_id}
  • Returns quiz metadata and questions
POST /api/v1/quiz-sessions
  • Creates new quiz session
  • Body: { quiz_id, user_id (optional) }
  • Returns: session_id, first question
POST /api/v1/quiz-sessions/{session_id}/answers
  • Records answer
  • Body: { question_id, selected_option_ids }
  • Returns: is_correct, feedback, next_question
GET /api/v1/quiz-sessions/{session_id}/results
  • Returns complete results
  • Includes score, breakdown, recommendations
```

Frontend Components

#### QuizContainer Component

``` Props:

  • quizId: string
  • userId?: string
  • onComplete: (results) => void
State:
  • currentQuestion: Question
  • questionIndex: number
  • answers: Answer[]
  • isLoading: boolean
  • showFeedback: boolean
Methods:
  • loadQuiz()
  • submitAnswer(optionIds: string[])
  • nextQuestion()
  • calculateResults()
```

#### QuestionCard Component

``` Props:

  • question: Question
  • onAnswer: (optionIds: string[]) => void
  • showFeedback: boolean
  • selectedOptions: string[]
  • isCorrect: boolean
Variants:
  • MultipleChoice
  • ImageIdentification
  • Matching
  • Scenario
```

#### ProgressBar Component

``` Props:

  • current: number
  • total: number
  • correct: number
```

#### ResultsDisplay Component

``` Props:

  • results: QuizResults
  • onRetake: () => void
  • onViewAnswers: () => void
```

Accessibility Requirements

RequirementImplementation
Keyboard navigationFull support with focus management
Screen readerARIA labels, live regions for feedback
Color contrastWCAG AA minimum (4.5:1)
Touch targetsMinimum 44×44 pixels
Focus indicatorsVisible focus rings
Skip linksSkip to main content, skip to results
---

Tool 2: Comprehensive Assessment

Reference Document

4.5.5 Test Your Knowledge Assessment

Additional Data Models

#### Assessment Result Schema

```json { "result_id": "string (UUID)", "session_id": "string", "user_id": "string (optional)", "assessment_type": "comprehensive", "completed_at": "datetime", "overall_score": { "correct": 23, "total": 30, "percentage": 76.67 }, "section_scores": [ { "section_id": "plant_identification", "section_name": "Plant Identification", "correct": 8, "total": 10, "percentage": 80.0, "status": "proficient" } ], "rating": "enum: expert | advanced | proficient | developing | beginning", "recommendations": [ { "section_id": "string", "content_urls": ["string"], "priority": "integer" } ], "certificate_eligible": "boolean", "certificate_id": "string (nullable)" } ```

#### Certificate Schema

```json { "certificate_id": "string (UUID)", "verification_code": "string (unique, human-readable)", "user_name": "string", "assessment_type": "string", "score_percentage": "float", "rating": "string", "issued_at": "datetime", "topics_covered": ["string"], "pdf_url": "string", "is_valid": "boolean" } ```

Progress Saving Implementation

#### Local Storage Schema

```javascript const assessmentProgress = { sessionId: "uuid", startedAt: "ISO datetime", lastSavedAt: "ISO datetime", currentQuestionIndex: 15, answers: [ { questionId: "uuid", selectedOptionIds: ["a"], answeredAt: "ISO datetime" } ], elapsedTimeMs: 450000 };

// Storage key: `asr_assessment_${sessionId}` ```

#### Resume Functionality

``` Flow:

  • On page load, check for existing progress
  • If found, prompt user: "Resume previous assessment?"
  • If yes, restore state and continue
  • If no, clear storage and start fresh
  • Auto-save every 30 seconds and on each answer
```

Certificate Generation

#### PDF Generation Requirements

  • Use server-side PDF library (PDFKit, Puppeteer, or similar)
  • Template-based generation
  • Include:
  • User name (provided at completion)
  • Score and rating
  • Date issued
  • Verification code
  • QR code linking to verification URL
  • Store generated PDFs in cloud storage
  • Provide shareable link
#### Verification Endpoint

``` GET /api/v1/certificates/verify/{verification_code}

  • Returns certificate details if valid
  • Public endpoint for verification
```

---

Tool 3: Image-Based Identification

Reference Document

4.5.2 Toxic Plant Image Collection

Image Management System

#### Image Schema

```json { "image_id": "string (UUID)", "plant_id": "string (references plant database)", "image_type": "enum: whole_plant | leaves | flowers | seeds | stem | root | habitat | comparison", "file_info": { "original_filename": "string", "storage_path": "string", "cdn_url": "string", "width": "integer", "height": "integer", "format": "string", "size_bytes": "integer" }, "variants": { "thumbnail": { "url": "string", "width": 150, "height": 150 }, "medium": { "url": "string", "width": 600, "height": 400 }, "large": { "url": "string", "width": 1200, "height": 800 }, "original": { "url": "string" } }, "metadata": { "alt_text": "string (required)", "caption": "string", "photographer": "string", "copyright": "string", "location": "string", "date_taken": "date", "diagnostic_features": ["string"] }, "usage": { "quiz_eligible": "boolean", "field_guide_eligible": "boolean", "featured": "boolean" }, "created_at": "datetime", "updated_at": "datetime" } ```

Image Processing Pipeline

``` Upload Flow:

  • Accept upload (validate type: JPEG, PNG)
  • Validate dimensions (minimum 2000×1500)
  • Extract EXIF metadata
  • Generate variants (thumbnail, medium, large)
  • Optimize for web (compression, format conversion)
  • Upload to CDN
  • Store metadata in database
  • Return image record
```

Lazy Loading Implementation

```javascript // Intersection Observer configuration const imageObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src; img.classList.remove('lazy'); imageObserver.unobserve(img); } }); }, { rootMargin: '50px 0px', threshold: 0.01 });

// Apply to all lazy images document.querySelectorAll('img.lazy').forEach(img => { imageObserver.observe(img); }); ```

---

Tool 4: Photo Submission Feature

Reference Document

4.5.4 Photo Submission Feature Spec

Submission Schema

```json { "submission_id": "string (UUID)", "user_id": "string (optional)", "submitted_at": "datetime", "status": "enum: pending | reviewing | identified | needs_info | rejected", "photos": [ { "photo_id": "string", "url": "string", "photo_type": "enum: whole_plant | leaves | flowers | other" } ], "location": { "latitude": "float (optional)", "longitude": "float (optional)", "county": "string", "region": "string" }, "user_description": "string", "contact_email": "string", "contact_preference": "enum: email | no_contact", "identification": { "plant_id": "string (nullable)", "plant_name": "string (nullable)", "confidence": "enum: confident | possible | uncertain", "notes": "string", "identified_by": "string", "identified_at": "datetime" }, "consent": { "image_use": "boolean", "location_share": "boolean" } } ```

Upload API

``` POST /api/v1/plant-submissions Content-Type: multipart/form-data

Body:

  • photos: File[] (max 5 files, 10MB each)
  • location: JSON string
  • description: string
  • email: string
  • consent: JSON string
Returns:
  • submission_id
  • status
  • confirmation message
GET /api/v1/plant-submissions/{submission_id}
  • Check status of submission
  • Returns identification if complete
```

Admin Review Interface

``` Features:

  • Queue of pending submissions
  • Side-by-side view: User photos | Reference database
  • Quick identification tool (search, select, confirm)
  • Notes field for complex cases
  • Bulk actions for spam/invalid submissions
  • Response template system
```

---

Tool 5: Mobile Plant ID App

Reference Document

4.5.6 Mobile Plant ID Tool Concept

Native App Technical Requirements

#### iOS Requirements

RequirementSpecification
Minimum iOS14.0
Camera accessRequired
Location accessRequired
Storage~500 MB for offline data
FrameworkSwift UI or React Native
#### Android Requirements
RequirementSpecification
Minimum Android10.0 (API 29)
Camera accessRequired
Location accessRequired
Storage~500 MB for offline data
FrameworkKotlin/Jetpack Compose or React Native

Offline Data Package

```json { "package_version": "1.0.0", "last_updated": "2026-01-21", "plants": [ { "plant_id": "string", "common_name": "string", "scientific_name": "string", "toxicity_level": "string", "images": [ { "type": "string", "local_path": "string", "features": ["string"] } ], "description": "string", "symptoms": ["string"], "treatment_summary": "string", "regions": ["string"], "seasons": ["string"] } ], "decision_tree": { "nodes": [], "edges": [] }, "emergency_info": {} } ```

ML Model Specifications

#### On-Device Model

SpecificationValue
Model typeTensorFlow Lite / Core ML
Model size<100 MB
Input size224×224 RGB
OutputTop-5 plant probabilities
Inference time<500ms on mid-range device
#### Training Requirements
  • Training dataset: 10,000+ images
  • Classes: 50+ toxic plants + 100+ look-alikes
  • Augmentation: Rotation, flip, brightness, crop
  • Validation split: 80/10/10 (train/val/test)
  • Target accuracy: 85%+ top-1, 95%+ top-3
---

Tool 6: Printable Field Guide

Reference Document

4.5.7 Printable Plant ID Field Guide

PDF Generation Specifications

#### Print-Ready PDF Requirements

SpecificationValue
Page size4" × 6" (custom)
Bleed0.125"
Color spaceCMYK
Resolution300 DPI minimum
Font embeddingAll fonts embedded
PDF versionPDF/X-4
#### Home Print PDF Requirements
SpecificationValue
Page size8.5" × 11" (Letter)
Layout2-up with crop marks
Color spacesRGB
Resolution150 DPI (web-optimized)
File size<15 MB

Dynamic PDF Generation

```javascript // PDF generation endpoint POST /api/v1/field-guide/generate Body: { format: "home_print" | "professional", colorMode: "color" | "grayscale", region: "string (optional filter)" }

Returns:

  • pdf_url: string (temporary download URL)
  • expires_at: datetime
```

---

Tool 7: Regional Content System

Reference Document

4.5.8 Regional Plant Variations

Region Data Model

```json { "region_id": "string", "region_name": "string", "counties": ["string"], "characteristics": { "elevation": "string", "rainfall": "string", "primary_land_use": "string", "terrain": "string" }, "priority_plants": [ { "plant_id": "string", "threat_level": "enum: extreme | high | moderate | low", "regional_notes": "string", "peak_seasons": ["string"] } ], "seasonal_calendar": [ { "month": "integer (1-12)", "primary_concerns": ["string"], "secondary_concerns": ["string"] } ] } ```

Content Personalization

``` User Flow:

  • Prompt for region selection on first visit
  • Store preference in localStorage / user profile
  • Filter/prioritize content based on region
  • Show regional alerts and seasonal warnings
  • Allow region change anytime
```

Geolocation Auto-Detection

```javascript // Auto-detect region from GPS async function detectRegion() { if (!navigator.geolocation) return null;

try { const position = await new Promise((resolve, reject) => { navigator.geolocation.getCurrentPosition(resolve, reject); });

const { latitude, longitude } = position.coords; const response = await fetch(`/api/v1/regions/detect?lat=${latitude}&lng=${longitude}`); return response.json(); } catch (error) { return null; // Fall back to manual selection } } ```

---

Analytics Implementation

Event Tracking Schema

```javascript // Standard event structure const trackEvent = { event_name: "string", event_category: "string", event_data: { // Event-specific data }, user_id: "string (optional)", session_id: "string", timestamp: "ISO datetime", device_info: { platform: "string", browser: "string" } };

// Key events to track const events = [ "quiz_started", "quiz_completed", "question_answered", "assessment_completed", "certificate_generated", "plant_submission_created", "field_guide_downloaded", "region_selected", "emergency_contact_clicked" ]; ```

Dashboard Metrics

MetricCalculation
Quiz completion rateCompleted / Started
Average quiz scoreMean of all scores
Most missed questionsRank by incorrect rate
Popular contentPage views + time on page
Download countField guide downloads
Submission volumePlant submissions per week
Regional distributionUsers by region
---

Security Considerations

Data Protection

ConcernMitigation
User dataEncrypt PII at rest
Image uploadsVirus scanning, size limits
API abuseRate limiting, authentication
XSSInput sanitization, CSP headers
CSRFToken-based protection

Privacy Compliance

  • GDPR consideration for EU visitors
  • Cookie consent for analytics
  • Data retention policies (define and document)
  • User data export/deletion capability
---

Testing Requirements

Unit Testing

  • Component tests for all UI components
  • API endpoint tests
  • Data validation tests
  • Quiz scoring logic tests

Integration Testing

  • Quiz flow end-to-end
  • Submission workflow
  • PDF generation
  • Mobile app sync

Accessibility Testing

  • Automated (aXe, WAVE)
  • Manual keyboard navigation
  • Screen reader testing (NVDA, VoiceOver)

Performance Testing

  • Load testing (expected concurrent users)
  • Mobile performance profiling
  • Offline capability testing
---

Deployment Architecture

Infrastructure Diagram

``` ┌──────────────────┐ │ CloudFlare │ │ (CDN/WAF) │ └────────┬─────────┘ │ ┌──────────────┴──────────────┐ │ │ ┌─────────┴─────────┐ ┌──────────┴──────────┐ │ Static Assets │ │ Application │ │ (S3/CloudFront) │ │ Server (ECS) │ └───────────────────┘ └──────────┬──────────┘ │ ┌─────────────────┼─────────────────┐ │ │ │ ┌──────────┴──────┐ ┌───────┴────────┐ ┌──────┴──────┐ │ PostgreSQL │ │ Redis │ │ S3 │ │ (RDS) │ │ (Cache) │ │ (Storage) │ └─────────────────┘ └────────────────┘ └─────────────┘ ```

CI/CD Pipeline

``` GitHub → GitHub Actions → Build/Test → Deploy to Staging → Manual Approval → Deploy to Production ```

---

---