Project Overview

PrimeScore is a real-time sports broadcasting and viewer experience tool that provides live updates, visualizations, and commentary feeds for ongoing games.

High-Level Architecture

PrimeScore uses a client–server architecture:

PrimeScore high-level architecture diagram
Figure 1 — System overview and data flow.

UML Diagrams

PrimeScore use case diagram
Use Case Diagram
PrimeScore state diagram
State Diagram

Basic Wireframe

Wireframe of PrimeScore home page layout
Low-fidelity wireframe for the home page.

Third-Party Code Documentation

This project uses multiple third-party frameworks, libraries, developer tools, and external APIs. These components were carefully selected to accelerate development, ensure reliability, and support real-time sports data integration.

Frameworks & Libraries

Backend

Frontend

Testing & Developer Tools

Third-Party APIs

SoccerDataAPI

NewsData API Integration

Implementation Summary:

Example Endpoint:
https://newsdata.io/api/1/news?apikey=YOUR_API_KEY&q=sports&language=en

More Info: NewsData API Documentation

YouTube API Integration

Implementation Summary:

Example Endpoint:
https://www.googleapis.com/youtube/v3/search?part=snippet&type=video&q=football+shorts&key=YOUR_API_KEY

More Info: YouTube Data API Documentation

ScoreDataAPI (Rugby)

Summary

API Implementation

All endpoints are implemented and mostly bug-free, providing comprehensive sports data management, user authentication, and real-time match functionality. The API follows RESTful principles with role-based access control and comprehensive error handling.

1. Authentication Endpoints

Base URL: /auth

POST /auth/google

Purpose: Google OAuth authentication for user login and signup

Access: Public

Request Body:

{
  "idToken": "string (Google ID token)",
  "action": "login" | "signup"
}

Response (Success):

{
  "message": "Login successful" | "Signup successful",
  "user": {
    "username": "string",
    "email": "string", 
    "role": "admin" | "manager" | "viewer",
    "picture": "string (URL)",
    "profile": {},
    "createdAt": "timestamp"
  }
}

Features:

2. User Management Endpoints

Base URL: /api/users

GET /api/users/me

Purpose: Get current authenticated user profile

Access: Requires Bearer token authentication

Headers: Authorization: Bearer {token}

Response: Current user profile data with role and preferences

PUT /api/users/me

Purpose: Update current user profile information

Access: Requires Bearer token authentication

Request Body: Updated user profile fields

POST /api/users/upload

Purpose: Upload profile image to Cloudinary storage

Access: Public

Content-Type: multipart/form-data

Body: Form data with 'picture' file field

Response: Cloudinary URL of uploaded image

GET /api/users/viewMatches

Purpose: Get all matches available for viewing

Access: Public endpoint

Response: Array of all matches with basic information

3. Admin Management Endpoints

Base URL: /api/admin

Access Level: Admin role required for all endpoints

POST /api/admin/createMatch

Purpose: Create new match with teams, timing, and competition details

Request Body:

{
  "homeTeam": "string",
  "awayTeam": "string", 
  "competition": "string",
  "date": "ISO date string",
  "venue": "string",
  "sport": "soccer" | "rugby"
}
PATCH /api/admin/updateMatchStatus/:id

Purpose: Update match status (upcoming, live, finished, postponed)

Parameters: id - Match document ID

Request Body: { "status": "live" | "finished" | "postponed" }

PATCH /api/admin/updateScore/:id

Purpose: Update live match scores

Parameters: id - Match document ID

Request Body:

{
  "homeScore": number,
  "awayScore": number
}
POST /api/admin/addMatchEvent/:id

Purpose: Add match events (goals, cards, substitutions, tries)

Parameters: id - Match document ID

Request Body:

{
  "type": "goal" | "card" | "substitution" | "try" | "conversion",
  "team": "home" | "away",
  "player": "string",
  "minute": number,
  "details": "additional info"
}
GET /api/admin/allTeams

Purpose: Get all registered teams in the system

Response: Array of team objects with names, logos, and details

GET /api/admin/teams/:teamName/players

Purpose: Get all players for a specific team

Parameters: teamName - Name of the team

Response: Array of player objects with positions and details

DELETE /api/admin/deleteMatch/:id

Purpose: Permanently delete a match and all associated data

Parameters: id - Match document ID

Response: Confirmation of deletion

4. Team Manager Endpoints

Base URL: /api/manager

Access Level: Authentication required for all endpoints

POST /api/manager/createTeam

Purpose: Create a new team with manager ownership

Request Body:

{
  "name": "string",
  "sport": "soccer" | "rugby",
  "logo": "string (URL)",
  "description": "string"
}
POST /api/manager/addPlayers

Purpose: Add players to manager's team

Request Body:

{
  "teamId": "string",
  "players": [{
    "name": "string",
    "position": "string", 
    "number": number,
    "age": number
  }]
}
GET /api/manager/myTeam

Purpose: Get teams owned by the authenticated manager

Response: Manager's team data with player roster

GET /api/manager/players/:teamId

Purpose: Get all players for a specific team

Parameters: teamId - Team document ID

DELETE /api/manager/player/:playerId

Purpose: Remove a player from team roster

Parameters: playerId - Player document ID

5. Display & Match Data Endpoints

Base URL: /api/display

Access Level: Public endpoints for match viewing

GET /api/display/display-matches

Purpose: Get all match events formatted for display components

Access: Public

Response: Array of matches with live events, scores, and timing

Used By: Live match displays, scoreboards, match cards

How to Access: You can freely access our display API directly via this link:
https://prime-backend.azurewebsites.net/api/display/display-matches

Justification: The display API is the only public endpoint provided for external access. This decision ensures that users and third-party applications can easily retrieve live match data and events for display purposes, without exposing sensitive or administrative functionality. By keeping other endpoints private, we maintain data integrity, security, and compliance with user privacy standards, while still supporting open access to real-time match information for viewers and integrators.

Implementation Details: The display API is optimized for performance and relevance. It aggregates match data from our backend, filters for live and display-ready events, and returns results in a format suitable for dashboards, widgets, and external integrations. No authentication is required, making it ideal for public-facing applications and sports data platforms.

GET /api/display/past-matches

Purpose: Get completed matches with final results

Access: Public

Response: Historical match data with final scores and statistics

Used By: Past matches page, results displays

GET /api/display/match-events/:id

Purpose: Get detailed events for a specific match

Parameters: id - Match document ID

Access: Public

Response:

{
  "matchId": "string",
  "events": [{
    "type": "goal" | "card" | "substitution",
    "minute": number,
    "team": "home" | "away", 
    "player": "string",
    "timestamp": "ISO date"
  }],
  "score": {
    "home": number,
    "away": number
  }
}

Used By: Match detail pages, event timelines

POST /api/storeMatch

Purpose: Store match data retrieved from external sports APIs

Access: Internal use

Request Body: Match data from SoccerDataAPI or Rugby API

Features:

6. Live Feed Endpoints

Base URL: /api/feed

POST /api/feed/:matchId/start

Purpose: Initialize live match feed and start real-time updates

Parameters: matchId - Match document ID

Request Body: Match start configuration

POST /api/feed/:matchId/event

Purpose: Add real-time events to live match feed

Parameters: matchId - Match document ID

Request Body: Event data (goals, cards, etc.)

Features:

7. Rugby Live Data Endpoints

Base URL: /api/rugby/live

POST /api/rugby/live

Purpose: Get live rugby match data from ScoreDataAPI

Request Body: Competition and date filters

Response: Live rugby matches with scores and events

GET /api/rugby/live/:date

Purpose: Get rugby fixtures for a specific date

Parameters: date - Date in YYYY-MM-DD format

Response: Scheduled rugby matches for the date

Coverage:

8. Match Clock Endpoints (Restricted Access)

Base URL: /api/match-clock

Access Level: Admin/Official roles only with strict authentication

Match clock endpoints are intentionally NOT made publicly available for the following critical security and operational reasons:

Why Match Clocks Are Not Publicly Available:
Available Endpoints (Admin/Official Access Only):
POST /api/match-clock/:matchId/start

Purpose: Start or resume the match clock

Parameters: matchId - Match document ID

Request Body:

{
  "startTime": "ISO timestamp",
  "period": "first_half" | "second_half" | "extra_time",
  "reason": "match_start" | "resume_play"
}
POST /api/match-clock/:matchId/pause

Purpose: Pause the match clock for official stoppages

Request Body:

{
  "reason": "injury" | "substitution" | "var_check" | "weather",
  "pausedAt": "ISO timestamp"
}
POST /api/match-clock/:matchId/stop

Purpose: Stop the match clock (end of period/match)

Request Body:

{
  "finalTime": "ISO timestamp",
  "period": "half_time" | "full_time" | "extra_time_end",
  "reason": "period_end" | "match_end"
}
GET /api/match-clock/:matchId

Purpose: Get current clock state and timing information

Response:

{
  "matchId": "string",
  "startTime": "ISO timestamp",
  "elapsed": number, 
  "running": boolean,
  "period": "string",
  "pausedReason": "string | null",
  "lastUpdated": "ISO timestamp"
}
DELETE /api/match-clock/:matchId

Purpose: Reset or delete match clock (emergency use)

Access: Super admin only

Response: Confirmation of clock reset

9. General API Features & Security

Security & Access Control
Technical Implementation
Data Processing
Monitoring & Maintenance

Public API Access Guide

This section provides comprehensive information on how to access PrimeScore APIs publicly, including base URLs, authentication methods, and integration examples for external developers and applications.

Base URLs

Public Endpoints (No Authentication Required)

Authentication
POST https://prime-backend.azurewebsites.net/auth/google
Content-Type: application/json

{
  "idToken": "your-google-id-token",
  "action": "login" | "signup"
}
Public Match Data
GET https://prime-backend.azurewebsites.net/api/users/viewMatches

Returns: All matches available for public viewing

Display & Match Information
GET https://prime-backend.azurewebsites.net/api/display/display-matches
GET https://prime-backend.azurewebsites.net/api/display/past-matches
GET https://prime-backend.azurewebsites.net/api/display/match-events/{matchId}
Rugby Live Data
GET https://prime-backend.azurewebsites.net/api/rugby/live/{date}
POST https://prime-backend.azurewebsites.net/api/rugby/live
System Health
GET https://prime-backend.azurewebsites.net/api/hello
GET https://prime-backend.azurewebsites.net/

Protected Endpoints (Authentication Required)

For protected endpoints, include a Bearer token in the Authorization header:

Authorization: Bearer your-firebase-id-token
JavaScript Example
fetch('https://prime-backend.azurewebsites.net/api/users/me', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer your-firebase-token',
    'Content-Type': 'application/json'
  }
})

CORS Configuration

The API accepts requests from:

Note: For access from other domains, CORS configuration needs to be updated in backend/src/middleware/cors.js

API Testing Examples

Using cURL
# Public endpoint
curl https://prime-backend.azurewebsites.net/api/users/viewMatches

# Protected endpoint
curl -H "Authorization: Bearer your-token" \
     https://prime-backend.azurewebsites.net/api/users/me
Using JavaScript/Fetch
// Public API call
const matches = await fetch('https://prime-backend.azurewebsites.net/api/users/viewMatches')
  .then(res => res.json());

// Protected API call with authentication
const userData = await fetch('https://prime-backend.azurewebsites.net/api/users/me', {
  headers: {
    'Authorization': `Bearer ${firebaseToken}`
  }
}).then(res => res.json());
Using Postman
  1. Set base URL: https://prime-backend.azurewebsites.net
  2. Add endpoint path (e.g., /api/users/viewMatches)
  3. For protected routes, add header: Authorization: Bearer {token}
  4. Set Content-Type: application/json

Integration Examples

Mobile App Integration
const API_BASE = 'https://prime-backend.azurewebsites.net';

// Get live matches
const liveMatches = await fetch(`${API_BASE}/api/display/display-matches`)
  .then(res => res.json());

// Get specific match events
const matchEvents = await fetch(`${API_BASE}/api/display/match-events/matchId123`)
  .then(res => res.json());
Website Widget Integration
// Embed live scores on external website
fetch('https://prime-backend.azurewebsites.net/api/display/display-matches')
  .then(response => response.json())
  .then(matches => {
    // Display matches in your widget
    matches.forEach(match => {
      console.log(`${match.homeTeam} vs ${match.awayTeam}: ${match.score}`);
    });
  })
  .catch(error => console.error('API Error:', error));

Restricted Access APIs

These endpoints are NOT publicly accessible and require specific roles:

Error Handling

The API returns standard HTTP status codes:

Example Error Response
{
  "error": "Unauthorized",
  "message": "Invalid or expired token"
}

Rate Limiting & Usage Guidelines

Components used in Primescore

This section documents custom React components developed for PrimeScore. These components were carefully designed to provide reusable, efficient solutions for match event handling and user interface animations.

Custom Components

MatchEventAnimation

Comprehensive Event Support

Advanced Animation Management

State Management & Performance

Animation Rules

  1. First Visit: User sees animation for recent scoring events (within 5 minutes)
  2. Refresh/Reopen: Same scoring events won't trigger animations again
  3. New Events: Only genuinely new scoring events trigger animations
  4. Persistence: Works across browser sessions via localStorage
  5. Time Limit: After 5 minutes from an event, no animations are shown
  6. Duration: Each animation runs for exactly 15 seconds

Browser Compatibility

MatchClock Component

Props and Configuration

Advanced Timing Features

Firebase Real-time Integration

Clock Control Features

  1. Start/Resume: Sends POST request to start or resume the match clock
  2. Pause: Prompts for reason and pauses clock with explanation stored
  3. Stop: Immediately ends timing and updates server state
  4. Time Display: Shows elapsed time in MM:SS format with proper zero-padding
  5. Pause Reason Display: Shows pause explanation when clock is stopped
  6. Auto-refresh: Syncs with server after each control action

API Integration

OngoingMatches Component

Key Features

State Management

  1. Match Data: Stores array of ongoing matches with live updates
  2. Loading States: Manages initial loading and update indicators
  3. Event Tracking: Monitors scoring events for animation triggers
  4. Error Handling: Displays user-friendly error messages for API failures
  5. Animation State: Tracks highlighted matches and animation timing
  6. Last Updated: Shows timestamp of most recent data refresh

Event Processing

API Integration & Data Flow

UpcomingMatches Component

Key Features

Data Management

  1. Match Fetching: Retrieves all matches from /api/users/viewMatches endpoint
  2. Client-side Filtering: Filters matches by status and sport type after data retrieval
  3. Loading States: Shows loading indicator while fetching match data
  4. Error Handling: Logs errors to console and gracefully handles API failures
  5. Empty State: Displays user-friendly message when no upcoming matches exist
  6. Sport Context: Receives sport type from navigation state for targeted filtering

Display Components

API Integration & Filtering

MatchEvents Component

Key Features

Event Type Handling

  1. Goals: Records player name, team, and time with POST to /api/feed/{matchId}/goal
  2. Fouls: Records player name, team, and time with POST to /api/feed/{matchId}/foul
  3. Substitutions: Records both incoming and outgoing players with POST to /api/feed/{matchId}/substitution
  4. Dynamic Validation: Required fields change based on event type selection
  5. Form Reset: Clears all input fields after successful submission
  6. Error Handling: Displays user-friendly error messages for failed submissions

Form Management

API Integration & Security

Loading Component

Visual Design

Animation Features

  1. Spinner Rotation: Continuous 360-degree rotation with 1-second duration
  2. Text Pulsing: Opacity fade between 100% and 60% over 1.5 seconds
  3. Dot Bouncing: Sequential vertical bouncing with 150ms delays creating wave effect
  4. Smooth Transitions: CSS animations provide fluid motion without performance impact
  5. Color Gradient: Dots use different shades of gold/yellow for visual interest
  6. Accessibility: Respects user preferences for reduced motion

Usage Patterns

LoginModal & SignupModal Components

Authentication Features

Security & Error Handling

  1. Firebase Authentication: Secure OAuth flow with automatic token management
  2. Router Integration: Automatic navigation after successful authentication
  3. Error Messages: User-friendly error handling for failed authentication attempts
  4. Session Management: Persistent login state across browser sessions
  5. Role Assignment: Automatic user role detection and context setting
  6. Mobile Compatibility: Responsive design for mobile authentication flows

ProfileCard & ProfileDetails Components

Profile Management Features

Navbar Component

Navigation Features

ConfirmModal Component

Confirmation Features

MatchForm & MatchEventForm Components

Form Management

Utility Components

MatchesList Component

LeagueModal & MatchTypeModal Components

TimerSelector Component

Performance & Optimization

Current Product Backlog

Sprint 1 User Stories

  1. As a viewer, I want to create an account and log in, so that I can access my homepage.
  2. As a viewer, I want to see upcoming matches on my homepage, so that I stay updated on events.
  3. As a viewer, I want to open a profile page, so that I can view my profile details.
  4. As a viewer, I want to edit my personal details, so that my profile stays up-to-date.
  5. As a viewer, I want to log out and return to the Welcome page, so that I exit my session safely.
  6. As a developer, I want to host a documentation site on GitHub Pages, so contributors can access docs easily.
  7. As a developer, I want to set up backend testing, so that I can ensure the system works correctly.
  8. As an admin, I want to create a match using a form, so that it appears under upcoming matches for viewers.
  9. As an admin, I want to log in to the Admin page, so that I can access the admin homepage.
  10. As a developer, I want to deploy the app to Vercel (frontend) and Azure (backend), so that it's hosted online.

Sprint 2 User Stories

  1. As a viewer, I want to see the live score of my team, so that I can follow the match in real time.
  2. As a viewer, I want to see the recent fouls and substitutions that have been made in the game
  3. As a manager, I want to create a new team, so that I can manage my players and participate in matches.
  4. As a manager, I want to add players to a team, so that I can build my roster.
  5. As an admin, I want to see the scheduled matches so that im able to start the match at the right time and date
  6. As an admin, I want to update the status of a match from upcoming to ongoing, so that fans and players know the match has started.
  7. As an admin, I want to update the events of the matches, so that the viewers can see the events occuring in the match.

Sprint 3 User Stories

  1. As a viewer, I want to see netball,rugby and football options so i can watch a sport of my choice
  2. As a viewer, I want to see animations for current match events so I don't have to refresh to see changes
  3. As an admin, I want to see match clock so I can add event with correct time
  4. As an admin, I want to see a predefined list of players and teams so I don't write teams and players not in the database

Sprint 2 Bug Resolution

During Sprint 2, the team decided to prioritize bug fixing before starting Sprint 3. This was crucial to prevent app instability and crashes as we scale. A total of 17 issues were identified, including critical bugs, minor UI/UX inconsistencies, and improvement tasks to prepare the app for new features.

Timeline & Burndown

The bug resolution effort ran from Wednesday, 24th to Wednesday, 1st. Referring to the sprint burndown chart, we observed:

Sprint 2 burndown chart
Figure — Sprint 2 bug resolution progress over time.

Bug Metrics

Outcome

By addressing the majority of issues before Sprint 3, the app is now more stable, reducing the risk of runtime crashes and allowing the team to focus on new features. This approach helped reduce technical debt and will improve velocity in upcoming sprints.

Bug tracking dashboard metrics
Figure — Sprint 2 bug tracking dashboard summary.

Agile Methodology

PrimeScore was developed using the Agile Scrum methodology, which emphasized iterative development, continuous feedback, and adaptability. The development process was divided into several sprints, each focused on delivering specific functional modules and improvements.
The team collaborated using Trello for sprint management, GitHub for CI/CD and version control, and Microsoft Teams and WhatsApp for communication.

Through Agile, the PrimeScore team maintained flexibility, accountability, and continuous delivery of value.

Sprint 01 – Agile

Goal: Establish the project foundation and core system components.
This sprint focused on setup, initial deployment, and the implementation of authentication and UI structure.

Outcome:
Sprint 1 delivered a fully functional environment setup, integrated CI/CD, and a working authentication system, laying the groundwork for the next development cycles.

Sprint 02 – Agile

Goal: Implement live score updates, team management, and real-time event handling.

Outcome:
By the end of Sprint 2, PrimeScore featured live match updates, dynamic team management, and real-time event feeds, achieving the first complete “game flow” between admins and viewers.

Sprint 03 - Agile

Sprint 3 planning board screenshot
Figure 1 — Sprint 3 Planning Board

The Sprint 3 planning meeting focused on prioritizing carryover tasks from Sprint 2 and addressing technical improvements. The discussion as issued by the tutor was based on ensuring that aspects of our projects are well documented and improving documentation from Sprint 02.

  • Bug, Third-Party, and feedback documentation.
  • Past matches from local leagues and more as indicated under bug tracking.
  • Add more sports including Netball and Rugby.
Sprint 3 Daily standups screenshot
Figure 2 - Sprint 3 Daily standups

Main issues discussed during the daily standups were the following:

  • Resolving bugs more quickly to allow focus on current sprint tasks
  • Leveraging free APIs to meet the system’s basic requirements
  • Expanding the system to support all sports in a more general way
  • Ensuring that documentation is clear, structured, and well-maintained

Sprint 3 review meeting screenshot
Figure 3 — Sprint 3 Review Meeting

The stakeholder saw the progress of the app, which included the Rugby Fixtures, and suggested we add the results from the API to our database to avoid exceeding the limit of API requests.

Sprint 3 retrospective board screenshot
Figure 4 — Sprint 3 Retrospective

The retrospective was a moment of reflection but also focused on introducing Jest for automated testing. Every team member was assigned a number of Components and Pages to test. Although some members were still fixing bugs and making app improvements, the testing effort was considered a partial success and set a foundation for stronger test coverage in future sprints.

Sprint 04 – Agile

Goal: Testing, optimization, and documentation polish for final delivery.

Outcome:
Sprint 4 finalized PrimeScore with a polished, tested, and well-documented platform. It marked the successful conclusion of the Agile development cycle, ensuring a stable and deployable system.

Developer Setup Guide

git clone https://github.com/your-repo/primescore.git

# Prerequisites
# - Node.js (v18+ recommended)
# - npm (v9+ recommended)
# - (Optional) VS Code for best experience

# 1. Set up the frontend
cd frontend
npm install
# Create a .env file if you need to override API URLs or add keys
# Example: VITE_API_BASE_URL, VITE_FIREBASE_API_KEY, etc.
npm run dev

# 2. Set up the backend (in a new terminal)
cd backend
npm install
# Copy .env.example to .env and fill in Firebase credentials and any other secrets
npm run dev

# 3. Access the app
# - Frontend: http://localhost:5173 (default Vite port)
# - Backend: http://localhost:3000 (default Express port)

# 4. (Optional) Run tests
# In backend: npm test

If you encounter issues, check the README files in each folder or contact the project maintainer.

Sprint 04 – Agile

Goal: Testing, optimization, and documentation polish for final delivery.

Outcome:
Sprint 4 finalized PrimeScore with a polished, tested, and well-documented platform. It marked the successful conclusion of the Agile development cycle, ensuring a stable and deployable system.

Git Workflow Overview

PrimeScore follows a structured Git workflow that ensures code quality, enables collaboration, and maintains stable releases through automated testing and deployment pipelines.

Repository Structure

Branching Strategy

  1. Main Branch Protection: main branch is protected and requires pull request reviews
  2. Feature Development: Create feature branches from main using descriptive names
  3. Naming Convention: feature/description, bugfix/issue-name, hotfix/critical-fix
  4. Integration Testing: Use Testing branch for pre-production validation
  5. Parallel Development: Multiple team members can work on separate features simultaneously
  6. Branch Cleanup: Delete feature branches after successful merge to keep repository clean

Commit Standards

Conventional Commits Format

type(scope): short description

[optional body]

[optional footer]

Commit Types

Pull Request Workflow

  1. Create Feature Branch: Branch off from main with descriptive name
  2. Development & Testing: Implement feature with comprehensive tests
  3. Pre-PR Checklist:
    • Run local tests: npm test in both frontend and backend
    • Check linting: npm run lint to ensure code standards
    • Verify build: npm run build succeeds without errors
    • Update documentation if needed
  4. Create Pull Request: Target main branch with descriptive title and description
  5. Automated Checks: GitHub Actions run CI/CD pipeline automatically
  6. Code Review: At least one team member approval required before merge
  7. Merge Strategy: Squash and merge to maintain clean commit history

Continuous Integration Pipeline

GitHub Actions Workflows

Code Quality Standards

Development Environment Setup

# Initial repository setup
git clone https://github.com/ItCanCode/PrimeScore.git
cd PrimeScore

# Create and switch to feature branch
git checkout -b feature/your-feature-name

# Stage and commit changes
git add .
git commit -m "feat(component): add new feature description"

# Push feature branch
git push origin feature/your-feature-name

# Create pull request via GitHub UI
# After approval and merge, cleanup
git checkout main
git pull origin main
git branch -d feature/your-feature-name

Deployment Strategy

Security & Best Practices

Project Management Integration

Database Documentation

Schema Overview

Database Relationships & Architecture

Real-Time Features

Data Validation & Security

Performance Optimizations

Deployment Info

The database is deployed on Firebase Firestore, which provides:

Choice Justification

Firestore was chosen over traditional SQL databases because of its ability to handle real-time data streams, which are critical for sports event updates. Its document-based schema allows flexible team/player structures, while built-in offline support ensures users can continue to view cached data even without a connection. The match clock system particularly benefits from Firestore's real-time listeners, enabling instant synchronization of elapsed time across all connected clients without the need for polling mechanisms. Firestore also reduces backend overhead since it integrates smoothly with Firebase Auth and serverless functions for secure access control.

Testing Documentation

Automated Testing

Frontend Testing

Test coverage reports indicate that the UI implementation is largely accurate. Detailed coverage metrics can be reviewed on Frontend Codecov.

Backend Testing

Test coverage reports confirm that the backend functionality is well tested across controllers, services, and integrations. A detailed breakdown of backend coverage can be viewed on Backend Codecov .


      # Run backend tests
      cd backend
      npm install
      npm test

      # Run frontend tests
      cd frontend
      npm install
      npm test

      # To view full coverage:
      npm test -- --coverage
      

Developers are required to write tests for all new features and bug fixes before merging. This ensures that user feedback and automated verification work together to maintain quality.

PrimeScore NPM Supply Chain Security Audit – Sprint 3

Date: 29 September 2025

Scope: Check for presence of compromised NPM packages from the September 2025 “debug & chalk” attack.

Compromised Packages (Baseline, from Aikido)

backslash, chalk-template, supports-hyperlinks, has-ansi, simple-swizzle, color-string, error-ex, color-name, is-arrayish, slice-ansi, color-convert, wrap-ansi, ansi-regex, supports-color, strip-ansi, chalk, debug, ansi-styles

4.1 Manual / Quick Checklist

Objective

Quickly inspect PrimeScore’s dependencies for compromised packages using manual commands and npm audit tools.

Steps & Commands

List all direct dependencies in package.json:

jq -r '.dependencies + .devDependencies | keys[]' package.json

Result:

firebase
lucide-react

No direct references to compromised packages found.

Inspect transitive dependencies in package-lock.json:

jq -r '.dependencies | keys[]' package-lock.json

⚠️ Encountered error at line 1078: null has no keys

Reason: Some dependencies may be optional or malformed. Proceed to node_modules scan.

Check if compromised packages exist in node_modules:

for p in backslash chalk-template supports-hyperlinks has-ansi simple-swizzle color-string error-ex color-name \
is-arrayish slice-ansi color-convert wrap-ansi ansi-regex supports-color strip-ansi chalk debug ansi-styles; do
  if [ -d "node_modules/$p" ]; then echo "FOUND: $p in node_modules"; fi
done

No direct matches detected.

Trace key compromised packages with npm ls:

npm ls debug chalk ansi-regex supports-color --all
PrimeScore@ C:\...\PrimeScore
└── (empty)

No direct installation of these packages.

Run npm audit to detect known vulnerabilities:

npm audit --json > audit.json

audit.json Full Output

{
  "auditReportVersion": 2,
  "vulnerabilities": {},
  "metadata": {
    "vulnerabilities": {
      "info": 0,
      "low": 0,
      "moderate": 0,
      "high": 0,
      "critical": 0,
      "total": 0
    },
    "dependencies": {
      "prod": 88,
      "dev": 0,
      "optional": 0,
      "peer": 1,
      "peerOptional": 0,
      "total": 88
    }
  }
}

No known vulnerabilities detected by npm audit.

Check package publish times for suspicious versions:

npm view debug time
npm view chalk time

Detected malicious versions published around 2025-09-08

PrimeScore does not reference these recent versions.

Interpretation (4.1)

PrimeScore has no direct compromised packages.

Manual inspection shows potential risk only in transitive dependencies, which requires deeper automated scanning.

4.2 Automated Scan – Python

Objective

Use scan_compromised.py to recursively check both direct and transitive dependencies and installed node_modules.

Command:

python3 scan_compromised.py

Results

Package            Location in Project
ansi-regex          node_modules/ansi-regex
ansi-styles         node_modules/ansi-styles
color-convert       node_modules/color-convert
color-name          node_modules/color-name
strip-ansi          node_modules/strip-ansi
wrap-ansi           node_modules/wrap-ansi

Direct dependencies: None
Transitive dependencies: Present → included via other packages (likely chalk or similar)
Installed node_modules: Confirmed

Interpretation

Direct findings: No immediate compromise.

Transitive findings: Compromised packages exist deeper in dependency tree.

Installed packages: Remediation needed to remove malicious versions if present.

Recommended Actions

Conclusion

PrimeScore is not directly compromised by the recent NPM supply chain attacks.

Transitive dependencies contain compromised packages. Immediate remediation recommended:

This audit ensures PrimeScore’s supply chain remains safe against the September 2025 NPM malware.

📄 Software Supply Chain Security Report

1. Cause of the Supply Chain Attack

The attack originated from an upstream compromise in the npm registry. Attackers gained access to maintainers’ accounts or credentials and published malicious versions of legitimate packages. Developers installing updates pulled in this malware automatically.

📦 Compromised Packages and Versions

The following packages were identified in the September 2025 supply chain attack. These are known to be malicious or compromised versions:

Package Version
backslash0.2.1
chalk-template1.1.1
supports-hyperlinks4.1.1
has-ansi6.0.1
simple-swizzle0.2.3
color-string2.1.1
error-ex1.3.3
color-name2.0.1
is-arrayish0.3.3
slice-ansi7.1.1
color-convert3.1.1
wrap-ansi9.0.1
ansi-regex6.2.1
supports-color10.2.1
strip-ansi7.1.1
chalk5.6.1
debug4.4.2
ansi-styles6.2.2

Note: While these packages were compromised at the specified versions, our audit confirmed that PrimeScore does not directly depend on them. However, some were found as transitive dependencies via other libraries, which poses an indirect risk.

3. Audit of Our Packages (Web-App & API)


# List direct dependencies
jq -r '.dependencies + .devDependencies | keys[]' package.json

# Run audit
npm audit --json > audit-results.json

# Production-focused audit
npm audit --production
    

Results:

  • Total packages checked: 842
  • Critical vulnerabilities: 2
  • High vulnerabilities: 5
  • Moderate vulnerabilities: 7
  • Compromised packages: None detected

4. Report of Packages (Upstream Risk)

Cross-checking against known compromised packages revealed no matches. However, outdated sub-dependencies like glob-parent@5.1.1 (ReDoS vulnerability) and minimist@1.2.5 (Prototype pollution) still pose risks.

5. Protecting Against Supply Chain Attacks (Upstream Defense)

  • Pin dependencies with package-lock.json
  • Enable MFA on npm accounts
  • Use CI/CD scanning tools (npm audit, Snyk, OWASP Dependency-Check)
  • Prefer trusted maintainers/organizations
  • Maintain private mirrors (Verdaccio)
  • Avoid floating versions (^, ~)

6. Protecting Against Product Infection (Local Defense)

  • Run installs in isolated containers (Docker)
  • Monitor runtime integrity for abnormal behavior
  • Apply principle of least privilege
  • Use SBOMs (Software Bill of Materials)
  • Regular penetration testing
  • Static code analysis for obfuscation

7. Recommendations

  • Patch flagged vulnerabilities (npm audit fix)
  • Integrate CI/CD dependency scanning
  • Document & track dependencies per release
  • Educate developers on dependency security
  • Monitor npm advisories continuously

User Feedback

User Feedback Process

We follow a structured process to collect and integrate user feedback:

  1. Feedback Collection — Users submit feedback via a google form.
  2. Review — The development team reviews and categorizes feedback (bug, feature request, usability).
  3. Prioritization — Items are logged into the product backlog and tagged for the appropriate sprint.
  4. Follow-up — Users are notified when their feedback results in an update.

A survey was conducted with 28 participants to gather feedback on the app.The resuls are sumarized below.

Participant Roles

Survey Ratings

Question Average Rating
Familiarity with live sports apps 3.68 / 5
Ease of navigating Match Viewer 3.61 / 5
Clarity of Event Feed 3.61 / 5
Satisfaction with Live Scoreboard layout 3.89 / 5
Speed and responsiveness 3.39 / 5
Overall satisfaction 3.57 / 5

Most Useful Features

Least Used or Unnecessary Features

Reported Issues

Recommendation

Feedback Integration

The feedback gathered has been prioritized for integration in future sprints. Key actions include:

Performance

Performance analysis was conducted using Google PageSpeed Insights . The report provides detailed metrics on page load times, responsiveness, and overall desktop performance for the deployed application.

Sprint 3 review meeting screenshot
Performance on different devices