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:
- Register service
- Add fleets
- Connect Axon metrics
- Configure PMET links
- Set BAU capacity
- 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:
- Service owner submits exception request
- EPIC team reviews
- 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} />