Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/dreancaste/TriviaPP/llms.txt

Use this file to discover all available pages before exploring further.

TriviaPP is an Angular single-page application (SPA) wrapped by Ionic for its component library and by Capacitor for its native Android runtime. The app follows Angular’s injectable service pattern — all business logic, data fetching, and persistence is encapsulated in dedicated services, keeping page components thin and focused purely on presentation. Authentication is split across two systems: AWS Amplify (Cognito) handles identity and session tokens, while Firebase Firestore stores online leaderboard scores. Persistence is similarly split: localStorage handles all per-device data (profile, history, local ranking, stats), while Firestore handles the shared daily ranking visible to all players.

Service Layer

Each Angular service has a single, clearly defined responsibility. All services are provided at the root level (providedIn: 'root').

AuthService

Wraps the AWS Amplify Auth module and is the sole entry point for all identity operations in the app:
MethodAmplify functionDescription
register(email, password)signUpCreates a new Cognito user
confirmarRegistro(email, code)confirmSignUpVerifies the email confirmation code
login(email, password)signInSigns the user in and caches their email in memory
logout()signOutSigns the user out and clears the cached email
getCurrentUser()getCurrentUserReturns the currently authenticated Amplify user, or null
obtenerTokenJWT()fetchAuthSessionReturns the Cognito idToken JWT string for the current session

TriviaService

Generates trivia questions for each game round by combining two sources:
  • 60% lore questions — drawn from a curated bank of 19 static Star Wars lore questions (characters, events, factions). Questions already shown in the current session are tracked in usedQuestionKeys to prevent repeats.
  • 40% SWAPI questions — generated dynamically by calling SwapiService. Three question types are possible: character homeworld (generatePeopleQuestion), planet climate (generatePlanetQuestion), and film director (generateFilmQuestion). Planet climate answers are passed through TranslationService to translate them from English to Spanish before display.
If all lore questions have been used in the current session, usedQuestionKeys resets automatically and the pool refills.

SwapiService

A lightweight HTTP wrapper around the Star Wars API (https://swapi.py4e.com/api). All methods return Promises via RxJS firstValueFrom.
MethodEndpoint
getPeople(page)GET /people/?page={page}
getPerson(id)GET /people/{id}/
getPlanets(page)GET /planets/?page={page}
getPlanet(id)GET /planets/{id}/
getFilms()GET /films/
getFilm(id)GET /films/{id}/
getByUrl(url)GET {url} (follows SWAPI resource URLs, e.g. homeworld links)

StorageService

Manages all localStorage-backed persistence. The service defines five storage keys:
KeyTypeContents
sw_profileProfileDisplay name, avatar (base64), haptics preference
sw_historyHistoryItem[]All past game results, newest first
sw_rankingRankingItem[]Local top-20 leaderboard, sorted by score descending
sw_statsobjectLifetime stats: gamesPlayed, correctAnswers, maxScore
sw_ranking_reset_timetimestampUnix ms timestamp of the last local ranking reset
The local ranking automatically resets every 24 hours. On each read or write to the ranking, checkAndResetRanking() compares the current time against sw_ranking_reset_time. If more than 24 hours have elapsed, sw_ranking is cleared and the reset timestamp is updated.

RankingService

Reads and writes the online daily leaderboard stored in Firebase Firestore. Each score entry is a document in the ranking collection with three fields: name, score, and date (ISO date string, e.g. "2025-01-15").
MethodDescription
addScore(name, score)Adds a new document to the ranking collection with today’s date
getDailyRanking()Queries the collection ordered by score descending, then filters client-side to return only today’s entries

TranslationService

Calls the MyMemory Translation API (https://api.mymemory.translated.net) to translate English SWAPI text into Spanish (language pair en|es). The API has a query-length limit; TranslationService handles this automatically:
  • Texts of 450 characters or fewer are sent in a single request.
  • Texts longer than 450 characters are split into sentence-boundary-aware chunks via splitForApi(), each chunk is translated in parallel with Promise.all, and the results are joined back together.
If a request fails or the API returns a QUERY LENGTH LIMIT EXCEEDED error, the original English text is returned as a fallback.

WikiContentService

Drives the in-app Star Wars wiki by combining static configuration (section definitions, navigation structure, and references to visual guide assets stored under src/app/data/) with dynamic translation. It delegates translation to TranslationService and uses a local cache (translationCache) to avoid re-requesting the same strings. It also builds Star Wars Visual Guide image URLs (https://starwars-visualguide.com/assets/img/{type}/{id}.jpg) and generates fallback curiosity facts from raw SWAPI entity fields when no curated facts are available for a given entity.

External Integrations

ServicePurposeURL / SDK
SWAPILive Star Wars character, planet, and film datahttps://swapi.py4e.com/api
AWS Amplify / CognitoUser registration, email confirmation, login, session tokensaws-amplify npm package
Firebase FirestoreOnline daily leaderboardfirebase npm package
MyMemory Translation APITranslate SWAPI English answers to Spanishhttps://api.mymemory.translated.net
Capacitor CameraCapture and set the player’s profile photo@capacitor/camera
Capacitor HapticsVibrate the device when the player selects a wrong answer@capacitor/haptics

Authentication Flow

TriviaPP uses a two-step registration flow powered by AWS Amplify and Amazon Cognito:
  1. Register — The player submits their email and password on the register page. AuthService.register() calls Amplify signUp, which creates an unconfirmed Cognito user and sends a confirmation code to the player’s email.
  2. Confirm — The player enters the six-digit code on the confirmation screen. AuthService.confirmarRegistro() calls Amplify confirmSignUp. On success, the account is activated.
  3. Login — The player signs in with their email and password. AuthService.login() calls Amplify signIn. On success, Amplify stores a JWT session internally; AuthService also caches the email in memory for the current app session.
  4. Session checkAuthGuard calls AuthService.getCurrentUser() (which wraps Amplify getCurrentUser) on every navigation to a protected route. If no authenticated user is found, the guard redirects to /login.
  5. Token access — Any service that needs to make an authenticated API call can retrieve the Cognito idToken JWT string via AuthService.obtenerTokenJWT(), which wraps Amplify fetchAuthSession.

Data Persistence

TriviaPP uses two distinct persistence layers that serve different scopes:
DataStorageScopeReset cadence
Player profile (name, avatar, haptics setting)localStorage (sw_profile)Device-localNever (manual update only)
Game historylocalStorage (sw_history)Device-localNever (accumulates indefinitely)
Local ranking (top 20)localStorage (sw_ranking)Device-localAutomatic every 24 hours
Lifetime statslocalStorage (sw_stats)Device-localNever (accumulates indefinitely)
Online daily rankingFirebase Firestore (ranking collection)Shared across all playersNew entries each day; old entries remain but are filtered out client-side

Routing

All routes are defined in src/app/app-routing.module.ts using Angular’s lazy-loaded module pattern. The root path ("") redirects to login.
RouteModuleAuthGuardNotes
/loginLoginPageModule❌ NoEntry point for returning users
/registerRegisterPageModule❌ NoNew user registration and email confirmation
/homeHomePageModule✅ YesMain menu after login
/profileProfilePageModule✅ YesDisplay name, avatar, stats
/triviaTriviaPageModule✅ YesActive game session
/rankingRankingPageModule✅ YesOnline and local leaderboard
/historyHistoryPageModule✅ YesPast game results
/wikiWikiPageModule❌ NoStar Wars wiki (public)
All routes use PreloadAllModules as the preloading strategy, so Angular begins downloading lazy module bundles in the background immediately after the initial page load.
The /wiki route is intentionally not protected by AuthGuard. Players and visitors can browse Star Wars wiki content without creating an account or logging in. This is the only content section accessible without authentication.

Build docs developers (and LLMs) love