What youβll learn: Every folder, every file, every important function in the EPICBackend module.
Prerequisite: Read Guide 01 (JavaScript Basics) first.
Section 1 β EPICBackend Overview
The EPICBackend is a Node.js application that runs as AWS Lambda functions. It handles all REST API calls from the frontend and stores/retrieves data from DynamoDB and MySQL.
Location: /home/theja/EPIC/EPIC/src/EPICBackend/src/epiclambda/
Folder Structure:
epiclambda/
βββ api/ β REST API handlers (one file per resource)
βββ operations/ β Database query logic
βββ clients/ β Database connection wrappers
βββ common/ β Constants and utility functions
βββ notification/ β Email sending logic
βββ sqs/ β SQS message handling
βββ stream/ β DynamoDB stream processing
βββ Script/ β One-time scripts and data migration tools
βββ templates/ β SIM ticket markdown templates
Section 2 β API Handlers (The api/ Folder)
Each file in api/ handles CRUD operations for one resource. Every method follows the same pattern.
Pattern for ALL API handlers:
static async methodName(event) {
// 1. Parse and validate input
try {
body = JSON.parse(event.body);
if (!required fields present) throw TypeError();
// extract fields
} catch (err) {
return Util.handleErr(400, "Bad request", err);
}
// 2. Do database work
try {
const result = await operations.doSomething(data);
return Util.handleResponse(200, JSON.stringify(result));
} catch (err) {
return Util.handleErr(503, "Server error", err);
}
}
Fleet.js β Fleet Management
A Fleet is a group of servers running a service in one region (e.g., βFORTRESSService-NA-X0β).
Methods:
| Method | What It Does | HTTP |
|---|---|---|
createFleet(event) |
Creates a new fleet with version tracking | POST /fleet |
getFleet(event) |
Gets a fleet for a specific event | GET /fleet/{FleetId}/{EventId} |
getAllFleetsForEvent(event) |
Gets all fleets for an event | GET /fleet/event/{EventId} |
updateFleetConfiguration(event) |
Updates fleet settings (hosts, ASGs, etc.) | PUT /fleet/{FleetId}/{EventId} |
getFleetVersionHistory(event) |
Gets all versions of a fleet config | GET /fleet/{FleetId}/{EventId}/versions |
Key concept β Version Tracking:
// Fleet uses versioning. Every update creates a NEW version.
// DynamoDB stores ALL versions.
// VersionId 1 = original, VersionId 2 = first update, etc.
// "LatestVersionId" field always points to the current version.
async createFleet(event) {
// ...
let newVersionId = 1; // first version
const item = {
FleetId: fleetId,
VersionId: newVersionId,
LatestVersionId: newVersionId,
// ... rest of fleet data
};
await dynamodb.put(item);
}
Service.js β Service Management
A Service is an Amazon microservice that owns fleets (e.g., βFORTRESSServiceβ).
Methods:
| Method | What It Does | HTTP |
|---|---|---|
createService(event) |
Create a new service | POST /service |
getService(event) |
Get a service by ID | GET /service/{ServiceId} |
getAllServices(event) |
Get all services (optional filter by type) | GET /service |
updateService(event) |
Update service details | PUT /service/{ServiceId} |
deleteService(event) |
Delete a service | DELETE /service/{ServiceId} |
Service Types:
// From ServiceConstants.js
SERVICE_TYPE_REGISTERED = 'Registered'; // fully onboarded to EPIC
SERVICE_TYPE_ONBOARDING = 'Onboarding'; // currently onboarding
Event.js β Event Management
An Event is a peak event like βPrimeDay2024β or βBlackFriday2024β.
Methods:
| Method | What It Does | HTTP |
|---|---|---|
createEvent(event) |
Create a new peak event | POST /event |
getEvent(event) |
Get event by ID | GET /event/{EventId} |
getAllEvents(event) |
Get all events | GET /event |
updateEvent(event) |
Update event details | PUT /event/{EventId} |
getLatestEventForId(event) |
Get latest version of event | GET /event/latest/{EventId} |
getEventDashboard(event) |
Get readiness dashboard for event | PUT /event/{EventId}/dashboard |
EventPlan.js β Milestone Tracking β (Very Important)
An EventPlan tracks milestone progress for one fleet Γ one event combination.
EventPlanId = β{EventId}#{FleetId}β (e.g., βPD2024#RIPE-NAβ)
Methods:
| Method | What It Does |
|---|---|
createEventPlan(event) |
Create milestone checklist for fleet+event |
updateMilestoneList(event) |
Replace entire milestone list |
updateMilestoneDetail(event) |
Update specific milestone details |
updateMileStoneStatus(event) |
Update status of one milestone (most common) |
getEventPlan(event) |
Get current event plan |
getEventPlanByVersionId(event) |
Get historical version |
Milestone Status Values:
NotStartedβ milestone hasnβt begunInProgressβ work is underwayCompletedβ done!PendingOnEPICβ EPIC system needs to actPendingOnServiceOwnerβ owner needs to act
Milestone Flow:
GatherProjections β HardwareOrder β HardwareFulfillment β CommunicateTPM β ThrottlingUpdate
HOTW.js β Hardware Order Management β (Core)
The HOTW (Head of the Week) API manages hardware ordering data.
Methods:
| Method | What It Does |
|---|---|
createOrUpdateHotwRunDetails(event) |
Start/update a HOTW weekly run |
updateHotwRunDetails(event) |
Update run with order type (Standard/Emergent) |
createHotwExecutionDetails(event) |
Store detailed results for one fleet |
createOrUpdateDashboardDetailsAndAsgDetails(event) |
Update HOTW dashboard |
getHotwDashboardDetails(event) |
Get dashboard for a leader/service owner |
getAsgDetails(event) |
Get ASG info for a fleet |
getHOTWExecutionHistory(event) |
Get history of HOTW runs for a fleet |
storeHOTWPreferredASGSForFleet(event) |
Save preferred ASG list |
getHOTWPreferredASGSForFleet(event) |
Get preferred ASG list |
Key data structures:
// What createOrUpdateDashboardDetailsAndAsgDetails receives:
{
"ServiceId": "RIPE",
"FleetId": "RIPE-NA",
"EventId": "PD2024",
"Purpose": "Upscaling",
"CapacityOverrideSum": "50",
"ASGDetails": [
{
"AutoScalingGroupName": "RIPE/NA/PROD/1a",
"AsgTag": "1a",
"HostType": "c5.2xlarge",
"EAPOnboardingStatus": true,
"EAPEnableStatus": true,
"AsgCapacityLowerBound": 5
}
]
}
// What createHotwExecutionDetails receives:
{
"FleetId": "RIPE-NA",
"EventId": "PD2024",
"RunId": 2,
"Status": "Success", // or "Fail" or "PartialSuccess"
"Reasoning": "EAP enabled successfully",
"HotwExecutionDetails": {
"PeakTPM": 50000,
"BAUTPM": 30000,
"CTPeakFactor": 1.5,
"BufferFactor": 1.1,
"RequiredHosts": 200,
"HostsPresentInApollo": 150,
"CapacityOverrideSum": 50,
"PendingEPICFMCHostOrder": 0,
"HostThroughPutTPM": 250
},
"CapacityOverrideDetails": [ ... ],
"FulfillmentDetails": [ ... ],
"ASGDetails": [ ... ]
}
Projection.js β Traffic Projections
Projections are estimates of how much traffic each fleet will get during a peak event.
Methods:
| Method | What It Does |
|---|---|
createProjection |
Submit a new projection |
getProjection |
Get projection for fleet+event |
updateProjection |
Update projection values |
getProjectionHistory |
Get all versions |
Throttling.js β Gizmo/SDC Throttling
Throttling limits traffic to prevent overload. EPIC manages throttling via Gizmo (also called SDC).
Methods:
| Method | What It Does |
|---|---|
createThrottlingConfig |
Set up throttling rules for a fleet |
getThrottlingConfig |
Get current throttling settings |
updateThrottlingConfig |
Update throttling limits |
getThrottlingStatus |
Check if throttling is applied |
Ticket.js β SIM Ticket Management
SIM tickets are Amazonβs internal task tracking system (like JIRA). EPIC auto-creates tickets for hardware orders.
Methods:
| Method | What It Does |
|---|---|
createTicket |
Create a new SIM ticket |
updateTicket |
Update ticket status/comments |
getTicket |
Get ticket details |
escalateTicket |
Escalate to higher severity |
Other API Files
| File | What It Manages |
|---|---|
Calendar.js |
EPIC calendar events and timelines |
Pmet.js |
PMET performance metric links |
Schema.js |
Data schema configurations |
SIM.js |
SIM ticket integration |
Traffic.js |
Traffic data and projections |
BulkJobs.js |
Batch operations (bulk PMET uploads, etc.) |
Exception.js |
Buffer factor exception requests |
Organization.js |
Organization/team structure |
Philosophy.js |
Service philosophy (capacity philosophy) |
Dimension.js |
Dimensional projections (breakdown by dimension) |
Employee.js |
Employee directory for LDAP lookups |
CustomFormula.js |
Custom capacity formulas |
CustomInputSF.js |
Custom Step Function inputs |
BAUHostJob.js |
BAU host job management |
EventProfile.js |
Event profile templates |
Section 3 β Operations (The operations/ Folder)
Operations files contain the actual database logic. They are called by API handlers.
HOTWOperations.js
class HOTWOperations {
constructor() {
this.db = new AuroraDB(); // MySQL/Aurora connection
}
// SQL: INSERT INTO hotwdashboard (...)
async createOrUpdateHotwDashBoardTable(tableName, entries) { ... }
// SQL: INSERT INTO asg_details (...)
async createOrUpdateAsgDetailsTable(tableName, entries) { ... }
// SQL: INSERT INTO hotw_run (EventIndexId, RunStatus)
async updateRunTable(tableName, entries, eventIndexId) { ... }
// SQL: INSERT INTO hotw_execution (PeakTPM, BAUTPM, ...)
async insertHotwExecutionDetails(tableName, fleetIndexId, runId, ...) { ... }
// SQL: INSERT INTO capacity_override_details (...)
async insertCapacityOverrideDetails(tableName, fleetIndexId, runId, details) { ... }
// SQL: INSERT INTO fulfillment_details (...)
async insertFulfillmentDetails(tableName, fleetIndexId, runId, details) { ... }
// SQL: INSERT INTO asg_details_run (...)
async insertAsgDetailsWithRunId(tableName, fleetIndexId, runId, asgDetails) { ... }
// SQL: SELECT * FROM hotw_dashboard WHERE EventId = ?
async getHotwDashboardDetails(eventId, purpose) { ... }
// SQL: SELECT * FROM hotw_execution WHERE fleetIndexId = ? AND runId = ?
async getHOTWExecutionHistoryForFleetWithEvent(eventIndexId, fleetIndexId) { ... }
}
FleetOperations.js
class FleetOperations {
// DynamoDB: get fleet by FleetId
async getLatestFleet(fleetId) { ... }
// DynamoDB: create fleet item
async createFleet(fleetId, data) { ... }
// DynamoDB: get numerical index for a fleet (used in MySQL)
async getFleetIndex(fleetId) {
// fleets have a string ID in DynamoDB but a numeric index in MySQL
// this returns the numeric index
}
// Check if fleet exists for event
async checkIfFleetIdExistsForEvent(fleetId, eventId) { ... }
}
EventPlanOperations.js
class EventPlanOperations {
// DynamoDB: get latest EventPlan
async getLatestEventPlan(eventPlanId) { ... }
// DynamoDB: create or update EventPlan (versioned)
async createOrUpdateEventPlanInDDB(eventPlanId, fleetOps, body, version, audit) { ... }
// DynamoDB: check if EventPlan exists
async checkIfEventPlanIdExists(eventPlanId) { ... }
// DynamoDB: get specific version of EventPlan
async getEventPlanByVersionId(eventPlanId, versionId) { ... }
// DynamoDB: get event plans for multiple fleets
async getBatchEventPlanForService(fleetIds, eventId) { ... }
}
Section 4 β Clients (The clients/ Folder)
DynamoDbDocumentClient.js β NoSQL Database
class DynamoDbDocumentClient {
constructor() {
this.client = new AWS.DynamoDB.DocumentClient();
}
// Create or replace an item
async put(tableName, item) { ... }
// Get one item by key
async get(tableName, key) { ... }
// Query items (uses index)
async query(tableName, params) { ... }
// Scan all items (slow, use carefully)
async scan(tableName, params) { ... }
// Delete an item
async delete(tableName, key) { ... }
// Update specific fields
async update(tableName, key, expression) { ... }
// Get multiple items at once
async batchGet(tableName, keys) { ... }
}
AuroraMysqlClient.js β SQL Database
class AuroraMysqlClient {
// Execute a SELECT query
async queryPromise(sql, values) { ... }
// Execute an INSERT query (single row)
async insertSingleQueryPromise(sql, values) { ... }
// Execute an INSERT query (multiple rows)
async insertQueryPromise(sql, valuesArray) { ... }
// Execute an UPDATE query
async updateQueryPromise(sql, values) { ... }
// Transaction management
async startTransaction() { ... }
async commitTransaction() { ... }
async rollbackTransaction() { ... }
}
When is each used?
- DynamoDB β for main data (Fleet, Service, Event, EventPlan, Projections, Schema)
- MySQL/Aurora β for HOTW run data (execution details, ASG details, fulfillment details)
SIMClient.js β SIM Ticket Integration
class SIMClient {
// Create a new SIM ticket
async createTicket(title, description, assignee) { ... }
// Add a comment to a ticket
async addComment(ticketId, comment) { ... }
// Update ticket status
async updateStatus(ticketId, status) { ... }
}
SQSClient.js β Queue Messaging
class SQSClient {
// Send a message to a queue
async sendMessage(queueUrl, messageBody, attributes) { ... }
// Receive messages from a queue
async receiveMessage(queueUrl) { ... }
// Delete message after processing
async deleteMessage(queueUrl, receiptHandle) { ... }
}
Section 5 β Common Files (The common/ Folder)
Util.js β Helper Functions
const Util = {
// Validate that all required keys exist in body
validateKeys(body, requiredKeys) {
return requiredKeys.every(key => key in body && body[key] !== null);
},
// Format HTTP response
handleResponse(statusCode, body) {
return {
statusCode,
headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' },
body
};
},
// Format HTTP error response
handleErr(statusCode, message, error) {
console.error(message, error);
return {
statusCode,
body: JSON.stringify({ message, error: error?.message })
};
},
// Get current timestamp as string
getCurrentTimestampString() {
return new Date().toISOString();
}
};
Constants Files (Very Important!)
These define all the string keys used throughout the backend:
| File | What It Defines |
|---|---|
FleetConstants.js |
FLEET_ID, REGION, ASG_PROPERTIES, etc. |
EventConstants.js |
EVENT_ID, REGION_LIST, SPCO_EVENT_DATES, etc. |
ServiceConstants.js |
SERVICE_ID, FLEET, OWNER, etc. |
HOTWConstants.js |
RUN_ID, STATUS, ASG_Details, PURPOSE, etc. |
EventPlanConstants.js |
EVENT_MILESTONE, MILESTONE_COMPLETION_STATUS, etc. |
EventMilestoneConstants.js |
All milestone IDs (ordered list) |
OtherConstants.js |
BODY, PATH_PARAMETERS, AZ_FACTOR_MAP, etc. |
ThrottlingConstants.js |
Throttling table schemas |
ApiResponseStatusCodes.js |
SUCCESSFUL_OK_STATUS_CODE = 200, etc. |
Why these matter: Instead of hardcoding strings everywhere, EPIC uses constants:
// BAD (typo-prone):
const fleetId = body["FleetId"]; // what if someone writes "FleetID"?
// GOOD (EPIC's way):
const fleetId = body[FleetConstants.FLEET_ID]; // FleetConstants.FLEET_ID = "FleetId"
Section 6 β Notifications (The notification/ Folder)
Notification.js β SNS Publishing
class Notification {
// Publish service update to SNS
static async publishServiceUpdate(serviceId, updateType) {
await sns.publish({
TopicArn: process.env.SNS_TOPIC_ARN,
Message: JSON.stringify({ serviceId, updateType }),
});
}
// Publish service creation notification
static async publishServiceCreation(service) { ... }
}
EmailNotification.js β SES Email Sending
Sends HTML emails for various EPIC events:
class EmailNotification {
// Send email using template
static async sendEmail(template, recipients, variables) { ... }
// Send hardware order summary
static async sendHardwareOrderSummary(fleetId, eventId, orderDetails) { ... }
// Send peak readiness report
static async sendPeakReadinessReport(eventId, report) { ... }
}
operations/EmailNotificationOperations.js
Handles the complex logic of building email content before sending.
operations/PeakReadinessReportOperation.js
Generates the peak readiness report email β shows green/yellow/red status for every fleet.
Section 7 β SQS Receivers (The sqs/ Folder)
Some Lambda functions are triggered by SQS messages instead of API Gateway:
FleetReceiver.js
Processes messages from the EventFleetCreationQueue. When a new event is created, it automatically creates event plans for all fleets of all registered services.
// When triggered by SQS message:
async function handler(event) {
for (const record of event.Records) {
const { eventId, fleetId } = JSON.parse(record.body);
await eventPlanOperations.createOrUpdateEventPlanInDDB(
`${eventId}#${fleetId}`,
// ... creates initial milestone list
);
}
}
EventTicketReceiver.js
Processes messages from EventTicketCreationQueue. Creates SIM tickets for new events.
Sender.js
Generic SQS message sender utility.
Section 8 β Scripts (The Script/ Folder)
One-time scripts or maintenance utilities:
| Script | Purpose |
|---|---|
DetectInconsistencies.js |
Finds fleets where Apollo data doesnβt match EPIC data |
AxonToPmetDiscrepencyScript.js |
Finds mismatches between Axon and PMET metrics |
MetricAutomatedPercentage.js |
Calculates % of services using automated metrics |
VerifiedDataPopulator.js |
Populates verified data for services |
Section 9 β Full Request Flow Example
User clicks βGet HOTW Dashboardβ for PrimeDay2024:
1. Browser β GET /hotw/dashboard/PD2024/Upscaling
β
2. API Gateway routes to HOTWLambdaStack.getHotwDashboardDetailsLambda
β
3. Lambda runs HOTW.getHotwDashboardDetails(event)
β
4. Parse path params: eventId="PD2024", purpose="Upscaling"
β
5. Call serviceOperations.getAllServices("Registered")
βββ DynamoDB: scan ServiceTable where ServiceType=Registered
β
6. Call eventOperations.getLatestEvent("PD2024")
βββ DynamoDB: get EventTable item where EventId=PD2024
β
7. Build list of all fleet IDs from all services
β
8. Call eventPlanOperations.getBatchEventPlanForService(fleetIds, "PD2024")
βββ DynamoDB: batch get EventPlanTable for all fleet+event combinations
β
9. Call hotwOperations.getHotwDashboardDetails("PD2024", "Upscaling")
βββ MySQL: SELECT * FROM hotwdashboard WHERE EventId=...
β
10. Merge HOTW dashboard data with EventPlan milestone status
(adds StatusReasoning and ActionPendingOn to each row)
β
11. Return sorted list organized by service
β
12. Frontend receives data and renders the table
Section 10 β Error Codes Used in EPIC Backend
| Code | Meaning | When Used |
|---|---|---|
| 200 | OK β success | Successful GET, PUT, POST |
| 400 | Bad Request | Missing required fields, invalid data |
| 404 | Not Found | Fleet/service/event doesnβt exist |
| 503 | Service Unavailable | Database error, downstream service down |
Section 11 β Key SQL Tables (MySQL)
These are the MySQL/Aurora tables that HOTW uses:
| Table Name | Stores |
|---|---|
hotwdashboard |
Per-fleet HOTW summary (CapacityOverrideSum, Purpose) |
hotw_run |
Per-event HOTW run metadata (RunId, RunStatus, OrderType) |
hotw_execution |
Detailed execution data per fleet per run (TPM, hosts, status) |
asg_details |
Latest ASG configuration per fleet |
asg_details_run |
ASG configuration snapshot per run |
capacity_override_details |
Capacity override details per run |
fulfillment_details |
FMC fulfillment tracking per ASG per run |
preferred_asg |
User-selected preferred ASGs per fleet per event |