A comprehensive mobile scouting application for FIRST Robotics Competition (FRC) Team 589, built for the 2025 REEFSCAPE game season.
Ready to get up and running? Dive into the Frontend Setup Guide!
- Overview
- Features
- Architecture
- Technology Stack
- File System Structure
- Database Schema
- Getting Started
- Documentation
- Contributing
- License
The FRC 589 Scouting App is a mobile-first application designed to streamline the collection, analysis, and visualization of match data during FIRST Robotics competitions. The app enables team members to scout opponent robots, track match performance, and make data-driven decisions for alliance selections.
- Data Collection: Scouts collect real-time data on robot performance during pit inspections and matches
- Strategic Analysis: Analyze team statistics, rankings, and capabilities to inform strategy
- Alliance Selection: Make informed decisions during alliance selection based on comprehensive data
- Competition Management: Administrators manage competitions, users, and data across multiple regionals
- Scouts: Team members collecting pit and match data on tablets/phones
- Strategy Team: Analyzing data for match strategy and alliance selection
- Scouting Leads: Managing competitions, users, and application configuration
-
β Pit Scouting
- Document robot capabilities and specifications
- Vision system and drivetrain information
- Intake and scoring capabilities
- Climb abilities and strategic notes
-
β Match Scouting
- Track autonomous, teleoperated, and endgame performance
- Score coral placement (L1-L4 levels)
- Track algae removal, processing, and scoring
- Record climb performance and endgame actions
- Driver ratings and defensive play tracking
-
β Real-time Statistics
- Auto-calculated team averages and rankings
- Leaderboard with sortable metrics
- Match history and trend analysis
- Visual charts and graphs
-
β User Management
- Supabase authentication (email/password)
- Role-based access control (scouts, admins)
- User profiles and permissions
- Submission tracking
-
β Competition Management
- Multiple competition support
- Dynamic competition switching
- Competition-specific data isolation
- Admin controls for competition setup
-
π Offline Support
- Upload queue for failed submissions
- Automatic retry with exponential backoff
- Local data caching
- Graceful degradation without internet
-
π Data Visualization
- Interactive bar charts
- Team comparison views
- Match-by-match breakdowns
- Sortable leaderboards
-
π¨ Modern UI/UX
- Swipe navigation between screens
- Touch-friendly controls
- Demo mode border for testing
- Connection status indicators
- Dark status bar for visibility
The application follows a client-server architecture with a mobile frontend and cloud-based backend:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Mobile Devices β
β (iOS/Android - React Native with Expo) β
β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β β Scouts β β Strategy β β Admins β β
β β (Tablets) β β Team β β (Manage) β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββ
β
β HTTPS / REST API
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Supabase Cloud Backend β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β PostgreSQL Database β β
β β β’ Match Reports β’ Pit Reports β β
β β β’ Robot Stats β’ User Profiles β β
β β β’ App Metadata β’ Scoring Config β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Supabase Services β β
β β β’ Authentication β’ Row Level Security β β
β β β’ Real-time (opt) β’ Storage (future) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- Context-based State Management: React Context API for global state (Auth, Competition)
- Service Layer Architecture: Separation of data access logic (
data/services) - Upload Queue Pattern: Resilient offline data submission with retry logic
- Cache-First Strategy: Local caching for performance and offline support
- Database Triggers: Auto-calculated statistics using PostgreSQL triggers
- Row Level Security: Supabase RLS policies for data access control
| Technology | Version | Purpose | Documentation |
|---|---|---|---|
| React Native | 0.81.5 | Mobile framework | Docs |
| Expo | 54.0.23 | Development platform | Docs |
| TypeScript | 5.9.3 | Type-safe JavaScript | Docs |
| Expo Router | 6.0.14 | File-based routing | Docs |
| React Native Chart Kit | 6.12.0 | Data visualization | Docs |
| Supabase JS | 2.75.0 | Backend client | Docs |
| AsyncStorage | 2.2.0 | Local data persistence | Docs |
| React Navigation | 7.1.17 | Navigation library | Docs |
| Technology | Purpose | Documentation |
|---|---|---|
| Supabase | Backend-as-a-Service | Docs |
| PostgreSQL | Relational database | Docs |
| PostgREST | REST API (via Supabase) | Docs |
| Row Level Security | Data access control | Docs |
| Tool | Purpose | Documentation |
|---|---|---|
| Git | Version control | Docs |
| npm | Package management | Docs |
| Jest | Testing framework | Docs |
| ESLint | Code linting | Docs |
- UI Components: React Native core components, Expo Vector Icons
- Gestures: React Native Gesture Handler, PanResponder
- Networking: Fetch API, Supabase client, NetInfo
- State Management: React Context API, useState, useEffect hooks
- Type Safety: TypeScript with strict mode enabled
589_Scouting_App_2026/
β
βββ Frontend_2025_Scouting/ # Mobile application
β βββ app/ # Expo Router pages
β β βββ (login)/ # Authenticated routes
β β β βββ (admin)/ # Admin pages (users, competitions)
β β β βββ (regional)/ # Competition-specific routes
β β β β βββ (Scouting)/ # Data collection
β β β β β βββ (MatchScouting)/ # Match scouting workflow
β β β β β β βββ Pregame.tsx # Team/match selection
β β β β β β βββ Auto.tsx # Autonomous tracking
β β β β β β βββ Tele.tsx # Teleoperated tracking
β β β β β β βββ Post.tsx # Endgame & submission
β β β β β βββ PitScouting.tsx # Pit report form
β β β β βββ (TeamInfo)/ # Data viewing
β β β β βββ (tabs)/ # Team detail tabs
β β β β β βββ RobotDisplay.tsx # Pit report view
β β β β β βββ MatchData.tsx # Averages chart
β β β β β βββ QualData.tsx # Per-match view
β β β β βββ Leaderboard.tsx # Rankings
β β β βββ home.tsx # Homepage
β β βββ login.tsx # Login screen
β β βββ signup.tsx # Registration screen
β β βββ index.tsx # Entry point
β β βββ _layout.tsx # Root layout
β β
β βββ components/ # Reusable UI components
β β βββ AppHeader.tsx # Top navigation bar
β β βββ AppFooter.tsx # Bottom navigation
β β βββ ConnectionHeader.tsx # Connection status
β β βββ DemoBorderWrapper.tsx # Demo mode indicator
β β βββ UploadQueueIndicator.tsx # Upload status
β β βββ RobotLeaderboard.tsx # Leaderboard list
β β βββ StatsAccordion.tsx # Expandable stats
β β βββ ProgressBar.tsx # Progress indicator
β β
β βββ contexts/ # React contexts
β β βββ AuthContext.tsx # Authentication state
β β βββ CompetitionContext.tsx # Active competition
β β
β βββ data/ # Data access layer
β β βββ supabaseClient.tsx # Supabase initialization
β β βββ supabaseService.tsx # Database queries
β β βββ processing.tsx # Data processing logic
β β βββ uploadQueue.tsx # Offline upload queue
β β βββ competitionManager.ts # Competition sync
β β βββ connectionManager.ts # Connection monitoring
β β βββ matchDataCache.ts # Match data cache
β β βββ cache.tsx # Local storage
β β βββ schemaVersion.ts # Version compatibility
β β
β βββ hooks/ # Custom React hooks
β β βββ useRealtimeMatches.ts # Real-time match updates
β β βββ useRealtimeRobots.ts # Real-time robot updates
β β
β βββ supabase_setup/ # Database setup scripts
β β βββ 1 - DROP_ALL_SCHEMA.sql # Clean slate (dangerous!)
β β βββ 2 - CREATE_CLEAN_SCHEMA.sql # Complete schema
β β βββ 3 - CREATE_AUTH_TRIGGER.sql # User profile trigger
β β βββ 4 - SET_TEST_COMPETITION.sql # Configure test competition
β β βββ 5 - LOAD_TEST_DATA.sql # Sample data
β β βββ 6 - GRANT_ADMIN_ACCESS.sql # Admin privileges
β β
β βββ docs/ # Frontend documentation
β β βββ SUPABASE_SETUP_GUIDE.md # Database setup guide
β β
β βββ assets/ # Images, fonts, icons
β βββ .env.example # Environment template
β βββ app.config.js # Expo configuration
β βββ package.json # Dependencies
β βββ tsconfig.json # TypeScript config
β
βββ Docs/ # Project documentation
β βββ IDEAS.md # Future enhancements
β βββ DATABASE_FUNCTIONS_AUDIT.md # Function documentation
β βββ DATABASE_TRIGGERS_EXPLAINED.md # Trigger behavior
β βββ SCHEMA_VERSIONING_GUIDE.md # Version management
β βββ UPLOAD_QUEUE_SYSTEM.md # Offline queue design
β βββ [Other documentation files]
β
βββ .git/ # Git repository
βββ .gitignore # Git ignore rules
βββ README.md # This file
app/: File-based routing structure (Expo Router)components/: Reusable UI componentscontexts/: Global state managementdata/: Business logic and database accesssupabase_setup/: Database schema and migrationsDocs/: Project documentation and guides
The database uses PostgreSQL 15+ via Supabase with Row Level Security enabled.
Purpose: Application-wide configuration (single row table)
| Column | Type | Description |
|---|---|---|
id |
INTEGER | Always 1 (primary key) |
app_name |
TEXT | Application name |
game_name |
TEXT | Current FRC game (REEFSCAPE) |
game_year |
INTEGER | Competition year (2025) |
schema_version |
TEXT | Database schema version |
active_competition |
VARCHAR | Currently selected competition |
available_competitions |
JSONB | List of competitions |
feature_flags |
JSONB | Feature toggles |
Purpose: User accounts and permissions (extends auth.users)
| Column | Type | Description |
|---|---|---|
id |
UUID | Links to auth.users(id) |
email |
TEXT | User email (unique) |
display_name |
TEXT | Display name |
team_number |
INTEGER | User's FRC team |
is_admin |
BOOLEAN | Admin privileges |
default_regional |
VARCHAR | Default competition |
Purpose: Match scouting data (one row per team per match)
| Column | Type | Description |
|---|---|---|
id |
INTEGER | Auto-increment primary key |
team_number |
INTEGER | Team being scouted |
match_number |
INTEGER | Match number |
regional |
VARCHAR | Competition name |
auto_l1_scored |
INTEGER | Auto L1 coral scored |
auto_l2_scored |
INTEGER | Auto L2 coral scored |
auto_l3_scored |
INTEGER | Auto L3 coral scored |
auto_l4_scored |
INTEGER | Auto L4 coral scored |
auto_algae_scored |
INTEGER | Auto algae in net |
tele_l1_scored |
INTEGER | Tele L1 coral scored |
tele_l2_scored |
INTEGER | Tele L2 coral scored |
tele_l3_scored |
INTEGER | Tele L3 coral scored |
tele_l4_scored |
INTEGER | Tele L4 coral scored |
tele_algae_scored |
INTEGER | Tele algae in net |
total_l1_scored |
INTEGER | Total L1 (auto + tele) |
total_l2_scored |
INTEGER | Total L2 (auto + tele) |
total_l3_scored |
INTEGER | Total L3 (auto + tele) |
total_l4_scored |
INTEGER | Total L4 (auto + tele) |
total_algae_scored |
INTEGER | Total algae (auto + tele) |
algae_removed |
INTEGER | Algae removed from reef |
algae_processed |
INTEGER | Algae processed |
climb_deep |
BOOLEAN | Deep cage climb |
climb_shallow |
BOOLEAN | Shallow cage climb |
park |
BOOLEAN | Parked in endgame |
match_score |
INTEGER | Auto-calculated total score |
defence |
BOOLEAN | Played defense |
driver_rating |
INTEGER | Driver skill (1-5) |
disabled |
BOOLEAN | Robot disabled |
malfunction |
BOOLEAN | Robot malfunction |
no_show |
BOOLEAN | Team didn't show |
comments |
TEXT | Scout notes |
submitted_by |
UUID | User who submitted |
submitted_at |
TIMESTAMP | Submission time |
Unique Constraint: (team_number, match_number, regional) - one report per team per match per competition
Purpose: Pit scouting data (robot capabilities)
| Column | Type | Description |
|---|---|---|
team_number |
INTEGER | Team number (PK) |
regional |
VARCHAR | Competition name (PK) |
vision_sys |
VARCHAR | Vision system type |
drive_train |
VARCHAR | Drivetrain type |
ground_intake |
BOOLEAN | Has ground intake |
source_intake |
BOOLEAN | Has source intake |
l1_scoring |
BOOLEAN | Can score L1 |
l2_scoring |
BOOLEAN | Can score L2 |
l3_scoring |
BOOLEAN | Can score L3 |
l4_scoring |
BOOLEAN | Can score L4 |
can_remove |
BOOLEAN | Can remove algae |
can_process |
BOOLEAN | Can process algae |
can_net |
BOOLEAN | Can score algae in net |
can_climb_deep |
BOOLEAN | Can deep climb |
can_climb_shallow |
BOOLEAN | Can shallow climb |
comments |
TEXT | Pit notes |
submitted_by |
UUID | User who submitted |
Purpose: Calculated team statistics (auto-updated by triggers)
| Column | Type | Description |
|---|---|---|
team_number |
INTEGER | Team number (PK) |
regional |
VARCHAR | Competition name (PK) |
matches_played |
INTEGER | Number of matches |
avg_l1 |
NUMERIC(5,2) | Average L1 scored |
avg_l2 |
NUMERIC(5,2) | Average L2 scored |
avg_l3 |
NUMERIC(5,2) | Average L3 scored |
avg_l4 |
NUMERIC(5,2) | Average L4 scored |
avg_coral |
NUMERIC(5,2) | Average total coral |
avg_algae_scored |
NUMERIC(5,2) | Average algae scored |
avg_algae_removed |
NUMERIC(5,2) | Average algae removed |
avg_algae_processed |
NUMERIC(5,2) | Average algae processed |
avg_algae |
NUMERIC(5,2) | Average total algae |
avg_climb_deep |
NUMERIC(5,2) | Deep climb rate (0-1) |
avg_climb_shallow |
NUMERIC(5,2) | Shallow climb rate (0-1) |
avg_park |
NUMERIC(5,2) | Park rate (0-1) |
avg_match_score |
NUMERIC(6,2) | Average calculated score |
rank_value |
NUMERIC(6,2) | Ranking (= avg_match_score) |
Note: This table is automatically updated by database triggers when match reports are inserted, updated, or deleted.
Purpose: REEFSCAPE point values (admin-configurable)
| Column | Type | Default | Description |
|---|---|---|---|
auto_coral_l1_points |
INTEGER | 3 | Auto L1 points |
auto_coral_l2_points |
INTEGER | 4 | Auto L2 points |
auto_coral_l3_points |
INTEGER | 6 | Auto L3 points |
auto_coral_l4_points |
INTEGER | 7 | Auto L4 points |
tele_coral_l1_points |
INTEGER | 2 | Tele L1 points |
tele_coral_l2_points |
INTEGER | 3 | Tele L2 points |
tele_coral_l3_points |
INTEGER | 4 | Tele L3 points |
tele_coral_l4_points |
INTEGER | 5 | Tele L4 points |
algae_net_points |
INTEGER | 4 | Algae in net points |
algae_processor_points |
INTEGER | 6 | Algae processed points |
park_points |
INTEGER | 2 | Park points |
climb_shallow_points |
INTEGER | 6 | Shallow climb points |
climb_deep_points |
INTEGER | 12 | Deep climb points |
leave_points |
INTEGER | 3 | Auto leave bonus |
Combines robot_stats and pit_reports for leaderboard display.
Shows user statistics including submission counts for admin dashboard.
| Function | Purpose |
|---|---|
calculate_match_score() |
Calculates total match score from game elements |
recalculate_team_stats() |
Recalculates all statistics for a team |
create_user_profile() |
Auto-creates profile when user signs up |
is_user_admin() |
Checks if user has admin privileges |
trigger_auto_calculate_match_score: Automatically calculatesmatch_scorebefore insert/update onmatch_reportstrigger_auto_recalculate_stats: Automatically updatesrobot_statsafter any change tomatch_reportson_auth_user_created: Createsuser_profilesentry when new user signs up
RLS policies control data access:
- Public read for match data, pit data, and statistics
- Authenticated write for scouts submitting data
- Admin-only access for user management and configuration
- User isolation for profile data (users can only see their own profile)
π Complete Setup Guide: See Frontend Setup Guide for detailed installation instructions including:
- Installing Node.js, Git, and development tools
- Setting up iOS Simulator or Android Emulator
- Configuring Expo Go on your phone
- Database setup and configuration
- Troubleshooting common issues
Assumes you already have:
- β Node.js 20+ installed
- β Git installed
- β Repository cloned
- β
Dependencies installed (
npm installalready run) - β
.envfile configured with Supabase credentials
Start the app:
cd Frontend_2025_Scouting
./start_app.shThe startup script will:
- β Check your development environment
- β Verify dependencies are installed
- β Confirm
.envconfiguration - β Start the Expo development server
Options:
./start_app.sh --tunnel # Use tunnel mode for network issues
./start_app.sh --clear # Clear cache before starting
./start_app.sh --help # Show all optionsOpen the app:
- Phone: Scan the QR code with Expo Go (iOS | Android)
- Simulator/Emulator: Press
ifor iOS orafor Android - Web Browser: Press
wfor web version
First Time?
- Sign up with your email
- Ask your team lead for admin access (if needed)
- Start scouting!
Need the .env file? Contact your team lead for Supabase credentials.
- Frontend Setup Guide β - Complete installation and setup instructions
- Supabase Setup Guide - Database setup and initialization
- iOS Simulator Setup - Setting up iOS Simulator on Mac
- Android Emulator Setup - Setting up Android Emulator
- Physical Device Setup - Running on your phone/tablet
-
Create a feature branch
git checkout -b feature/your-feature-name
-
Make your changes
- Follow existing code style
- Add comments for complex logic
- Update documentation as needed
-
Test your changes
- Test on both iOS and Android
- Test offline functionality
- Test with and without admin privileges
-
Commit your changes
git add . git commit -m "Description of changes"
-
Push to remote
git push -u origin feature/your-feature-name
-
Create a Pull Request
- Describe your changes
- Link any related issues
- Request review from team members
- Use TypeScript for type safety
- Follow React hooks best practices
- Use async/await for asynchronous code
- Add JSDoc comments for complex functions
- Keep components small and focused
- Use meaningful variable names
main- Current development branch (v2.1.0)version2- Used for major refactoring and removal of node.js backend (archived)feature/*- New featuresbugfix/*- Bug fixesdocs/*- Documentation updates
This project is licensed under the MIT License.
Developed by: FRC Team 589 - Falkons Season: 2025 REEFSCAPE Organization: Cresenta Valley High School
- FIRST Robotics Competition for the game design
- Supabase for the backend infrastructure
- Expo team for the development platform
- All team members who contributed to testing and feedback
For questions, issues, or contributions:
- GitHub Issues: Report a bug or request a feature
- Team Contact: Contact FRC Team 589 through FIRST website
- Documentation: Check the
Docs/folder for detailed guides
- β Team Starring System: User-specific favorites (yellow stars) and admin flags (blue stars)
- β Persistent Stars: Stars sync across leaderboard and all team detail pages
- β Admin Star Features: Double-tap to set blue stars visible to all users
- β Database Integration: Star tables and functions added to core schema
- β Optimized Setup: Streamlined Supabase initialization to 6 sequential scripts
- β Enhanced Documentation: Completely updated setup guides with verification steps
- β Complete refactoring to use database-driven competition names
- β Removed hardcoded competition codes
- β Added CompetitionContext for dynamic competition switching
- β Improved offline support with upload queue
- β Added authentication and user management
- β New admin panel for competition and user management
- β Enhanced UI with swipe navigation and modern design
- β Comprehensive documentation and setup guides
- Initial release
- Basic match and pit scouting functionality
- Supabase integration
- Core data visualization
Built with β€οΈ by FRC Team 589 for the 2025 REEFSCAPE season