Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
eea199b
Add comprehensive unit testing framework
a1ly404 Sep 18, 2025
3fa988b
feat: Improve test coverage from 63.11% to 85.24%
a1ly404 Sep 18, 2025
2889244
refactor: Eliminate code duplication and improve test quality
a1ly404 Sep 18, 2025
d4b54a9
refactor: Replace hardcoded mock data with maintainable constants andโ€ฆ
a1ly404 Sep 18, 2025
c993106
Update package.json
a1ly404 Sep 18, 2025
4abf04d
Update src/test/Bouts.test.tsx
a1ly404 Sep 18, 2025
c644187
Update src/test/setup.ts
a1ly404 Sep 18, 2025
b1c518b
Update src/test/Players.test.tsx
a1ly404 Sep 18, 2025
d401a38
Update src/test/Navigation.test.tsx
a1ly404 Sep 18, 2025
303193d
Update package.json
a1ly404 Sep 18, 2025
b67c595
feat: improve createChainableQuery mock with state tracking
a1ly404 Sep 18, 2025
d538d89
refactor: replace magic numbers with constants and add Vercel Speed Iโ€ฆ
a1ly404 Sep 18, 2025
49ac44f
Update src/test/setup.ts
a1ly404 Sep 18, 2025
f1321bd
fix: resolve TypeScript interface mismatch in test setup
a1ly404 Sep 18, 2025
ea8f398
refactor: remove global useAuth mock to prevent test conflicts
a1ly404 Sep 18, 2025
af542b4
docs: update comprehensive test coverage report
a1ly404 Sep 18, 2025
8c609f1
fix: replace deprecated __dirname with ES module equivalent
a1ly404 Sep 18, 2025
709f9a8
Commit coverage html
a1ly404 Sep 18, 2025
140ecbb
Update src/test/setup.ts
a1ly404 Sep 18, 2025
d1cfdc3
Update src/test/setup.ts
a1ly404 Sep 18, 2025
8d6c0eb
Adding github actions to fail on failing tests
a1ly404 Sep 18, 2025
5303674
fix: resolve jsdom compatibility issues in CI environment
a1ly404 Sep 18, 2025
67a20dd
fix: update CI test script to use ES modules
a1ly404 Sep 18, 2025
69d8983
fix: migrate from jsdom to happy-dom for better CI compatibility
a1ly404 Sep 18, 2025
1fa0d5c
docs: add comprehensive testing documentation
a1ly404 Sep 18, 2025
1ebf158
fix: resolve Vitest reporter configuration issues
a1ly404 Sep 18, 2025
6bf16e8
Update .github/workflows/quality-gate.yml
a1ly404 Sep 18, 2025
144fe9f
Update .github/workflows/ci.yml
a1ly404 Sep 18, 2025
ee3f8c2
Standardize all GitHub Actions workflows to Node.js 22
a1ly404 Sep 18, 2025
06a763d
Merge branch 'dev' of https://github.com/a1ly404/derby-stat-tracker iโ€ฆ
a1ly404 Sep 18, 2025
29ec878
Fix GitHub Actions permission error in test-before-deploy workflow
a1ly404 Sep 18, 2025
2ff73e6
Update .github/workflows/test-before-deploy.yml
a1ly404 Sep 18, 2025
f053855
Update .github/workflows/quality-gate.yml
a1ly404 Sep 18, 2025
709f7f0
Update .github/workflows/ci.yml
a1ly404 Sep 18, 2025
443444b
Ran lint:fix
a1ly404 Sep 18, 2025
a1ce6dc
Update .github/workflows/quality-gate.yml
a1ly404 Sep 18, 2025
a9b5937
Merge branch 'main' into dev
a1ly404 Sep 18, 2025
98daccc
Optimize CI/CD pipeline: Use build artifacts instead of rebuilding
a1ly404 Sep 18, 2025
13d55f5
Potential fix for code scanning alert no. 1: Incomplete URL substringโ€ฆ
a1ly404 Sep 18, 2025
23f1305
Potential fix for code scanning alert no. 2: DOM text reinterpreted aโ€ฆ
a1ly404 Sep 18, 2025
983ae75
Potential fix for code scanning alert no. 3: DOM text reinterpreted aโ€ฆ
a1ly404 Sep 18, 2025
1b23718
Fix ESLint unused variable errors in test setup
a1ly404 Sep 18, 2025
0c910e3
Removing trailing whitespace
a1ly404 Sep 18, 2025
7da8997
Update .github/workflows/test-before-deploy.yml
a1ly404 Sep 18, 2025
1ec0b13
Update .github/workflows/quality-gate.yml
a1ly404 Sep 18, 2025
aeb70da
Update .github/workflows/ci.yml
a1ly404 Sep 18, 2025
3e5033f
Add Vercel preview deployment for dev branch
a1ly404 Sep 18, 2025
206837e
Fix Vercel GitHub Action reference
a1ly404 Sep 18, 2025
0881f51
Simplify Vercel deployment: Remove --prebuilt flag
a1ly404 Sep 18, 2025
e9597f3
Update .github/workflows/test-before-deploy.yml
a1ly404 Sep 18, 2025
e1dee16
Update .github/workflows/quality-gate.yml
a1ly404 Sep 18, 2025
87dec2a
Update .github/workflows/ci.yml
a1ly404 Sep 18, 2025
2895645
Fix CI workflow YAML formatting and missing test step
a1ly404 Sep 18, 2025
45c08bf
Fix YAML syntax error in test-before-deploy workflow
a1ly404 Sep 18, 2025
f0f48e9
Revert to amondnet/vercel-action for preview deployment
a1ly404 Sep 18, 2025
ae89de7
Fix preview deployment condition for pull requests
a1ly404 Sep 18, 2025
f8f802a
feat: Complete live derby stat tracking system with bout management
a1ly404 Sep 26, 2025
61aa7fa
refactor: Replace jarring page reload with smooth navigation
a1ly404 Sep 26, 2025
fb97f53
Merge pull request #6 from a1ly404/5-live-tracking
a1ly404 Sep 26, 2025
9e8e487
feat: Add database performance optimization scripts
a1ly404 Sep 26, 2025
93b92ad
Remove coverage folder
a1ly404 Sep 29, 2025
dd98b83
Merge branch 'main' into dev
a1ly404 Sep 29, 2025
56decdb
Respond to pr feedback
a1ly404 Sep 29, 2025
4de4fee
More pr feedback
a1ly404 Sep 29, 2025
d5c8808
Fix dupes on player ids
a1ly404 Sep 29, 2025
dbeb983
more pr feedback
a1ly404 Sep 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ dist-ssr
*.sw?
.env
*.tsbuildinfo
coverage/.tmp
coverage/*
!coverage/.tmp
2 changes: 2 additions & 0 deletions coverage/.tmp
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# This file keeps the coverage folder in git while ignoring all coverage reports
# Coverage reports are generated by running: npm run test:coverage
46 changes: 46 additions & 0 deletions database/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Database Scripts

This folder contains SQL scripts and database-related files for the Derby Stat Tracker application.

## Files

### `supabase-rls-performance-fixes.sql`

Comprehensive SQL script to fix Supabase performance issues identified by the database linter.

**Includes:**
- **RLS Performance Fixes** - Optimizes Row Level Security policies by wrapping `auth.uid()` calls in subqueries
- **Foreign Key Indexes** - Adds missing indexes on foreign key columns for better query performance

**How to use:**
1. Open your Supabase Dashboard
2. Navigate to the SQL Editor
3. Copy and paste the contents of this file
4. Execute the SQL commands

**Performance Benefits:**
- Eliminates RLS auth function re-evaluation per row (22 warnings fixed)
- Improves join performance with proper foreign key indexing (4 warnings fixed)
- Faster queries for live stat tracking operations
- Better performance when loading team rosters and bout data

**Tables Optimized:**
- `teams` - RLS policies and foreign key references
- `players` - RLS policies
- `player_teams` - RLS policies and team_id indexing
- `bouts` - RLS policies and team foreign key indexing
- `player_stats` - RLS policies and bout_id indexing

## Future Database Changes

When making database schema changes:
1. Add new SQL scripts to this folder
2. Use descriptive filenames with dates when relevant
3. Document the purpose and usage in this README
4. Test scripts in development before applying to production

## Development Notes

- These scripts are safe to run multiple times (uses `IF EXISTS` and `IF NOT EXISTS`)
- All changes maintain existing security policies while improving performance
- Foreign key indexes use standard naming convention: `idx_{table}_{column}`
133 changes: 133 additions & 0 deletions database/supabase-rls-performance-fixes.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
-- Supabase RLS Performance Fixes
-- Run these commands in your Supabase SQL editor to fix the auth RLS initialization plan warnings

-- Fix teams table RLS policies
DROP POLICY IF EXISTS "Allow authenticated users to view teams" ON public.teams;
DROP POLICY IF EXISTS "Allow authenticated users to insert teams" ON public.teams;
DROP POLICY IF EXISTS "Allow authenticated users to update teams" ON public.teams;
DROP POLICY IF EXISTS "Allow authenticated users to delete teams" ON public.teams;

CREATE POLICY "Allow authenticated users to view teams" ON public.teams
FOR SELECT USING ((SELECT auth.uid()) IS NOT NULL);

CREATE POLICY "Allow authenticated users to insert teams" ON public.teams
FOR INSERT WITH CHECK ((SELECT auth.uid()) IS NOT NULL);

CREATE POLICY "Allow authenticated users to update teams" ON public.teams
FOR UPDATE USING ((SELECT auth.uid()) IS NOT NULL);

CREATE POLICY "Allow authenticated users to delete teams" ON public.teams
FOR DELETE USING ((SELECT auth.uid()) IS NOT NULL);

-- Fix players table RLS policies
DROP POLICY IF EXISTS "Allow authenticated users to view players" ON public.players;
DROP POLICY IF EXISTS "Allow authenticated users to insert players" ON public.players;
DROP POLICY IF EXISTS "Allow authenticated users to update players" ON public.players;
DROP POLICY IF EXISTS "Allow authenticated users to delete players" ON public.players;

CREATE POLICY "Allow authenticated users to view players" ON public.players
FOR SELECT USING ((SELECT auth.uid()) IS NOT NULL);

CREATE POLICY "Allow authenticated users to insert players" ON public.players
FOR INSERT WITH CHECK ((SELECT auth.uid()) IS NOT NULL);

CREATE POLICY "Allow authenticated users to update players" ON public.players
FOR UPDATE USING ((SELECT auth.uid()) IS NOT NULL);

CREATE POLICY "Allow authenticated users to delete players" ON public.players
FOR DELETE USING ((SELECT auth.uid()) IS NOT NULL);

-- Fix player_teams table RLS policies
DROP POLICY IF EXISTS "Allow authenticated users to view player_teams" ON public.player_teams;
DROP POLICY IF EXISTS "Allow authenticated users to insert player_teams" ON public.player_teams;
DROP POLICY IF EXISTS "Allow authenticated users to update player_teams" ON public.player_teams;
DROP POLICY IF EXISTS "Allow authenticated users to delete player_teams" ON public.player_teams;

CREATE POLICY "Allow authenticated users to view player_teams" ON public.player_teams
FOR SELECT USING ((SELECT auth.uid()) IS NOT NULL);

CREATE POLICY "Allow authenticated users to insert player_teams" ON public.player_teams
FOR INSERT WITH CHECK ((SELECT auth.uid()) IS NOT NULL);

CREATE POLICY "Allow authenticated users to update player_teams" ON public.player_teams
FOR UPDATE USING ((SELECT auth.uid()) IS NOT NULL);

CREATE POLICY "Allow authenticated users to delete player_teams" ON public.player_teams
FOR DELETE USING ((SELECT auth.uid()) IS NOT NULL);

-- Fix bouts table RLS policies
DROP POLICY IF EXISTS "Allow authenticated users to view bouts" ON public.bouts;
DROP POLICY IF EXISTS "Allow authenticated users to insert bouts" ON public.bouts;
DROP POLICY IF EXISTS "Allow authenticated users to update bouts" ON public.bouts;
DROP POLICY IF EXISTS "Allow authenticated users to delete bouts" ON public.bouts;

CREATE POLICY "Allow authenticated users to view bouts" ON public.bouts
FOR SELECT USING ((SELECT auth.uid()) IS NOT NULL);

CREATE POLICY "Allow authenticated users to insert bouts" ON public.bouts
FOR INSERT WITH CHECK ((SELECT auth.uid()) IS NOT NULL);

CREATE POLICY "Allow authenticated users to update bouts" ON public.bouts
FOR UPDATE USING ((SELECT auth.uid()) IS NOT NULL);

CREATE POLICY "Allow authenticated users to delete bouts" ON public.bouts
FOR DELETE USING ((SELECT auth.uid()) IS NOT NULL);

-- Fix player_stats table RLS policies
DROP POLICY IF EXISTS "Allow authenticated users to view player_stats" ON public.player_stats;
DROP POLICY IF EXISTS "Allow authenticated users to insert player_stats" ON public.player_stats;
DROP POLICY IF EXISTS "Allow authenticated users to update player_stats" ON public.player_stats;
DROP POLICY IF EXISTS "Allow authenticated users to delete player_stats" ON public.player_stats;

CREATE POLICY "Allow authenticated users to view player_stats" ON public.player_stats
FOR SELECT USING ((SELECT auth.uid()) IS NOT NULL);

CREATE POLICY "Allow authenticated users to insert player_stats" ON public.player_stats
FOR INSERT WITH CHECK ((SELECT auth.uid()) IS NOT NULL);

CREATE POLICY "Allow authenticated users to update player_stats" ON public.player_stats
FOR UPDATE USING ((SELECT auth.uid()) IS NOT NULL);

CREATE POLICY "Allow authenticated users to delete player_stats" ON public.player_stats
FOR DELETE USING ((SELECT auth.uid()) IS NOT NULL);

-- Note: These fixes wrap auth.uid() in (SELECT auth.uid()) subqueries
-- This ensures the authentication check is evaluated once per query instead of once per row
-- This dramatically improves performance for queries that return multiple rows

-- =============================================================================
-- FOREIGN KEY INDEX PERFORMANCE FIXES
-- =============================================================================
-- These indexes improve performance for foreign key lookups and joins

-- Index for bouts.home_team_id foreign key
-- Improves performance when querying bouts by home team
CREATE INDEX IF NOT EXISTS idx_bouts_home_team_id ON public.bouts(home_team_id);

-- Index for bouts.away_team_id foreign key
-- Improves performance when querying bouts by away team
CREATE INDEX IF NOT EXISTS idx_bouts_away_team_id ON public.bouts(away_team_id);

-- Index for player_stats.bout_id foreign key
-- Improves performance when querying player stats by bout
-- This is particularly important for live stat tracking
CREATE INDEX IF NOT EXISTS idx_player_stats_bout_id ON public.player_stats(bout_id);

-- Index for player_teams.team_id foreign key
-- Improves performance when querying player-team relationships by team
-- This is important for loading team rosters
CREATE INDEX IF NOT EXISTS idx_player_teams_team_id ON public.player_teams(team_id);

-- Composite index for player_stats (bout_id, player_id)
-- Optimizes the common query pattern of getting specific player stats for a bout
CREATE INDEX IF NOT EXISTS idx_player_stats_bout_player ON public.player_stats(bout_id, player_id);

-- Composite index for player_teams (team_id, is_active)
-- Optimizes loading active players for a team (common in live tracking)
CREATE INDEX IF NOT EXISTS idx_player_teams_team_active ON public.player_teams(team_id, is_active);

-- Note: These indexes will significantly improve query performance for:
-- 1. Loading bout details with team information
-- 2. Fetching player stats for a specific bout (live tracking)
-- 3. Getting team rosters and active players
-- 4. Joining tables on foreign key relationships
24 changes: 20 additions & 4 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,31 @@ import Dashboard from './components/Dashboard'
import Teams from './components/Teams'
import Players from './components/Players'
import Bouts from './components/Bouts'
import LiveStatTracker from './components/LiveStatTracker'
import { Auth } from './components/Auth'
import { ConfigurationError } from './components/ConfigurationError'
import { useAuth } from './hooks/useAuth'
import { isSupabaseConfigured } from './lib/supabase'
import { Analytics } from "@vercel/analytics/react"
import { SpeedInsights } from '@vercel/speed-insights/react'


type ActiveView = 'dashboard' | 'players' | 'bouts' | 'teams' | 'settings'
import { ActiveView } from './types'

function App() {
const [activeView, setActiveView] = useState<ActiveView>('dashboard')
const [selectedBoutId, setSelectedBoutId] = useState<string | null>(null)

// Always call hooks first (React hooks rules)
const { user, loading } = useAuth()

const handleStartLiveTracking = (boutId: string) => {
setSelectedBoutId(boutId)
setActiveView('live-track')
}

const handleNavigateBackToBouts = () => {
setSelectedBoutId(null)
setActiveView('bouts')
}

// Check for configuration errors early - if Supabase is not configured, show error
if (!isSupabaseConfigured) {
Expand Down Expand Up @@ -49,8 +59,14 @@ function App() {
<main className="main-content">
{activeView === 'dashboard' && <Dashboard />}
{activeView === 'players' && <Players />}
{activeView === 'bouts' && <Bouts />}
{activeView === 'bouts' && <Bouts onStartLiveTracking={handleStartLiveTracking} />}
{activeView === 'teams' && <Teams />}
{activeView === 'live-track' && (
<LiveStatTracker
boutId={selectedBoutId}
onNavigateBack={handleNavigateBackToBouts}
/>
)}
{activeView === 'settings' && <div className="view-placeholder">Settings - Coming Soon</div>}
<Analytics />
<SpeedInsights />
Expand Down
Loading