What you’ll learn: Every page, component, state slice, and API call in the EPIC frontend.
Prerequisite: Read Guides 06 and 07 first.


Section 1 β€” Frontend Overview

The EPICFrontend is a React app that serves as the UI for EPIC. Service owners, leaders, and EPIC operators use it to:

  • View and manage peak events
  • Configure fleets (ASGs, host counts, TPM projections)
  • Monitor readiness milestones
  • Track hardware orders (HOTW dashboard)
  • Configure throttling
  • Manage exceptions to standard capacity rules

Tech Stack:

  • React (component framework)
  • Redux Toolkit (global state)
  • Amazon Polaris (@amzn/awsui-components-react) β€” UI component library
  • Amazon Harmony (internal hosting + authentication)

Section 2 β€” Application Entry Points

index.js β€” App Bootstrap

// index.js starts the React app
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';  // wraps everything with Redux
import store from './store/store';
import Epic from './Epic';

ReactDOM.render(
    <Provider store={store}>  // makes Redux store available everywhere
        <Epic />              // main app component
    </Provider>,
    document.getElementById('root')
);

Epic.js β€” Root Component

Epic.js renders:
β”œβ”€β”€ Sticky Header
β”‚   β”œβ”€β”€ TopFlashbar (announcements from EPIC team)
β”‚   β”œβ”€β”€ AnnouncementFlashbar (general announcements)
β”‚   β”œβ”€β”€ EmergentAnnouncementFlashbar (urgent peak warnings)
β”‚   └── TopNavigationEpic (top nav bar with service selector)
β”œβ”€β”€ AppLayout (Polaris layout)
β”‚   β”œβ”€β”€ navigation β†’ SideNav (left sidebar navigation)
β”‚   β”œβ”€β”€ content β†’ MainContainer (current page content)
β”‚   └── tools β†’ TutorialPanel (right panel for tutorials)
└── Sticky Footer (SIM link for feedback)

Section 3 β€” Navigation Structure

Side Navigation (sideNav.jsx)

The left sidebar shows navigation options. Items change based on current page:

  • Home / Dashboard
  • Events
  • Services
  • HOTW Dashboard
  • BAU Dashboard
  • Action Dashboard
  • Developer Options

Top Navigation (topNavigation.jsx)

  • EPIC logo/home link
  • Service name selector (updates Redux state)
  • Region selector
  • Help button (opens helpModal.jsx)
  • User information from Harmony

Section 4 β€” All Pages in Detail

events.jsx β€” Events List Page

URL: /events What it shows: Table of all peak events (PD2024, BF2024, etc.) Actions: Create event button, click event to go to dashboard

// Key state:
const [events, setEvents] = useState([]);
const [isLoading, setIsLoading] = useState(true);

// Data fetch:
useEffect(() => {
    backend_api.getAllEvents()
        .then(response => setEvents(response.data));
}, []);

// Renders:
<eventsTable items={events} />  // see Section 10 for tables

service.jsx β€” Service Overview

URL: /service/:serviceName What it shows: Overview of one service β€” its fleets, settings, and summary stats

service.jsx shows:
β”œβ”€β”€ Service header (name, owner, type)
β”œβ”€β”€ Fleet list table (fleetsTable.jsx)
β”‚   β”œβ”€β”€ Each fleet row shows:
β”‚   β”‚   β”œβ”€β”€ Fleet ID
β”‚   β”‚   β”œβ”€β”€ Region
β”‚   β”‚   β”œβ”€β”€ Current host count
β”‚   β”‚   └── Peak ready status
β”‚   └── Click fleet β†’ goes to serviceDetails.jsx
└── Actions:
    β”œβ”€β”€ Add Fleet button
    β”œβ”€β”€ Service Preferences button
    └── Onboarding Checklist link

serviceDetails.jsx β€” Fleet Details (Most Complex Page) ⭐

URL: /serviceDetails/{serviceName}/{fleetId}/{eventId} What it shows: Everything about one fleet for one event β€” the central workspace

Tabs in serviceDetails:

Tab 1: Host Projections

  • Current host count in Apollo
  • Projected hosts needed for peak
  • BAU TPM, Peak TPM, CT Factor, Buffer Factor
  • FMC order status
  • Actions: Override TPM, Order Hosts, Dial Up/Down hosts
// hostProjectionTab.jsx renders:
<hostProjectionsTable
    fleetDetails={fleetDetails}
    eventId={eventId}
/>
// Also shows CapacityOverride section:
<scalingPlannerCapacityOverride
    asgList={asgList}
    overrides={overrides}
/>

Tab 2: Upstream Projections

  • Traffic coming FROM upstream services (dependencies)
  • Verify projections submitted by upstream teams
  • Mark projections as verified
// upstreamProjectionsTab.jsx renders:
<upstreamProjectionsTable />
<upstreamDownstreamSettingsTab />

Tab 3: Downstream Projections

  • Traffic pushed TO downstream services
  • Send your TPM projections to downstream services
  • Approve/reject projections received from upstream

Tab 4: Fleet Milestone Readiness

  • Checklist of all milestones for this fleet Γ— event
  • Each milestone shows: status, ETA, last updated timestamp
  • Actions: Update milestone, view history

Tab 5: HOTW ASG Details

  • List of all Auto Scaling Groups for this fleet
  • EAP enrollment status
  • Preferred ASGs selection
  • Run HOTW for this fleet button (atomicHotwModal)

hotwDashboard.jsx β€” HOTW Dashboard ⭐

URL: /hotw/{eventName} What it shows: Hardware order status for ALL fleets for an event

Data shown per fleet:

Fleet ID | Service | Peak TPM | Hosts Needed | Hosts in Apollo | FMC Orders | Status | Action Pending On

Key logic:

// For each fleet, calculate:
const pendingFMCOrder = Object.values(hostOrderStatuses.HostsPendingApproval)
    .reduce((acc, value) => acc + value, 0);

// Action pending determines who needs to act:
switch (actionPendingOn) {
    case 'Completed': actionItem = "No action"; break;
    case 'PendingOnEPIC': actionItem = "EPIC"; break;
    default: actionItem = serviceDetails.Owner; break; // owner needs to act
}

Filters available:

  • By service owner (alias parameter in URL)
  • By hardware order status (pending, completed, no order)

hotwRunHistory.jsx β€” HOTW Run History

URL: /hotwRunHistory/{eventId}
What it shows: All HOTW runs for an event, with status per fleet

RunId Fleet Status Peak TPM BAU TPM Hosts Needed Hosts Ordered
5 RIPE-NA Success 50000 33000 200 50

hotwAsgRunDetails.jsx β€” Per-ASG Run Details

URL: /hotwAsgRunDetails/{eventId}/{fleetId}/{runId} What it shows: Detailed ASG-level results for a specific HOTW run

ASG Name Override Value Fulfillment Status Is Emergent Link
RIPE/NA/PROD/1a 100 Completed No FMC link

serviceReadinessDashboard.jsx β€” Peak Readiness Dashboard

URL: /readiness/{eventId} What it shows: Green/Yellow/Red readiness status for every service

Service GatherProjections HardwareOrder HardwareFulfillment CommunicateTPM ThrottlingUpdate
RIPE 🟒 🟑 πŸ”΄ πŸ”΄ πŸ”΄

serviceDescaleReadinessDashboard.jsx β€” Descale Readiness Dashboard

After peak events, this shows descale milestone status for all fleets.


fleetConfigurations.jsx β€” Fleet Configuration

URL: /fleetConfig/{serviceName}/{fleetId}/{eventId} What it shows: ASG configuration for a fleet β€” scale up/down settings

Actions:

  • Create ASG
  • Update max instance count
  • Set preferred ASGs for HOTW

serviceThrottling.jsx β€” Throttling Configuration

URL: /throttling/{serviceName}/{fleetId}/{eventId} What it shows: Gizmo/SDC throttling settings for this fleet

Throttling controls maximum TPS (transactions per second) to prevent overload during peak.


onboardingChecklist.jsx β€” Service Onboarding

URL: /onboarding/{serviceName} What it shows: Checklist for onboarding a new service to EPIC

Steps:

  1. Register service
  2. Add fleets
  3. Connect Axon metrics
  4. Configure PMET links
  5. Set BAU capacity
  6. Complete onboarding

createEvent.jsx β€” Create New Event

URL: /createEvent What it shows: Form to create a new peak event

Fields:

  • Event ID (e.g., β€œPD2025”)
  • Event Name (e.g., β€œPrime Day 2025”)
  • Start/End dates per region
  • SPCO order dates per region
  • Game Day dates (practice run dates)

bauServiceOwnerDashboard.jsx β€” BAU Dashboard

URL: /bauDashboard What it shows: Business-As-Usual (non-peak) capacity tracking

Shows each fleet’s:

  • Current BAU TPM
  • Approved BAU max hosts
  • Current hosts in Apollo
  • Whether hosts need to be added or released

actionDashboard.jsx β€” Action Items Dashboard

URL: /actions What it shows: Pending actions for the logged-in user

Action Service Fleet Event Due Date
Submit Projections RIPE RIPE-NA PD2024 2026-06-01
Approve Exception FORTRESS FORTRESS-NA PD2024 2026-06-05

serviceOnboarding.jsx β€” Service Onboarding Wizard

Step-by-step wizard for onboarding new services.


dashboards.jsx β€” Main Dashboard

Shows an overview of all events and readiness status.


approveException.jsx β€” Exception Approval

Exceptions are when a service needs a different buffer factor than standard.

Exception workflow:

  1. Service owner submits exception request
  2. EPIC team reviews
  3. Approves or rejects

createException.jsx β€” Create Exception Request

Form for service owners to submit a buffer factor exception.


descaleFleetConfigurations.jsx β€” Descale Configuration

Configure which hosts to release after a peak event.


descaleServiceThrottling.jsx β€” Descale Throttling

Configure throttling reductions for post-peak descale.


dimensionView.jsx / configureDimension.jsx β€” Dimensional Projections

Some services break their traffic projections into β€œdimensions” (e.g., by country, by product type). These pages configure and view dimensional projections.


hostMigration.jsx β€” Host Migration

When host types change (e.g., migrating from c5.2xlarge to c6i.2xlarge), this page tracks the migration.


syncSettings.jsx / EpicDeveloperOptions/ β€” Developer Tools

Internal tools for EPIC team members to debug and sync data.


Section 5 β€” Redux State Slices

All global state managed by Redux:

store/pageNameSlice.js

// Tracks current page name
// Used to: show correct tutorial, control navigation highlighting
state.pageReducer.value = "hotwDashboard"  // or "serviceDetails", "events", etc.

store/serviceNameSlice.js

// Tracks currently selected service name
// Used to: show service-specific data, navigate within service
state.serviceNameReducer.value = "FORTRESSService"

store/regionSlice.js

// Tracks currently selected region
// Used to: filter fleets by region
state.regionNameReducer.value = "us-east-1"

store/eventObjectSlice.js

// Stores the full current event object
// Used to: show event dates, filter by event
state.eventObjectReducer.value = {
    EventId: "PD2024",
    EventName: "Prime Day 2024",
    RegionList: ["us-east-1", "eu-west-1"],
    // ... all event fields
}

store/serviceSlice.js

// Stores the full current service object
state.serviceObjectReducer.value = {
    ServiceId: "FORTRESSService",
    Owner: "fortress-owner@amazon.com",
    Fleet: [...],
    // ...
}

store/fleetObjectSlice.js

// Stores the full current fleet object
state.fleetObjectReducer.value = {
    FleetId: "FORTRESSService-NA-X0",
    ApolloName: "FORTRESSService_NA_X0",
    // ...
}

store/toolsOpenSlice.js

// Whether the right tools/tutorial panel is open
state.toolsOpenReducer.value = false  // or true

store/tutorialActiveIdSlice.js

// Which tutorial is currently being shown
state.tutorialActiveIdReducer.value = 3  // tutorial ID

store/isTutorialActiveSlice.js

// Whether a tutorial is currently in progress
state.isTutorialActiveReducer.value = true  // or false

Section 6 β€” API Call Layer (common/)

backend_api.js β€” Main Backend API Calls

// How API calls work:
backend_api.methodName(params)
    .then(response => {
        const data = response.data;
        setStateWithData(data);
    })
    .catch(error => {
        showError(error);
    });

All backend_api methods:

Method Endpoint Used By
getServiceDetails(name) GET /service/{name} service.jsx
getAllServices() GET /service many pages
getFleetDetails(fleetId, eventId) GET /fleet/{fleetId}/{eventId} serviceDetails.jsx
getAllEvents() GET /event events.jsx
getHotwDashboardDetails(eventId) GET /hotw/dashboard/{eventId} hotwDashboard.jsx
getHOTWExecutionHistory(eventId, fleetId) GET /hotw/executionDetail/{eventId}/{fleetId} hotwRunHistory.jsx
getEventPlan(eventId, fleetId) GET /eventplan/{eventId}/{fleetId} serviceDetails.jsx
updateMilestoneStatus(...) PUT /eventplan/{eventId}/{fleetId} milestone tabs
createOrUpdateASGDetails(...) POST /hotw/dashboardDetail fleetConfigurations.jsx

hotw_api.js β€” HOTW-Specific API Calls

Additional HOTW API methods:

hotw_api.getAsgDetails(fleetId)          // GET /hotw/asgDetail/{fleetId}
hotw_api.storePreferredASGs(fleetId, eventId, asgList)  // PUT /hotw/asgsPreference/...
hotw_api.getPreferredASGs(fleetId, eventId)              // GET /hotw/asgsPreference/...
hotw_api.triggerAtomicHotw(fleetId, eventId, versions)  // POST /hotw/atomic/{fleetId}/{eventId}

Other API Files

File What It Calls
apollo_api.js Apollo capacity data
axon_traffic_api.js Axon traffic metrics
scaling_planner_api.js ScalingPlanner capacity overrides
fmc_api.js FMC hardware order links
fmbi_api.js FMBI order details
throttling_api.js Gizmo throttling config
ticketing_api.js SIM ticket operations
approval_api.js Exception approval workflow
consensus_api.js Consensus (approval) workflow
resilience_api.js Service resilience data
pmet_api.js PMET metric links
guardrail_api.js Guardrail checks

Section 7 β€” Tables Component Reference

Most EPIC UI is tables. Key table components:

hotwReadinessTable.jsx

Shows HOTW dashboard β€” all fleets, their order status, and action items.

fleetsTable.jsx

Lists all fleets of a service with their readiness status.

milestonesTable.jsx

Shows milestone completion status for a fleet.

hostProjectionsTable.jsx

Shows host count projections vs. current vs. ordered.

hotwRunHistoryTable.jsx

Shows history of HOTW runs with per-fleet status.

hotwAsgHistoryTable.jsx

Shows per-ASG details for a HOTW run.

serviceReadinessTable.jsx

Shows readiness dashboard β€” green/yellow/red per service.

upstreamProjectionsTable.jsx

Shows upstream traffic projections received.

downstreamTrafficProjectionsTable.jsx

Shows downstream traffic projections sent.

throttlingTable.jsx

Shows Gizmo throttling configuration.

preferredAsgTable.jsx

Shows and edits the preferred ASG list for HOTW.


Section 8 β€” Modals Reference

EPIC has 30+ modal dialogs. Important ones:

Modal When It Opens What It Does
atomicHotwModal.jsx Click β€œRun HOTW” Manually triggers HOTW for one fleet
orderHostsModal.jsx Click β€œOrder Hosts” Places a manual FMC hardware order
submitModalForOverridingInputTPM.jsx Click β€œOverride TPM” Overrides the auto-calculated peak TPM
submitModalForApproval.jsx Click β€œSubmit for Approval” Submits exception for approval
escalateTicketModal.jsx Click β€œEscalate” Escalates a SIM ticket
ModalForHostDialUp.jsx Click β€œDial Up” Increases Apollo max host count
ModalForHostDialDown.jsx Click β€œDial Down” Decreases Apollo max host count
ModalForHostRelease.jsx Click β€œRelease” Releases hosts back to pool
dialHostsInApollo.jsx Various buttons Directly sets Apollo desired capacity
createAutoScalingGroup.jsx Click β€œAdd ASG” Creates new ASG for fleet
diffViewerModal.jsx Click β€œView Diff” Shows version diff for fleet config
helpModal.jsx Click help (?) Shows help documentation
submitModalForServiceOnboarding.jsx Onboarding flow Submits service onboarding
submitModalForBauSetting.jsx BAU page Updates BAU capacity settings

Section 9 β€” Tutorials System

EPIC has interactive tutorials to help new users:

// tutorials/fleetDetails/data.js
// tutorials/serviceDetails/data.js
// tutorials/serviceReadinessDashboard/data.js
// tutorials/configureDimension/data.js

Tutorials use the Polaris AnnotationContext and TutorialPanel:

  • Click a tutorial to start
  • Annotations highlight specific UI elements
  • Step-by-step instructions
  • Tracks completion status

Section 10 β€” Key Utility Functions (common/Util.js)

// Get current region from Apollo name
getCurrRegion(apolloName)
// "FORTRESSService_NA_X0" β†’ "NA"

// Get host type breakdown
getHostType(fleetDetails)
// Returns { "c5.2xlarge": 50, "c6i.2xlarge": 100 }

// Get FMC link
getLinkToAllOrdersOfFMC(hardwareOrderTags, apolloName, eventId)
// Returns URL to FMC page with all pending orders

// Check if emergent announcement needed
checkIfEmergentAnnouncementFlashbarNeedsToBeDisplayed(pageName)
// Returns true if on service details / HOTW dashboard

// Get hosts in child Apollo environments
getHostsCountInChildApolloEnvs(childEnvs, field)
// Returns total hosts across all child environments

Section 11 β€” Common Frontend Patterns

Pattern 1: Page with loading + data

const MyPage = ({ match }) => {
    const fleetId = match.params.fleetId;
    const [data, setData] = useState(null);
    const [isLoading, setIsLoading] = useState(true);
    const [error, setError] = useState(null);
    
    useEffect(() => {
        backend_api.getFleetDetails(fleetId, eventId)
            .then(response => { setData(response.data); setIsLoading(false); })
            .catch(err => { setError(err.message); setIsLoading(false); });
    }, [fleetId, eventId]);
    
    if (isLoading) return <Spinner />;
    if (error) return <Alert type="error">{error}</Alert>;
    if (!data) return <Alert type="warning">No data found</Alert>;
    
    return <DataDisplay data={data} />;
};

Pattern 2: Modal for user action

const [modalVisible, setModalVisible] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);

const handleSubmit = async () => {
    setIsSubmitting(true);
    try {
        await backend_api.updateSomething(data);
        setModalVisible(false);
        // refresh data
    } catch (err) {
        showError(err);
    } finally {
        setIsSubmitting(false);
    }
};

<Button onClick={() => setModalVisible(true)}>Take Action</Button>
<Modal visible={modalVisible} onDismiss={() => setModalVisible(false)}>
    <Button loading={isSubmitting} onClick={handleSubmit}>Confirm</Button>
</Modal>

Pattern 3: Table with filters

const [filterText, setFilterText] = useState("");
const filteredItems = data.filter(item =>
    item.FleetId.toLowerCase().includes(filterText.toLowerCase())
);

<TextFilter
    value={filterText}
    onChange={({ detail }) => setFilterText(detail.filteringText)}
/>
<Table items={filteredItems} />