diff --git a/content/courses/ab-nfpa-1001-firefighter-i.yaml b/content/courses/ab-nfpa-1001-firefighter-i.yaml index c5e29e1..ac72685 100644 --- a/content/courses/ab-nfpa-1001-firefighter-i.yaml +++ b/content/courses/ab-nfpa-1001-firefighter-i.yaml @@ -1,127 +1,127 @@ course: id: ab-nfpa-1001-ff1 - name: "NFPA 1001 Fire Fighter Level I (Alberta)" - description: "Aligned to NFPA 1001-2019, Chapter 4. IFSAC/Pro Board accredited via Alberta Municipal Affairs." + name: NFPA 1001 Fire Fighter Level I (Alberta) + description: Aligned to NFPA 1001-2019, Chapter 4. IFSAC/Pro Board accredited via Alberta Municipal Affairs. estimatedHours: 40 - version: "2024.1" - sourceDocument: "NFPA 1001-2019: Standard for Fire Fighter Professional Qualifications, Chapter 4" - + version: '2024.1' + sourceDocument: 'NFPA 1001-2019: Standard for Fire Fighter Professional Qualifications, Chapter 4' concepts: - - # ============================================================ - # 4.1 General Requirements - # ============================================================ - - id: ppe-donning-doffing - name: "PPE Donning and Doffing" + name: PPE Donning and Doffing difficulty: 2 estimatedMinutes: 20 - tags: [s4.1-general, ppe, foundational] - sourceRef: "NFPA 1001-2019 JPR 4.1.1" + tags: + - s4.1-general + - ppe + - foundational + sourceRef: NFPA 1001-2019 JPR 4.1.1 knowledgePoints: - id: ppe-ensemble-components problems: - id: ppe-ensemble-p1 type: multiple_choice - question: "Which of the following is NOT a standard component of a firefighter's structural PPE ensemble?" + question: Which of the following is NOT a standard component of a firefighter's structural PPE ensemble? options: - - "Helmet with eye protection and ear flaps" - - "Turnout coat and pants with moisture barrier, thermal barrier, and outer shell" - - "Level A chemical encapsulating suit" - - "Gloves, hood, and NFPA-compliant boots" + - Helmet with eye protection and ear flaps + - Turnout coat and pants with moisture barrier, thermal barrier, and outer shell + - Level A chemical encapsulating suit + - Gloves, hood, and NFPA-compliant boots correct: 2 - explanation: "A Level A chemical encapsulating suit is hazmat PPE, not part of the structural firefighting ensemble. The structural ensemble includes helmet, hood, turnout coat and pants (each with three layers: outer shell, moisture barrier, thermal barrier), gloves, and boots — all compliant with NFPA 1971." + explanation: 'A Level A chemical encapsulating suit is hazmat PPE, not part of the structural firefighting ensemble. The structural ensemble includes helmet, hood, turnout coat and pants (each with three layers: outer shell, moisture barrier, thermal barrier), gloves, and boots — all compliant with NFPA 1971.' - id: ppe-ensemble-p2 type: true_false - question: "When doffing contaminated PPE after a fire, firefighters should remove gear in a clean area and avoid cross-contaminating the cab interior." - correct: "true" - explanation: "Contaminated PPE carries carcinogenic particulates from combustion products. Proper doffing in a designated area, bagging gear for cleaning, and keeping contaminated PPE out of the apparatus cab are essential cancer-prevention practices aligned with NFPA 1851 and modern decontamination protocols." - + question: When doffing contaminated PPE after a fire, firefighters should remove gear in a clean area and avoid cross-contaminating the cab interior. + correct: 'true' + explanation: Contaminated PPE carries carcinogenic particulates from combustion products. Proper doffing in a designated area, bagging gear for cleaning, and keeping contaminated PPE out of the apparatus cab are essential cancer-prevention practices aligned with NFPA 1851 and modern decontamination protocols. - id: knots-bends-hitches - name: "Knots, Bends, and Hitches" + name: Knots, Bends, and Hitches difficulty: 3 estimatedMinutes: 25 - tags: [s4.1-general, ropes, foundational] - sourceRef: "NFPA 1001-2019 JPR 4.1.2" + tags: + - s4.1-general + - ropes + - foundational + sourceRef: NFPA 1001-2019 JPR 4.1.2 knowledgePoints: - id: knot-types-applications problems: - id: knot-types-p1 type: multiple_choice - question: "Which knot is the MOST appropriate choice for creating a fixed loop at the end of a rope to attach to a tool for hoisting?" + question: Which knot is the MOST appropriate choice for creating a fixed loop at the end of a rope to attach to a tool for hoisting? options: - - "Clove hitch" - - "Bowline" - - "Sheet bend" - - "Water knot" + - Clove hitch + - Bowline + - Sheet bend + - Water knot correct: 1 - explanation: "The bowline creates a fixed, non-slipping loop at the end of a rope and is the standard knot for attaching to tools, equipment, or creating an anchor point for hoisting. It is easy to untie after loading. A clove hitch secures rope to an object but can slip. A sheet bend joins two ropes. A water knot is used for webbing." + explanation: The bowline creates a fixed, non-slipping loop at the end of a rope and is the standard knot for attaching to tools, equipment, or creating an anchor point for hoisting. It is easy to untie after loading. A clove hitch secures rope to an object but can slip. A sheet bend joins two ropes. A water knot is used for webbing. - id: knot-types-p2 type: fill_blank - question: "A ___ is used to join two ropes of different diameters together." - correct: "sheet bend" - explanation: "The sheet bend (also called a becket bend) is specifically designed to join two ropes of unequal diameter. The thicker rope forms the bight, and the thinner rope passes through and around it. For critical loads, a double sheet bend adds security." - - # ============================================================ - # 4.2 Fire Department Communications - # ============================================================ - + question: A ___ is used to join two ropes of different diameters together. + correct: sheet bend + explanation: The sheet bend (also called a becket bend) is specifically designed to join two ropes of unequal diameter. The thicker rope forms the bight, and the thinner rope passes through and around it. For critical loads, a double sheet bend adds security. - id: alarm-receiving-processing - name: "Receiving Telephone Calls and Alarm Processing" + name: Receiving Telephone Calls and Alarm Processing difficulty: 2 estimatedMinutes: 15 - tags: [s4.2-communications, dispatch] - sourceRef: "NFPA 1001-2019 JPR 4.2.1" + tags: + - s4.2-communications + - dispatch + sourceRef: NFPA 1001-2019 JPR 4.2.1 knowledgePoints: - id: alarm-processing-procedures problems: - id: alarm-proc-p1 type: multiple_choice - question: "When receiving an emergency call at the fire station, what information is MOST critical to obtain first?" + question: When receiving an emergency call at the fire station, what information is MOST critical to obtain first? options: - - "The caller's insurance information" - - "The exact location/address of the emergency and the nature of the incident" - - "The number of fire apparatus to respond" - - "The building's construction date" + - The caller's insurance information + - The exact location/address of the emergency and the nature of the incident + - The number of fire apparatus to respond + - The building's construction date correct: 1 - explanation: "The location and nature of the emergency are the most critical pieces of information because they determine which resources to dispatch and how quickly. Without an accurate address, responders cannot find the scene. The nature of the incident (fire, medical, hazmat) determines the type and level of response." + explanation: The location and nature of the emergency are the most critical pieces of information because they determine which resources to dispatch and how quickly. Without an accurate address, responders cannot find the scene. The nature of the incident (fire, medical, hazmat) determines the type and level of response. - id: alarm-proc-p2 type: true_false - question: "A firefighter receiving a telephone alarm should keep the caller on the line as long as possible to gather additional information while units are being dispatched." - correct: "true" - explanation: "Keeping the caller on the line allows gathering additional details (number of occupants, location of fire within the building, hazards present) that can be relayed to responding units. Dispatch should be initiated immediately with the address and nature, but the caller can provide valuable supplemental information while units are en route." - + question: A firefighter receiving a telephone alarm should keep the caller on the line as long as possible to gather additional information while units are being dispatched. + correct: 'true' + explanation: Keeping the caller on the line allows gathering additional details (number of occupants, location of fire within the building, hazards present) that can be relayed to responding units. Dispatch should be initiated immediately with the address and nature, but the caller can provide valuable supplemental information while units are en route. - id: radio-communications - name: "Radio Communications (Transmit/Receive)" + name: Radio Communications (Transmit/Receive) difficulty: 3 estimatedMinutes: 15 - tags: [s4.2-communications, radio] - sourceRef: "NFPA 1001-2019 JPR 4.2.2" + tags: + - s4.2-communications + - radio + sourceRef: NFPA 1001-2019 JPR 4.2.2 knowledgePoints: - id: radio-procedures-fundamentals problems: - id: radio-proc-p1 type: multiple_choice - question: "When transmitting a radio message on the fireground, the correct procedure is to:" + question: 'When transmitting a radio message on the fireground, the correct procedure is to:' options: - - "Press the transmit button and immediately begin speaking" - - "Press the transmit button, pause briefly (1 second), then speak clearly using plain language and the unit identifier" - - "Speak as quickly as possible to keep the channel clear" - - "Use 10-codes exclusively for all transmissions" + - Press the transmit button and immediately begin speaking + - Press the transmit button, pause briefly (1 second), then speak clearly using plain language and the unit identifier + - Speak as quickly as possible to keep the channel clear + - Use 10-codes exclusively for all transmissions correct: 1 - explanation: "The brief pause after keying the microphone allows the repeater or system to activate, preventing the first part of the message from being clipped. Plain language (per NIMS/ICS requirements) is preferred over 10-codes for interoperability. Clear, deliberate speech at moderate pace ensures the message is understood. Unit identification is required for accountability." + explanation: The brief pause after keying the microphone allows the repeater or system to activate, preventing the first part of the message from being clipped. Plain language (per NIMS/ICS requirements) is preferred over 10-codes for interoperability. Clear, deliberate speech at moderate pace ensures the message is understood. Unit identification is required for accountability. - id: radio-proc-p2 type: fill_blank - question: "The standard radio acknowledgment format when receiving an order from command is to ___ the message back to confirm understanding." - correct: "repeat" - explanation: "Repeating (echoing back) the message confirms that the receiver heard and understood the order correctly. This closed-loop communication prevents dangerous misunderstandings on the fireground. For example: Command says 'Engine 1, advance a line to the second floor.' Engine 1 responds: 'Engine 1 copies, advancing a line to the second floor.'" - + question: The standard radio acknowledgment format when receiving an order from command is to ___ the message back to confirm understanding. + correct: repeat + explanation: 'Repeating (echoing back) the message confirms that the receiver heard and understood the order correctly. This closed-loop communication prevents dangerous misunderstandings on the fireground. For example: Command says ''Engine 1, advance a line to the second floor.'' Engine 1 responds: ''Engine 1 copies, advancing a line to the second floor.''' - id: emergency-radio-mayday - name: "Emergency Radio Communications (Mayday Procedures)" + name: Emergency Radio Communications (Mayday Procedures) difficulty: 5 estimatedMinutes: 20 - tags: [s4.2-communications, radio, mayday, emergency] - sourceRef: "NFPA 1001-2019 JPR 4.2.3" + tags: + - s4.2-communications + - radio + - mayday + - emergency + sourceRef: NFPA 1001-2019 JPR 4.2.3 prerequisites: - radio-communications knowledgePoints: @@ -129,150 +129,152 @@ concepts: problems: - id: mayday-proc-p1 type: multiple_choice - question: "A firefighter is trapped and must declare a Mayday. Using the LUNAR report format, what information should be transmitted?" + question: A firefighter is trapped and must declare a Mayday. Using the LUNAR report format, what information should be transmitted? options: - - "Location, Unit, Name, Assignment/Air supply, Resources needed" - - "Latitude, Utility status, Number of victims, Access route, Radio channel" - - "Ladder placement, Utility shutoff, Nozzle type, Apparatus number, Roof conditions" - - "Location, Unit, Nozzle pressure, Apparatus type, Rescue plan" + - Location, Unit, Name, Assignment/Air supply, Resources needed + - Latitude, Utility status, Number of victims, Access route, Radio channel + - Ladder placement, Utility shutoff, Nozzle type, Apparatus number, Roof conditions + - Location, Unit, Nozzle pressure, Apparatus type, Rescue plan correct: 0 - explanation: "LUNAR stands for Location (where you are), Unit (your unit designation), Name (your name), Assignment/Air supply (what you were doing and how much air you have), and Resources needed (what help you need). This standardized format gives incident command the essential information to initiate a rapid intervention team (RIT) deployment." + explanation: LUNAR stands for Location (where you are), Unit (your unit designation), Name (your name), Assignment/Air supply (what you were doing and how much air you have), and Resources needed (what help you need). This standardized format gives incident command the essential information to initiate a rapid intervention team (RIT) deployment. - id: mayday-proc-p2 type: true_false - question: "Any firefighter on the fireground can declare a Mayday — it is not limited to officers or incident command." - correct: "true" - explanation: "Any firefighter who is lost, trapped, injured, or in an immediately dangerous situation has both the authority and the obligation to declare a Mayday. Waiting for an officer to declare it could cost critical seconds. The Mayday declaration immediately triggers RIT activation and shifts incident priorities to firefighter rescue." - - # ============================================================ - # 4.3 Fireground Operations - # ============================================================ - - # --- SCBA cluster --- - + question: Any firefighter on the fireground can declare a Mayday — it is not limited to officers or incident command. + correct: 'true' + explanation: Any firefighter who is lost, trapped, injured, or in an immediately dangerous situation has both the authority and the obligation to declare a Mayday. Waiting for an officer to declare it could cost critical seconds. The Mayday declaration immediately triggers RIT activation and shifts incident priorities to firefighter rescue. + keyPrerequisite: radio-communications - id: scba-donning-doffing-breathing - name: "SCBA Donning, Doffing, and Controlled Breathing" + name: SCBA Donning, Doffing, and Controlled Breathing difficulty: 4 estimatedMinutes: 30 - tags: [s4.3-fireground, scba, ppe, foundational] - sourceRef: "NFPA 1001-2019 JPR 4.3.1" + tags: + - s4.3-fireground + - scba + - ppe + - foundational + sourceRef: NFPA 1001-2019 JPR 4.3.1 prerequisites: - ppe-donning-doffing knowledgePoints: - id: scba-components - instruction: "content/ab-ff1/scba-components.md" - workedExample: "content/ab-ff1/scba-components-ex.md" + instruction: content/ab-ff1/scba-components.md + workedExample: content/ab-ff1/scba-components-ex.md problems: - id: scba-comp-p1 type: multiple_choice - question: "Which component of the SCBA regulates air pressure from the cylinder to a breathable level for the firefighter?" + question: Which component of the SCBA regulates air pressure from the cylinder to a breathable level for the firefighter? options: - - "Regulator (first-stage reducer and second-stage regulator)" - - "Facepiece exhalation valve" - - "Cylinder valve handwheel" - - "PASS device sensor" + - Regulator (first-stage reducer and second-stage regulator) + - Facepiece exhalation valve + - Cylinder valve handwheel + - PASS device sensor correct: 0 - explanation: "The regulator system (first-stage reducer drops cylinder pressure to intermediate, second-stage demand valve delivers breathing air at ambient pressure) is the component that makes high-pressure cylinder air breathable." + explanation: The regulator system (first-stage reducer drops cylinder pressure to intermediate, second-stage demand valve delivers breathing air at ambient pressure) is the component that makes high-pressure cylinder air breathable. - id: scba-comp-p2 type: multiple_choice - question: "What is the standard minimum rated service life of an SCBA air cylinder before it must be hydrostatically retested?" + question: What is the standard minimum rated service life of an SCBA air cylinder before it must be hydrostatically retested? options: - - "3 years" - - "5 years" - - "10 years" - - "15 years" + - 3 years + - 5 years + - 10 years + - 15 years correct: 1 - explanation: "DOT and CGA standards require hydrostatic testing of composite SCBA cylinders every 5 years. The cylinder's manufacture date and retest schedule are stamped on the cylinder itself." + explanation: DOT and CGA standards require hydrostatic testing of composite SCBA cylinders every 5 years. The cylinder's manufacture date and retest schedule are stamped on the cylinder itself. - id: scba-comp-p3 type: fill_blank - question: "The low-air alarm on most SCBA activates when cylinder pressure drops to approximately ___ psi (25% of a standard 4500-psi cylinder)." - correct: "1125" - explanation: "The low-air alarm (audible bell or whistle) typically activates at approximately 25% of rated cylinder pressure. For a 4500-psi cylinder, that is roughly 1125 psi, signaling the firefighter to exit the hazardous atmosphere immediately." - + question: The low-air alarm on most SCBA activates when cylinder pressure drops to approximately ___ psi (25% of a standard 4500-psi cylinder). + correct: '1125' + explanation: The low-air alarm (audible bell or whistle) typically activates at approximately 25% of rated cylinder pressure. For a 4500-psi cylinder, that is roughly 1125 psi, signaling the firefighter to exit the hazardous atmosphere immediately. + keyPrerequisite: ppe-donning-doffing - id: scba-donning-procedures - instruction: "content/ab-ff1/scba-donning.md" - workedExample: "content/ab-ff1/scba-donning-ex.md" + instruction: content/ab-ff1/scba-donning.md + workedExample: content/ab-ff1/scba-donning-ex.md problems: - id: scba-don-p1 type: multiple_choice - question: "When donning SCBA using the over-the-head method, what must be completed BEFORE placing the facepiece?" + question: When donning SCBA using the over-the-head method, what must be completed BEFORE placing the facepiece? options: - - "Open the cylinder valve fully, verify positive-pressure airflow, and check the gauge" - - "Seal the facepiece and take two test breaths" - - "Activate the PASS device manually" - - "Connect the regulator to the facepiece" + - Open the cylinder valve fully, verify positive-pressure airflow, and check the gauge + - Seal the facepiece and take two test breaths + - Activate the PASS device manually + - Connect the regulator to the facepiece correct: 0 - explanation: "Before facepiece placement, the firefighter must open the cylinder valve fully (listen for the low-air alarm to chirp briefly, confirming activation), verify the heads-up display or remote gauge shows adequate air supply, and confirm positive-pressure airflow. This ensures the system is functional before entering the IDLH atmosphere." + explanation: Before facepiece placement, the firefighter must open the cylinder valve fully (listen for the low-air alarm to chirp briefly, confirming activation), verify the heads-up display or remote gauge shows adequate air supply, and confirm positive-pressure airflow. This ensures the system is functional before entering the IDLH atmosphere. - id: scba-don-p2 type: multiple_choice - question: "After donning the SCBA facepiece, how should you verify a proper seal?" + question: After donning the SCBA facepiece, how should you verify a proper seal? options: - - "Listen for air leaks around the nose cup area" - - "Cover the regulator inlet with your palm and inhale — the facepiece should collapse slightly and hold negative pressure" - - "Exhale sharply and check that the exhalation valve opens" - - "Check the heads-up display for a green indicator light" + - Listen for air leaks around the nose cup area + - Cover the regulator inlet with your palm and inhale — the facepiece should collapse slightly and hold negative pressure + - Exhale sharply and check that the exhalation valve opens + - Check the heads-up display for a green indicator light correct: 1 - explanation: "The standard negative-pressure seal check is performed by covering the regulator inlet (or breathing tube opening) and inhaling. If the facepiece collapses slightly against your face and holds, the seal is good. Any air leaking in indicates a poor seal that must be corrected before entry." + explanation: The standard negative-pressure seal check is performed by covering the regulator inlet (or breathing tube opening) and inhaling. If the facepiece collapses slightly against your face and holds, the seal is good. Any air leaking in indicates a poor seal that must be corrected before entry. - id: scba-don-p3 type: multiple_choice - question: "What is the PRIMARY reason for fully opening the cylinder valve before entering an IDLH environment?" + question: What is the PRIMARY reason for fully opening the cylinder valve before entering an IDLH environment? options: - - "To activate the PASS device automatically" - - "To ensure maximum airflow is available and to prevent a partially open valve from restricting air under high breathing demand" - - "To reset the low-air alarm" - - "To pressurize the backup regulator" + - To activate the PASS device automatically + - To ensure maximum airflow is available and to prevent a partially open valve from restricting air under high breathing demand + - To reset the low-air alarm + - To pressurize the backup regulator correct: 1 - explanation: "A partially opened cylinder valve can restrict airflow when the firefighter is under heavy physical exertion and high breathing demand. Fully opening the valve ensures maximum air delivery. While opening the valve also arms the PASS device on many units, the primary safety reason is unrestricted airflow." - + explanation: A partially opened cylinder valve can restrict airflow when the firefighter is under heavy physical exertion and high breathing demand. Fully opening the valve ensures maximum air delivery. While opening the valve also arms the PASS device on many units, the primary safety reason is unrestricted airflow. + keyPrerequisite: scba-donning-doffing-breathing - id: scba-controlled-breathing - instruction: "content/ab-ff1/scba-breathing.md" - workedExample: "content/ab-ff1/scba-breathing-ex.md" + instruction: content/ab-ff1/scba-breathing.md + workedExample: content/ab-ff1/scba-breathing-ex.md problems: - id: scba-breath-p1 type: multiple_choice - question: "Which controlled breathing technique is MOST effective for conserving air while performing moderate work in SCBA?" + question: Which controlled breathing technique is MOST effective for conserving air while performing moderate work in SCBA? options: - - "Rapid shallow breaths to minimize volume per breath" - - "Slow, deep breaths (inhale through nose, exhale through mouth) with a brief pause between cycles" - - "Holding breath for as long as possible between tasks" - - "Breathing only through the mouth to maximize airflow" + - Rapid shallow breaths to minimize volume per breath + - Slow, deep breaths (inhale through nose, exhale through mouth) with a brief pause between cycles + - Holding breath for as long as possible between tasks + - Breathing only through the mouth to maximize airflow correct: 1 - explanation: "Slow, deep, rhythmic breathing (sometimes called 'skip breathing' in relaxed form) is the most effective technique. It maximizes gas exchange per breath, reduces dead space ventilation, and lowers the overall breathing rate. Rapid shallow breathing wastes air in dead space. Breath-holding causes CO2 buildup and dangerous reflex gasping." + explanation: Slow, deep, rhythmic breathing (sometimes called 'skip breathing' in relaxed form) is the most effective technique. It maximizes gas exchange per breath, reduces dead space ventilation, and lowers the overall breathing rate. Rapid shallow breathing wastes air in dead space. Breath-holding causes CO2 buildup and dangerous reflex gasping. - id: scba-breath-p2 type: multiple_choice - question: "A firefighter's air consumption rate increases MOST dramatically due to which factor?" + question: A firefighter's air consumption rate increases MOST dramatically due to which factor? options: - - "Ambient temperature" - - "Physical exertion and stress/anxiety" - - "Cylinder age" - - "Facepiece brand" + - Ambient temperature + - Physical exertion and stress/anxiety + - Cylinder age + - Facepiece brand correct: 1 - explanation: "Physical exertion can increase air consumption from a resting rate of ~20 L/min to over 100 L/min during heavy work. Psychological stress and anxiety compound this by triggering rapid, shallow breathing. These are the dominant factors — far exceeding the influence of temperature or equipment variables." + explanation: Physical exertion can increase air consumption from a resting rate of ~20 L/min to over 100 L/min during heavy work. Psychological stress and anxiety compound this by triggering rapid, shallow breathing. These are the dominant factors — far exceeding the influence of temperature or equipment variables. - id: scba-breath-p3 type: fill_blank - question: "A standard 30-minute rated SCBA cylinder provides approximately ___ minutes of working air for a firefighter under heavy exertion." - correct: "15-20" - explanation: "The 30-minute rating is based on a standardized breathing rate of 40 L/min. Under heavy fireground exertion, a firefighter may consume 80-100+ L/min, reducing effective working time to roughly 15-20 minutes. This is why air management discipline and the rule of air (know your point of no return) are critical." - + question: A standard 30-minute rated SCBA cylinder provides approximately ___ minutes of working air for a firefighter under heavy exertion. + correct: 15-20 + explanation: The 30-minute rating is based on a standardized breathing rate of 40 L/min. Under heavy fireground exertion, a firefighter may consume 80-100+ L/min, reducing effective working time to roughly 15-20 minutes. This is why air management discipline and the rule of air (know your point of no return) are critical. + keyPrerequisite: scba-donning-doffing-breathing - id: scba-doffing-inspection - instruction: "content/ab-ff1/scba-doffing.md" + instruction: content/ab-ff1/scba-doffing.md problems: - id: scba-doff-p1 type: multiple_choice - question: "After doffing SCBA, what is the FIRST maintenance action a firefighter should perform?" + question: After doffing SCBA, what is the FIRST maintenance action a firefighter should perform? options: - - "Refill the cylinder immediately" - - "Close the cylinder valve and bleed remaining pressure from the system" - - "Remove and clean the facepiece lens" - - "Test the PASS device battery" + - Refill the cylinder immediately + - Close the cylinder valve and bleed remaining pressure from the system + - Remove and clean the facepiece lens + - Test the PASS device battery correct: 1 - explanation: "After doffing, the cylinder valve must be closed and remaining pressure bled from the regulator and hose. This protects the regulator from prolonged pressure stress, prevents accidental activation, and sets the unit up for proper inspection and refilling." - + explanation: After doffing, the cylinder valve must be closed and remaining pressure bled from the regulator and hose. This protects the regulator from prolonged pressure stress, prevents accidental activation, and sets the unit up for proper inspection and refilling. + keyPrerequisite: scba-donning-doffing-breathing - id: scba-emergency-procedures - name: "SCBA Emergency Procedures" + name: SCBA Emergency Procedures difficulty: 6 estimatedMinutes: 25 - tags: [s4.3-fireground, scba, emergency, pass-device] - sourceRef: "NFPA 1001-2019 JPR 4.3.1" + tags: + - s4.3-fireground + - scba + - emergency + - pass-device + sourceRef: NFPA 1001-2019 JPR 4.3.1 prerequisites: - scba-donning-doffing-breathing knowledgePoints: @@ -280,26 +282,29 @@ concepts: problems: - id: scba-emerg-p1 type: multiple_choice - question: "If an SCBA facepiece lens becomes damaged or compromised in an IDLH atmosphere, the firefighter should IMMEDIATELY:" + question: 'If an SCBA facepiece lens becomes damaged or compromised in an IDLH atmosphere, the firefighter should IMMEDIATELY:' options: - - "Remove the facepiece and breathe through a wet cloth" - - "Press the facepiece tightly against the face, activate the bypass/purge valve to maintain positive pressure, and withdraw to a safe atmosphere immediately" - - "Switch to a buddy-breathing connection with a partner" - - "Continue working while covering the damaged area with a gloved hand" + - Remove the facepiece and breathe through a wet cloth + - Press the facepiece tightly against the face, activate the bypass/purge valve to maintain positive pressure, and withdraw to a safe atmosphere immediately + - Switch to a buddy-breathing connection with a partner + - Continue working while covering the damaged area with a gloved hand correct: 1 - explanation: "Pressing the facepiece against the face and activating the bypass/purge valve creates continuous positive pressure flow that pushes contaminated air out through the damage rather than allowing it in. This buys the firefighter time to withdraw to clean air. Removing the facepiece in an IDLH atmosphere is immediately life-threatening." + explanation: Pressing the facepiece against the face and activating the bypass/purge valve creates continuous positive pressure flow that pushes contaminated air out through the damage rather than allowing it in. This buys the firefighter time to withdraw to clean air. Removing the facepiece in an IDLH atmosphere is immediately life-threatening. - id: scba-emerg-p2 type: true_false - question: "The PASS (Personal Alert Safety System) device automatically activates its alarm when a firefighter remains motionless for approximately 30 seconds." - correct: "true" - explanation: "The PASS device is designed to detect a lack of motion. When a firefighter is motionless for approximately 30 seconds (varies by manufacturer), it emits a loud audible alarm to alert other firefighters that someone may be down, trapped, or incapacitated. This is a critical safety feature for rapid intervention." - + question: The PASS (Personal Alert Safety System) device automatically activates its alarm when a firefighter remains motionless for approximately 30 seconds. + correct: 'true' + explanation: The PASS device is designed to detect a lack of motion. When a firefighter is motionless for approximately 30 seconds (varies by manufacturer), it emits a loud audible alarm to alert other firefighters that someone may be down, trapped, or incapacitated. This is a critical safety feature for rapid intervention. + keyPrerequisite: scba-donning-doffing-breathing - id: scba-restricted-passage - name: "SCBA Restricted Passage Operations" + name: SCBA Restricted Passage Operations difficulty: 6 estimatedMinutes: 20 - tags: [s4.3-fireground, scba, confined-space] - sourceRef: "NFPA 1001-2019 JPR 4.3.1" + tags: + - s4.3-fireground + - scba + - confined-space + sourceRef: NFPA 1001-2019 JPR 4.3.1 prerequisites: - scba-emergency-procedures knowledgePoints: @@ -307,28 +312,29 @@ concepts: problems: - id: restrict-pass-p1 type: multiple_choice - question: "When navigating a restricted passage while wearing SCBA, the PREFERRED technique is to:" + question: 'When navigating a restricted passage while wearing SCBA, the PREFERRED technique is to:' options: - - "Remove the SCBA completely and push it ahead" - - "Reduce the profile by repositioning the SCBA to the side or in front while maintaining the facepiece connection and air supply" - - "Remove the facepiece temporarily to fit through the opening" - - "Use a different entry point — restricted passages should never be entered" + - Remove the SCBA completely and push it ahead + - Reduce the profile by repositioning the SCBA to the side or in front while maintaining the facepiece connection and air supply + - Remove the facepiece temporarily to fit through the opening + - Use a different entry point — restricted passages should never be entered correct: 1 - explanation: "Repositioning the SCBA (typically swinging the pack to one side or removing the harness and pushing the unit ahead while keeping the facepiece connected via the low-pressure hose) reduces the firefighter's profile. The facepiece must remain sealed and connected at all times in an IDLH atmosphere. Complete removal of SCBA or facepiece is not acceptable." + explanation: Repositioning the SCBA (typically swinging the pack to one side or removing the harness and pushing the unit ahead while keeping the facepiece connected via the low-pressure hose) reduces the firefighter's profile. The facepiece must remain sealed and connected at all times in an IDLH atmosphere. Complete removal of SCBA or facepiece is not acceptable. - id: restrict-pass-p2 type: fill_blank - question: "Before entering a restricted passage, a firefighter should check their ___ supply to ensure adequate reserves for the additional time and exertion required." - correct: "air" - explanation: "Navigating restricted passages is physically demanding and time-consuming, significantly increasing air consumption. Checking the remaining air supply before committing to a restricted passage is essential. If air reserves are insufficient, the firefighter must find an alternate route or withdraw." - - # --- Scene management --- - + question: Before entering a restricted passage, a firefighter should check their ___ supply to ensure adequate reserves for the additional time and exertion required. + correct: air + explanation: Navigating restricted passages is physically demanding and time-consuming, significantly increasing air consumption. Checking the remaining air supply before committing to a restricted passage is essential. If air reserves are insufficient, the firefighter must find an alternate route or withdraw. + keyPrerequisite: scba-emergency-procedures - id: responding-on-apparatus - name: "Responding on Apparatus Safely" + name: Responding on Apparatus Safely difficulty: 2 estimatedMinutes: 15 - tags: [s4.3-fireground, apparatus, safety] - sourceRef: "NFPA 1001-2019 JPR 4.3.2" + tags: + - s4.3-fireground + - apparatus + - safety + sourceRef: NFPA 1001-2019 JPR 4.3.2 prerequisites: - ppe-donning-doffing knowledgePoints: @@ -336,26 +342,29 @@ concepts: problems: - id: apparatus-resp-p1 type: multiple_choice - question: "When riding on fire apparatus responding to an emergency, firefighters must:" + question: 'When riding on fire apparatus responding to an emergency, firefighters must:' options: - - "Stand on the tailboard for quick dismount upon arrival" - - "Be seated with seatbelts securely fastened in an approved riding position at all times while the vehicle is in motion" - - "Sit in the cab but seatbelts are optional during emergency response" - - "Ride on the running boards if all interior seats are occupied" + - Stand on the tailboard for quick dismount upon arrival + - Be seated with seatbelts securely fastened in an approved riding position at all times while the vehicle is in motion + - Sit in the cab but seatbelts are optional during emergency response + - Ride on the running boards if all interior seats are occupied correct: 1 - explanation: "NFPA 1500 and NFPA 1901 require all firefighters to be seated and belted in approved riding positions whenever the apparatus is in motion. Standing on tailboards, riding running boards, or riding unbelted are prohibited. Firefighter fatalities from falls and ejections during response have driven these requirements." + explanation: NFPA 1500 and NFPA 1901 require all firefighters to be seated and belted in approved riding positions whenever the apparatus is in motion. Standing on tailboards, riding running boards, or riding unbelted are prohibited. Firefighter fatalities from falls and ejections during response have driven these requirements. - id: apparatus-resp-p2 type: true_false - question: "A firefighter may don SCBA while the apparatus is in motion, provided they remain seated and belted." - correct: "true" - explanation: "Many departments train firefighters to don the SCBA backpack assembly while seated and belted in the cab. The seat-mounted SCBA bracket allows the firefighter to slip into the harness while belted. This saves critical time on arrival. However, the firefighter must remain belted at all times — standing to don SCBA while the apparatus is moving is prohibited." - + question: A firefighter may don SCBA while the apparatus is in motion, provided they remain seated and belted. + correct: 'true' + explanation: Many departments train firefighters to don the SCBA backpack assembly while seated and belted in the cab. The seat-mounted SCBA bracket allows the firefighter to slip into the harness while belted. This saves critical time on arrival. However, the firefighter must remain belted at all times — standing to don SCBA while the apparatus is moving is prohibited. + keyPrerequisite: ppe-donning-doffing - id: scene-safety-traffic - name: "Scene Safety — Traffic Control" + name: Scene Safety — Traffic Control difficulty: 3 estimatedMinutes: 15 - tags: [s4.3-fireground, scene-safety, traffic] - sourceRef: "NFPA 1001-2019 JPR 4.3.3" + tags: + - s4.3-fireground + - scene-safety + - traffic + sourceRef: NFPA 1001-2019 JPR 4.3.3 prerequisites: - ppe-donning-doffing knowledgePoints: @@ -363,26 +372,29 @@ concepts: problems: - id: traffic-ctrl-p1 type: multiple_choice - question: "When establishing a traffic control zone at a highway incident, apparatus should be positioned:" + question: 'When establishing a traffic control zone at a highway incident, apparatus should be positioned:' options: - - "Parallel to the travel lanes with all lights off to avoid distracting drivers" - - "At an angle upstream of the incident to create a physical barrier (block position) between traffic and the work zone, with warning lights activated" - - "As close to the incident as possible regardless of traffic flow direction" - - "On the shoulder only, to keep travel lanes open" + - Parallel to the travel lanes with all lights off to avoid distracting drivers + - At an angle upstream of the incident to create a physical barrier (block position) between traffic and the work zone, with warning lights activated + - As close to the incident as possible regardless of traffic flow direction + - On the shoulder only, to keep travel lanes open correct: 1 - explanation: "Apparatus is positioned at an angle upstream (between oncoming traffic and the work zone) to create a physical barrier that protects personnel. This 'block' position uses the apparatus as a shield. Warning lights, cones, and flares create an advance warning area. This practice follows the Manual on Uniform Traffic Control Devices (MUTCD) and NFPA 1500 guidelines." + explanation: Apparatus is positioned at an angle upstream (between oncoming traffic and the work zone) to create a physical barrier that protects personnel. This 'block' position uses the apparatus as a shield. Warning lights, cones, and flares create an advance warning area. This practice follows the Manual on Uniform Traffic Control Devices (MUTCD) and NFPA 1500 guidelines. - id: traffic-ctrl-p2 type: fill_blank - question: "Firefighters operating near traffic at an emergency scene must wear ANSI/ISEA-compliant high-visibility ___ vests." - correct: "safety" - explanation: "NFPA 1500 requires firefighters operating in or near traffic to wear ANSI/ISEA 207-compliant high-visibility safety vests. These fluorescent and retroreflective vests make firefighters visible to approaching motorists, significantly reducing the risk of being struck. Turnout gear alone does not meet highway visibility requirements." - + question: Firefighters operating near traffic at an emergency scene must wear ANSI/ISEA-compliant high-visibility ___ vests. + correct: safety + explanation: NFPA 1500 requires firefighters operating in or near traffic to wear ANSI/ISEA 207-compliant high-visibility safety vests. These fluorescent and retroreflective vests make firefighters visible to approaching motorists, significantly reducing the risk of being struck. Turnout gear alone does not meet highway visibility requirements. + keyPrerequisite: ppe-donning-doffing - id: scene-safety-electrical - name: "Scene Safety — Electrical Hazards and Downed Wires" + name: Scene Safety — Electrical Hazards and Downed Wires difficulty: 4 estimatedMinutes: 15 - tags: [s4.3-fireground, scene-safety, electrical] - sourceRef: "NFPA 1001-2019 JPR 4.3.3" + tags: + - s4.3-fireground + - scene-safety + - electrical + sourceRef: NFPA 1001-2019 JPR 4.3.3 prerequisites: - ppe-donning-doffing knowledgePoints: @@ -390,28 +402,29 @@ concepts: problems: - id: elec-hazard-p1 type: multiple_choice - question: "When encountering downed power lines at an emergency scene, the safe approach distance for firefighters without specialized training is:" + question: 'When encountering downed power lines at an emergency scene, the safe approach distance for firefighters without specialized training is:' options: - - "3 metres (10 feet) in all directions from the wire" - - "A minimum of 10 metres (33 feet) in all directions — treat all downed wires as energized until the utility confirms de-energization" - - "Close enough to move the wire with a dry wooden pole" - - "5 metres (16 feet) on dry pavement only" + - 3 metres (10 feet) in all directions from the wire + - A minimum of 10 metres (33 feet) in all directions — treat all downed wires as energized until the utility confirms de-energization + - Close enough to move the wire with a dry wooden pole + - 5 metres (16 feet) on dry pavement only correct: 1 - explanation: "All downed wires must be treated as energized and lethal. A minimum 10-metre (33-foot) safe zone in all directions is the standard. Ground gradient (step potential) can electrocute anyone within this zone, even without directly touching the wire. Only the utility company can confirm de-energization. Moving wires with any tool is extremely dangerous without specialized training." + explanation: All downed wires must be treated as energized and lethal. A minimum 10-metre (33-foot) safe zone in all directions is the standard. Ground gradient (step potential) can electrocute anyone within this zone, even without directly touching the wire. Only the utility company can confirm de-energization. Moving wires with any tool is extremely dangerous without specialized training. - id: elec-hazard-p2 type: true_false - question: "A downed power line that is not sparking or arcing can be safely assumed to be de-energized." - correct: "false" - explanation: "A downed power line can be fully energized without any visible sparking, arcing, or movement. Automatic reclosers on the power grid can re-energize a line at any time without warning. The ONLY way to confirm a line is de-energized is through direct confirmation from the utility company. Always treat every downed wire as live and lethal." - - # --- Forcible entry --- - + question: A downed power line that is not sparking or arcing can be safely assumed to be de-energized. + correct: 'false' + explanation: A downed power line can be fully energized without any visible sparking, arcing, or movement. Automatic reclosers on the power grid can re-energize a line at any time without warning. The ONLY way to confirm a line is de-energized is through direct confirmation from the utility company. Always treat every downed wire as live and lethal. + keyPrerequisite: ppe-donning-doffing - id: forcible-entry - name: "Forcible Entry Techniques" + name: Forcible Entry Techniques difficulty: 5 estimatedMinutes: 25 - tags: [s4.3-fireground, forcible-entry, tools] - sourceRef: "NFPA 1001-2019 JPR 4.3.4" + tags: + - s4.3-fireground + - forcible-entry + - tools + sourceRef: NFPA 1001-2019 JPR 4.3.4 prerequisites: - ppe-donning-doffing knowledgePoints: @@ -419,28 +432,30 @@ concepts: problems: - id: force-entry-p1 type: multiple_choice - question: "The 'irons' (also called 'married irons') consist of which two tools carried together for forcible entry?" + question: The 'irons' (also called 'married irons') consist of which two tools carried together for forcible entry? options: - - "Pike pole and ceiling hook" - - "Flat-head axe and Halligan bar" - - "Bolt cutters and K-tool" - - "Sledgehammer and pry bar" + - Pike pole and ceiling hook + - Flat-head axe and Halligan bar + - Bolt cutters and K-tool + - Sledgehammer and pry bar correct: 1 - explanation: "The 'irons' are the flat-head axe and Halligan bar, carried together as a matched set. The flat-head axe can be used to strike the fork or adze of the Halligan to drive it into a door frame, while the Halligan provides prying capability. Together they can force virtually any conventional door. This combination is the most versatile forcible entry toolset in the fire service." + explanation: The 'irons' are the flat-head axe and Halligan bar, carried together as a matched set. The flat-head axe can be used to strike the fork or adze of the Halligan to drive it into a door frame, while the Halligan provides prying capability. Together they can force virtually any conventional door. This combination is the most versatile forcible entry toolset in the fire service. - id: force-entry-p2 type: fill_blank - question: "When forcing an inward-opening door, the Halligan bar is placed near the lock with the ___ end inserted between the door and the frame." - correct: "fork" - explanation: "The fork (also called the claw) end of the Halligan is inserted into the gap between the door and frame near the lock. Once set, it is driven in further using the flat-head axe striking the back of the Halligan, then pried to force the door open. The adze end is typically used on outward-opening doors." - - # --- Emergency egress --- - + question: When forcing an inward-opening door, the Halligan bar is placed near the lock with the ___ end inserted between the door and the frame. + correct: fork + explanation: The fork (also called the claw) end of the Halligan is inserted into the gap between the door and frame near the lock. Once set, it is driven in further using the flat-head axe striking the back of the Halligan, then pried to force the door open. The adze end is typically used on outward-opening doors. + keyPrerequisite: ppe-donning-doffing - id: emergency-egress - name: "Emergency Egress from Hazardous Environments" + name: Emergency Egress from Hazardous Environments difficulty: 6 estimatedMinutes: 20 - tags: [s4.3-fireground, egress, emergency, survival] - sourceRef: "NFPA 1001-2019 JPR 4.3.5" + tags: + - s4.3-fireground + - egress + - emergency + - survival + sourceRef: NFPA 1001-2019 JPR 4.3.5 prerequisites: - ppe-donning-doffing - scba-donning-doffing-breathing @@ -449,132 +464,134 @@ concepts: problems: - id: emerg-egress-p1 type: multiple_choice - question: "If a firefighter becomes disoriented in zero-visibility conditions and cannot locate a hose line, which technique should be used to find an exterior wall?" + question: If a firefighter becomes disoriented in zero-visibility conditions and cannot locate a hose line, which technique should be used to find an exterior wall? options: - - "Stand up to look above the smoke layer" - - "Stay low and crawl in a straight line until contacting a wall, then follow the wall to locate a window or door" - - "Remove SCBA to fit through smaller openings" - - "Wait in place for conditions to improve" + - Stand up to look above the smoke layer + - Stay low and crawl in a straight line until contacting a wall, then follow the wall to locate a window or door + - Remove SCBA to fit through smaller openings + - Wait in place for conditions to improve correct: 1 - explanation: "Staying low beneath the thermal layer and crawling in a straight line to reach a wall is the primary technique. Once a wall is reached, the firefighter follows it (maintaining wall contact) to locate a door, window, or other exit. Listening for sounds from outside, feeling for air movement, and transmitting a Mayday are also critical survival actions." + explanation: Staying low beneath the thermal layer and crawling in a straight line to reach a wall is the primary technique. Once a wall is reached, the firefighter follows it (maintaining wall contact) to locate a door, window, or other exit. Listening for sounds from outside, feeling for air movement, and transmitting a Mayday are also critical survival actions. - id: emerg-egress-p2 type: true_false - question: "A firefighter who becomes trapped should activate their PASS device manually and transmit a Mayday before attempting self-rescue." - correct: "true" - explanation: "Activating the PASS device manually (rather than waiting for the motion sensor) immediately alerts nearby crews. Transmitting a Mayday with LUNAR information notifies incident command to deploy the RIT. These two actions take seconds and dramatically increase the chance of rescue, even while the firefighter simultaneously attempts self-rescue." - - # --- Ladders --- - + question: A firefighter who becomes trapped should activate their PASS device manually and transmit a Mayday before attempting self-rescue. + correct: 'true' + explanation: Activating the PASS device manually (rather than waiting for the motion sensor) immediately alerts nearby crews. Transmitting a Mayday with LUNAR information notifies incident command to deploy the RIT. These two actions take seconds and dramatically increase the chance of rescue, even while the firefighter simultaneously attempts self-rescue. + keyPrerequisite: scba-donning-doffing-breathing - id: ground-ladder-operations - name: "Ground Ladder Operations" + name: Ground Ladder Operations difficulty: 5 estimatedMinutes: 35 - tags: [s4.3-fireground, ladders, foundational] - sourceRef: "NFPA 1001-2019 JPR 4.3.6" + tags: + - s4.3-fireground + - ladders + - foundational + sourceRef: NFPA 1001-2019 JPR 4.3.6 prerequisites: - ppe-donning-doffing knowledgePoints: - id: ladder-types-construction - instruction: "content/ab-ff1/ladder-types.md" - workedExample: "content/ab-ff1/ladder-types-ex.md" + instruction: content/ab-ff1/ladder-types.md + workedExample: content/ab-ff1/ladder-types-ex.md problems: - id: ladder-type-p1 type: multiple_choice - question: "Which type of ground ladder is MOST appropriate for accessing a flat commercial roof at approximately 9 metres (30 feet)?" + question: Which type of ground ladder is MOST appropriate for accessing a flat commercial roof at approximately 9 metres (30 feet)? options: - - "14-foot roof ladder" - - "24-foot extension ladder" - - "35-foot extension ladder" - - "10-foot folding (attic) ladder" + - 14-foot roof ladder + - 24-foot extension ladder + - 35-foot extension ladder + - 10-foot folding (attic) ladder correct: 2 - explanation: "A 35-foot extension ladder is appropriate for reaching a 30-foot roof. The working length of an extension ladder is reduced by overlap of fly sections and the requirement that the tip extend 3-5 rungs above the roofline. A 24-foot ladder would not have sufficient working height. Roof ladders and folding ladders serve different purposes." + explanation: A 35-foot extension ladder is appropriate for reaching a 30-foot roof. The working length of an extension ladder is reduced by overlap of fly sections and the requirement that the tip extend 3-5 rungs above the roofline. A 24-foot ladder would not have sufficient working height. Roof ladders and folding ladders serve different purposes. - id: ladder-type-p2 type: multiple_choice - question: "What is the PRIMARY purpose of a roof (hook) ladder?" + question: What is the PRIMARY purpose of a roof (hook) ladder? options: - - "To extend reach beyond 40 feet" - - "To provide a stable working platform on a pitched roof by hooking retractable hooks over the ridge" - - "To bridge gaps between buildings" - - "To serve as a makeshift stretcher for victim removal" + - To extend reach beyond 40 feet + - To provide a stable working platform on a pitched roof by hooking retractable hooks over the ridge + - To bridge gaps between buildings + - To serve as a makeshift stretcher for victim removal correct: 1 - explanation: "A roof ladder has retractable folding hooks at the tip that, when deployed, hook over the roof ridge. This distributes the firefighter's weight across multiple roof members and prevents sliding on a pitched roof, providing a stable working platform for vertical ventilation or rescue operations." + explanation: A roof ladder has retractable folding hooks at the tip that, when deployed, hook over the roof ridge. This distributes the firefighter's weight across multiple roof members and prevents sliding on a pitched roof, providing a stable working platform for vertical ventilation or rescue operations. - id: ladder-type-p3 type: fill_blank - question: "The folding ladder (also called an ___ ladder) is designed for use in confined interior spaces such as accessing scuttle holes or attic openings." - correct: "attic" - explanation: "The folding (attic) ladder is a narrow, hinged ladder that can be carried through doorways and hallways, then unfolded for interior access to attics, lofts, or scuttle holes where standard ladders cannot be maneuvered." - + question: The folding ladder (also called an ___ ladder) is designed for use in confined interior spaces such as accessing scuttle holes or attic openings. + correct: attic + explanation: The folding (attic) ladder is a narrow, hinged ladder that can be carried through doorways and hallways, then unfolded for interior access to attics, lofts, or scuttle holes where standard ladders cannot be maneuvered. + keyPrerequisite: ppe-donning-doffing - id: ladder-placement-angles - instruction: "content/ab-ff1/ladder-placement.md" - workedExample: "content/ab-ff1/ladder-placement-ex.md" + instruction: content/ab-ff1/ladder-placement.md + workedExample: content/ab-ff1/ladder-placement-ex.md problems: - id: ladder-place-p1 type: multiple_choice - question: "What is the correct climbing angle for a ground ladder placed against a structure?" + question: What is the correct climbing angle for a ground ladder placed against a structure? options: - - "Approximately 60 degrees — base distance equals one-half the working length" - - "Approximately 75 degrees — base distance equals one-quarter the working length" - - "Approximately 90 degrees — flush against the wall" - - "Approximately 45 degrees — base distance equals working length" + - Approximately 60 degrees — base distance equals one-half the working length + - Approximately 75 degrees — base distance equals one-quarter the working length + - Approximately 90 degrees — flush against the wall + - Approximately 45 degrees — base distance equals working length correct: 1 - explanation: "The correct climbing angle is approximately 75 degrees from the ground. A quick field check: stand at the base with toes touching the beams, arms extended straight forward — your palms should rest comfortably on the rung at shoulder height. The base-to-wall distance should be approximately one-quarter of the working length." + explanation: 'The correct climbing angle is approximately 75 degrees from the ground. A quick field check: stand at the base with toes touching the beams, arms extended straight forward — your palms should rest comfortably on the rung at shoulder height. The base-to-wall distance should be approximately one-quarter of the working length.' - id: ladder-place-p2 type: multiple_choice - question: "When placing a ladder for roof access, how many rungs should extend above the roofline?" + question: When placing a ladder for roof access, how many rungs should extend above the roofline? options: - - "1-2 rungs" - - "3-5 rungs" - - "At least 7 rungs" - - "The tip should be flush with the roofline" + - 1-2 rungs + - 3-5 rungs + - At least 7 rungs + - The tip should be flush with the roofline correct: 1 - explanation: "3-5 rungs (approximately 3 feet / 1 metre) above the roofline provides a visible target for firefighters returning to the ladder, a stable handhold for transitioning from the roof to the ladder, and sufficient height for safe mounting and dismounting." + explanation: 3-5 rungs (approximately 3 feet / 1 metre) above the roofline provides a visible target for firefighters returning to the ladder, a stable handhold for transitioning from the roof to the ladder, and sufficient height for safe mounting and dismounting. - id: ladder-place-p3 type: multiple_choice - question: "What is the MOST important consideration when selecting a ladder placement location on a fire building?" + question: What is the MOST important consideration when selecting a ladder placement location on a fire building? options: - - "Proximity to the front door" - - "Wind direction" - - "Firm, level footing on a stable surface away from overhead hazards (power lines, falling debris)" - - "Shortest carry distance from the apparatus" + - Proximity to the front door + - Wind direction + - Firm, level footing on a stable surface away from overhead hazards (power lines, falling debris) + - Shortest carry distance from the apparatus correct: 2 - explanation: "A stable foundation is the most critical factor. A ladder placed on soft, uneven, or unstable ground can shift or sink under load, causing a catastrophic failure. Overhead hazards (power lines, falling debris) must also be assessed. While proximity and carry distance matter tactically, they never override safe placement." - + explanation: A stable foundation is the most critical factor. A ladder placed on soft, uneven, or unstable ground can shift or sink under load, causing a catastrophic failure. Overhead hazards (power lines, falling debris) must also be assessed. While proximity and carry distance matter tactically, they never override safe placement. + keyPrerequisite: ground-ladder-operations - id: ladder-climbing-working - instruction: "content/ab-ff1/ladder-climbing.md" + instruction: content/ab-ff1/ladder-climbing.md problems: - id: ladder-climb-p1 type: multiple_choice - question: "When climbing a ground ladder, the firefighter should maintain three points of contact and look:" + question: 'When climbing a ground ladder, the firefighter should maintain three points of contact and look:' options: - - "Down at the rungs to ensure proper foot placement" - - "Straight ahead or slightly upward toward the objective" - - "At the base of the ladder to ensure stability" - - "Over their shoulder to monitor the fire" + - Down at the rungs to ensure proper foot placement + - Straight ahead or slightly upward toward the objective + - At the base of the ladder to ensure stability + - Over their shoulder to monitor the fire correct: 1 - explanation: "Climbers should look straight ahead or slightly upward toward the objective. Looking down can cause disorientation and slow climbing speed. Three points of contact (two hands and one foot, or two feet and one hand) must be maintained at all times. The climber's arms should slide along the beams, not grip individual rungs." - + explanation: Climbers should look straight ahead or slightly upward toward the objective. Looking down can cause disorientation and slow climbing speed. Three points of contact (two hands and one foot, or two feet and one hand) must be maintained at all times. The climber's arms should slide along the beams, not grip individual rungs. + keyPrerequisite: ground-ladder-operations - id: ladder-heeling-securing - instruction: "content/ab-ff1/ladder-securing.md" + instruction: content/ab-ff1/ladder-securing.md problems: - id: ladder-heel-p1 type: multiple_choice - question: "If no firefighter is available to heel the ladder, what is the PREFERRED method to secure it?" + question: If no firefighter is available to heel the ladder, what is the PREFERRED method to secure it? options: - - "Lean it at a shallower angle (60 degrees)" - - "Tie the halyard to a fixed object at the base" - - "Secure the tip to the structure using a roof hook or ladder strap, or tie off the base to a fixed anchor point" - - "Have the climber ascend quickly before it can shift" + - Lean it at a shallower angle (60 degrees) + - Tie the halyard to a fixed object at the base + - Secure the tip to the structure using a roof hook or ladder strap, or tie off the base to a fixed anchor point + - Have the climber ascend quickly before it can shift correct: 2 - explanation: "When no one can heel (foot) the ladder, securing both the tip and base is the standard. The tip can be tied to a structural member, secured with a ladder strap, or the hooks on a roof ladder engaged. The base can be tied to a fixed anchor. Simply adjusting the angle or rushing the climb introduces unacceptable risk." - - # --- Vehicle fire --- - + explanation: When no one can heel (foot) the ladder, securing both the tip and base is the standard. The tip can be tied to a structural member, secured with a ladder strap, or the hooks on a roof ladder engaged. The base can be tied to a fixed anchor. Simply adjusting the angle or rushing the climb introduces unacceptable risk. + keyPrerequisite: ground-ladder-operations - id: vehicle-fire-attack - name: "Vehicle Fire Attack" + name: Vehicle Fire Attack difficulty: 4 estimatedMinutes: 20 - tags: [s4.3-fireground, vehicle-fire, hose-operations] - sourceRef: "NFPA 1001-2019 JPR 4.3.7" + tags: + - s4.3-fireground + - vehicle-fire + - hose-operations + sourceRef: NFPA 1001-2019 JPR 4.3.7 prerequisites: - ppe-donning-doffing - scba-donning-doffing-breathing @@ -583,28 +600,29 @@ concepts: problems: - id: veh-fire-p1 type: multiple_choice - question: "When approaching a vehicle fire, the attack team should approach from:" + question: 'When approaching a vehicle fire, the attack team should approach from:' options: - - "Directly from the front of the vehicle" - - "The upwind/uphill side at a 45-degree angle, avoiding the bumper areas due to strut/shock absorber and bumper piston hazards" - - "Directly from the rear for the best view of the fire" - - "Any direction — vehicle fires pose no directional hazards" + - Directly from the front of the vehicle + - The upwind/uphill side at a 45-degree angle, avoiding the bumper areas due to strut/shock absorber and bumper piston hazards + - Directly from the rear for the best view of the fire + - Any direction — vehicle fires pose no directional hazards correct: 1 - explanation: "Approaching at a 45-degree angle from upwind avoids toxic smoke inhalation and positions the team away from bumper areas where hydraulic struts, shock absorbers, and bumper pistons can explode under heat and become projectiles. The 45-degree angle also provides partial protection from potential fuel tank rupture or tire failure." + explanation: Approaching at a 45-degree angle from upwind avoids toxic smoke inhalation and positions the team away from bumper areas where hydraulic struts, shock absorbers, and bumper pistons can explode under heat and become projectiles. The 45-degree angle also provides partial protection from potential fuel tank rupture or tire failure. - id: veh-fire-p2 type: true_false - question: "Vehicle fires involving alternative fuel vehicles (hybrid/electric) may present electrical shock hazards from high-voltage battery systems." - correct: "true" - explanation: "Hybrid and electric vehicles contain high-voltage battery systems (typically 200-800 volts DC) that can present severe electrical shock hazards to firefighters. These batteries can reignite hours after extinguishment (thermal runaway). Firefighters should identify the vehicle type, consult Emergency Response Guides (ERG), avoid cutting into high-voltage cables (often orange), and use copious water for battery fires." - - # --- Exterior fire attack --- - + question: Vehicle fires involving alternative fuel vehicles (hybrid/electric) may present electrical shock hazards from high-voltage battery systems. + correct: 'true' + explanation: Hybrid and electric vehicles contain high-voltage battery systems (typically 200-800 volts DC) that can present severe electrical shock hazards to firefighters. These batteries can reignite hours after extinguishment (thermal runaway). Firefighters should identify the vehicle type, consult Emergency Response Guides (ERG), avoid cutting into high-voltage cables (often orange), and use copious water for battery fires. + keyPrerequisite: scba-donning-doffing-breathing - id: exterior-class-a-fire-attack - name: "Exterior/Class A Fire Attack (Stacked Materials, Trash Containers)" + name: Exterior/Class A Fire Attack (Stacked Materials, Trash Containers) difficulty: 3 estimatedMinutes: 15 - tags: [s4.3-fireground, exterior-fire, class-a] - sourceRef: "NFPA 1001-2019 JPR 4.3.8" + tags: + - s4.3-fireground + - exterior-fire + - class-a + sourceRef: NFPA 1001-2019 JPR 4.3.8 prerequisites: - ppe-donning-doffing knowledgePoints: @@ -612,28 +630,29 @@ concepts: problems: - id: ext-class-a-p1 type: multiple_choice - question: "When attacking an exterior Class A fire involving stacked lumber or pallets, the MOST effective approach is:" + question: 'When attacking an exterior Class A fire involving stacked lumber or pallets, the MOST effective approach is:' options: - - "Apply a wide fog pattern from a distance to cool the entire stack" - - "Apply a straight stream to penetrate deep into the stack, then break apart (overhaul) the pile to expose and extinguish hidden pockets of fire" - - "Surround the pile with foam and let it smother" - - "Wait for the fire to burn down before applying water" + - Apply a wide fog pattern from a distance to cool the entire stack + - Apply a straight stream to penetrate deep into the stack, then break apart (overhaul) the pile to expose and extinguish hidden pockets of fire + - Surround the pile with foam and let it smother + - Wait for the fire to burn down before applying water correct: 1 - explanation: "Stacked materials require penetration to reach deep-seated fire. A straight stream delivers water into the core of the pile. After knockdown, the pile must be broken apart (pulled apart with pike poles or other tools) to expose hidden embers and hot spots, then fully extinguished. Surface application alone leaves fire burning deep inside." + explanation: Stacked materials require penetration to reach deep-seated fire. A straight stream delivers water into the core of the pile. After knockdown, the pile must be broken apart (pulled apart with pike poles or other tools) to expose hidden embers and hot spots, then fully extinguished. Surface application alone leaves fire burning deep inside. - id: ext-class-a-p2 type: fill_blank - question: "Class A fires involve ___ combustible materials such as wood, paper, cloth, and rubber." - correct: "ordinary" - explanation: "Class A fires involve ordinary combustible materials — solids that leave ash when burned. These include wood, paper, cloth, rubber, and many plastics. They are extinguished primarily by cooling with water. This is distinguished from Class B (flammable liquids), Class C (energized electrical), Class D (combustible metals), and Class K (cooking oils)." - - # --- Master streams --- - + question: Class A fires involve ___ combustible materials such as wood, paper, cloth, and rubber. + correct: ordinary + explanation: Class A fires involve ordinary combustible materials — solids that leave ash when burned. These include wood, paper, cloth, rubber, and many plastics. They are extinguished primarily by cooling with water. This is distinguished from Class B (flammable liquids), Class C (energized electrical), Class D (combustible metals), and Class K (cooking oils). + keyPrerequisite: ppe-donning-doffing - id: master-stream-operations - name: "Master Stream Operations" + name: Master Stream Operations difficulty: 5 estimatedMinutes: 20 - tags: [s4.3-fireground, master-stream, water-supply] - sourceRef: "NFPA 1001-2019 JPR 4.3.8" + tags: + - s4.3-fireground + - master-stream + - water-supply + sourceRef: NFPA 1001-2019 JPR 4.3.8 prerequisites: - ppe-donning-doffing - water-supply-hydrant @@ -642,28 +661,30 @@ concepts: problems: - id: master-stream-p1 type: multiple_choice - question: "A master stream device is typically defined as any appliance delivering more than:" + question: 'A master stream device is typically defined as any appliance delivering more than:' options: - - "100 GPM (380 LPM)" - - "200 GPM (760 LPM)" - - "350 GPM (1325 LPM)" - - "500 GPM (1900 LPM)" + - 100 GPM (380 LPM) + - 200 GPM (760 LPM) + - 350 GPM (1325 LPM) + - 500 GPM (1900 LPM) correct: 2 - explanation: "Master stream devices (deck guns, portable monitors, ladder pipes) are defined as appliances capable of flowing more than 350 GPM (1325 LPM). They are used for defensive operations when fire conditions exceed the capability of hand-held attack lines. Their deployment typically signals a transition from offensive to defensive strategy." + explanation: Master stream devices (deck guns, portable monitors, ladder pipes) are defined as appliances capable of flowing more than 350 GPM (1325 LPM). They are used for defensive operations when fire conditions exceed the capability of hand-held attack lines. Their deployment typically signals a transition from offensive to defensive strategy. - id: master-stream-p2 type: true_false - question: "When a master stream is being directed into a structure, no firefighters should be operating inside that structure." - correct: "true" - explanation: "Master stream deployment is a defensive tactic. The volume of water (350+ GPM) creates structural collapse hazards from water weight, can push fire and steam onto interior crews, and indicates conditions too dangerous for interior operations. All interior crews must be withdrawn and accounted for before master streams are deployed. Operating interior crews and master streams simultaneously is a critical safety violation." - - # --- Search and rescue --- - + question: When a master stream is being directed into a structure, no firefighters should be operating inside that structure. + correct: 'true' + explanation: Master stream deployment is a defensive tactic. The volume of water (350+ GPM) creates structural collapse hazards from water weight, can push fire and steam onto interior crews, and indicates conditions too dangerous for interior operations. All interior crews must be withdrawn and accounted for before master streams are deployed. Operating interior crews and master streams simultaneously is a critical safety violation. + keyPrerequisite: water-supply-hydrant - id: search-rescue-techniques - name: "Search and Rescue Techniques" + name: Search and Rescue Techniques difficulty: 7 estimatedMinutes: 30 - tags: [s4.3-fireground, search, rescue, interior] - sourceRef: "NFPA 1001-2019 JPR 4.3.9" + tags: + - s4.3-fireground + - search + - rescue + - interior + sourceRef: NFPA 1001-2019 JPR 4.3.9 prerequisites: - scba-donning-doffing-breathing - ppe-donning-doffing @@ -680,26 +701,29 @@ concepts: problems: - id: search-tech-p1 type: multiple_choice - question: "What is the PRIMARY difference between a primary search and a secondary search?" + question: What is the PRIMARY difference between a primary search and a secondary search? options: - - "Primary search uses thermal imaging; secondary does not" - - "Primary search is a rapid, systematic search for victims conducted under fire conditions; secondary search is a thorough, slower search after fire control to ensure no victims were missed" - - "Primary search covers only the fire floor; secondary covers all floors" - - "Primary search is conducted by the first engine; secondary by the truck company only" + - Primary search uses thermal imaging; secondary does not + - Primary search is a rapid, systematic search for victims conducted under fire conditions; secondary search is a thorough, slower search after fire control to ensure no victims were missed + - Primary search covers only the fire floor; secondary covers all floors + - Primary search is conducted by the first engine; secondary by the truck company only correct: 1 - explanation: "The primary search is a rapid, aggressive search conducted as soon as possible — often under active fire conditions — focusing on areas most likely to have viable victims (bedrooms, areas near the fire). The secondary search is a thorough, methodical search conducted after fire control to confirm that every space has been checked and no victims were missed." + explanation: The primary search is a rapid, aggressive search conducted as soon as possible — often under active fire conditions — focusing on areas most likely to have viable victims (bedrooms, areas near the fire). The secondary search is a thorough, methodical search conducted after fire control to confirm that every space has been checked and no victims were missed. - id: search-tech-p2 type: fill_blank - question: "During a primary search in zero visibility, firefighters maintain contact with a wall using one hand and sweep the floor with the other hand or a tool. This technique is called a ___ search pattern." - correct: "wall" - explanation: "The wall (or perimeter) search pattern involves the search team entering a room and systematically following the walls while sweeping inward with a tool or free hand. This ensures complete coverage of the room's perimeter and prevents disorientation. The team maintains a reference point (the wall) at all times to ensure they can find their way back to the entry point." - + question: During a primary search in zero visibility, firefighters maintain contact with a wall using one hand and sweep the floor with the other hand or a tool. This technique is called a ___ search pattern. + correct: wall + explanation: The wall (or perimeter) search pattern involves the search team entering a room and systematically following the walls while sweeping inward with a tool or free hand. This ensures complete coverage of the room's perimeter and prevents disorientation. The team maintains a reference point (the wall) at all times to ensure they can find their way back to the entry point. + keyPrerequisite: scba-donning-doffing-breathing - id: victim-rescue-from-ladder - name: "Victim Rescue from a Ladder" + name: Victim Rescue from a Ladder difficulty: 6 estimatedMinutes: 20 - tags: [s4.3-fireground, rescue, ladders] - sourceRef: "NFPA 1001-2019 JPR 4.3.9" + tags: + - s4.3-fireground + - rescue + - ladders + sourceRef: NFPA 1001-2019 JPR 4.3.9 prerequisites: - ground-ladder-operations - ppe-donning-doffing @@ -708,55 +732,57 @@ concepts: problems: - id: ladder-rescue-p1 type: multiple_choice - question: "When removing an unconscious victim down a ground ladder, the rescuer should:" + question: 'When removing an unconscious victim down a ground ladder, the rescuer should:' options: - - "Carry the victim over one shoulder in a fireman's carry" - - "Place the victim between the rescuer and the ladder with the victim's feet on the rungs and the rescuer's arms under the victim's armpits, descending rung by rung" - - "Lower the victim headfirst on a rope alongside the ladder" - - "Slide the victim down the beams of the ladder" + - Carry the victim over one shoulder in a fireman's carry + - Place the victim between the rescuer and the ladder with the victim's feet on the rungs and the rescuer's arms under the victim's armpits, descending rung by rung + - Lower the victim headfirst on a rope alongside the ladder + - Slide the victim down the beams of the ladder correct: 1 - explanation: "The standard unconscious victim ladder removal technique positions the victim between the rescuer and the ladder. The victim's feet rest on the rungs with the rescuer's arms threaded under the victim's armpits and hands gripping the rungs. This distributes the weight, maintains three points of contact, and allows controlled descent. A second firefighter should heel the ladder during the operation." + explanation: The standard unconscious victim ladder removal technique positions the victim between the rescuer and the ladder. The victim's feet rest on the rungs with the rescuer's arms threaded under the victim's armpits and hands gripping the rungs. This distributes the weight, maintains three points of contact, and allows controlled descent. A second firefighter should heel the ladder during the operation. - id: ladder-rescue-p2 type: true_false - question: "When performing a ladder rescue, the ladder should be heeled by a second firefighter or mechanically secured at all times." - correct: "true" - explanation: "The combined weight of rescuer and victim, along with the dynamic forces of descent, place extreme loads on the ladder. A heeled or secured ladder prevents shifting, sliding, or collapse. If a second firefighter is not available to heel the ladder, it must be tied off or mechanically secured before the rescue descent begins." - - # --- Fire behavior (prerequisite for interior ops and ventilation) --- - + question: When performing a ladder rescue, the ladder should be heeled by a second firefighter or mechanically secured at all times. + correct: 'true' + explanation: The combined weight of rescuer and victim, along with the dynamic forces of descent, place extreme loads on the ladder. A heeled or secured ladder prevents shifting, sliding, or collapse. If a second firefighter is not available to heel the ladder, it must be tied off or mechanically secured before the rescue descent begins. + keyPrerequisite: ground-ladder-operations - id: fire-behavior-fundamentals - name: "Fire Behavior Fundamentals" + name: Fire Behavior Fundamentals difficulty: 3 estimatedMinutes: 25 - tags: [s4.3-fireground, fire-science, foundational] - sourceRef: "NFPA 1001-2019 JPR 4.3.10" + tags: + - s4.3-fireground + - fire-science + - foundational + sourceRef: NFPA 1001-2019 JPR 4.3.10 knowledgePoints: - id: fire-behavior-principles problems: - id: fire-behav-p1 type: multiple_choice - question: "The fire tetrahedron consists of four elements required to sustain combustion. Which of the following correctly identifies all four?" + question: The fire tetrahedron consists of four elements required to sustain combustion. Which of the following correctly identifies all four? options: - - "Heat, fuel, oxygen, and water" - - "Heat, fuel, oxygen, and a chemical chain reaction" - - "Heat, fuel, carbon dioxide, and a chemical chain reaction" - - "Fuel, oxygen, smoke, and radiant heat" + - Heat, fuel, oxygen, and water + - Heat, fuel, oxygen, and a chemical chain reaction + - Heat, fuel, carbon dioxide, and a chemical chain reaction + - Fuel, oxygen, smoke, and radiant heat correct: 1 - explanation: "The fire tetrahedron includes heat (energy to raise fuel to ignition temperature), fuel (combustible material), oxygen (oxidizing agent), and a self-sustaining chemical chain reaction. Removing any one of these four elements extinguishes the fire. The tetrahedron superseded the older fire triangle by adding the chemical chain reaction as a distinct element." + explanation: The fire tetrahedron includes heat (energy to raise fuel to ignition temperature), fuel (combustible material), oxygen (oxidizing agent), and a self-sustaining chemical chain reaction. Removing any one of these four elements extinguishes the fire. The tetrahedron superseded the older fire triangle by adding the chemical chain reaction as a distinct element. - id: fire-behav-p2 type: fill_blank - question: "The phenomenon in which all exposed combustible materials in a room simultaneously ignite due to radiant heat feedback is called ___." - correct: "flashover" - explanation: "Flashover occurs when the heat flux from the hot gas layer and burning materials raises all exposed combustible surfaces in a room to their ignition temperature simultaneously. This transition from a growing fire to a fully developed fire is extremely rapid and unsurvivable for unprotected occupants. Temperatures at floor level can exceed 600 degrees Celsius (1100 degrees Fahrenheit)." - - # --- Interior fire attack --- - + question: The phenomenon in which all exposed combustible materials in a room simultaneously ignite due to radiant heat feedback is called ___. + correct: flashover + explanation: Flashover occurs when the heat flux from the hot gas layer and burning materials raises all exposed combustible surfaces in a room to their ignition temperature simultaneously. This transition from a growing fire to a fully developed fire is extremely rapid and unsurvivable for unprotected occupants. Temperatures at floor level can exceed 600 degrees Celsius (1100 degrees Fahrenheit). - id: interior-fire-attack-grade - name: "Interior Fire Attack — Grade Level" + name: Interior Fire Attack — Grade Level difficulty: 8 estimatedMinutes: 40 - tags: [s4.3-fireground, interior-fire, hose-operations, tactics] - sourceRef: "NFPA 1001-2019 JPR 4.3.10" + tags: + - s4.3-fireground + - interior-fire + - hose-operations + - tactics + sourceRef: NFPA 1001-2019 JPR 4.3.10 prerequisites: - scba-donning-doffing-breathing - ppe-donning-doffing @@ -780,104 +806,108 @@ concepts: weight: 0.3 knowledgePoints: - id: interior-attack-size-up - instruction: "content/ab-ff1/interior-attack-sizeup.md" - workedExample: "content/ab-ff1/interior-attack-sizeup-ex.md" + instruction: content/ab-ff1/interior-attack-sizeup.md + workedExample: content/ab-ff1/interior-attack-sizeup-ex.md problems: - id: int-atk-p1 type: multiple_choice - question: "Before making entry for an interior fire attack at grade level, a firefighter should confirm all of the following EXCEPT:" + question: 'Before making entry for an interior fire attack at grade level, a firefighter should confirm all of the following EXCEPT:' options: - - "A charged backup line is in place or being deployed" - - "The building's property tax assessment value" - - "Two-in/two-out rule is satisfied (two firefighters inside, two outside ready for rescue)" - - "Water supply is established or apparatus tank has adequate capacity for initial attack" + - A charged backup line is in place or being deployed + - The building's property tax assessment value + - Two-in/two-out rule is satisfied (two firefighters inside, two outside ready for rescue) + - Water supply is established or apparatus tank has adequate capacity for initial attack correct: 1 - explanation: "OSHA's two-in/two-out requirement (29 CFR 1910.134), confirmed water supply, and a backup line are all critical pre-entry checks. The property tax assessment is not a fireground consideration. Size-up focuses on construction type, fire conditions, life safety, and resource readiness." + explanation: OSHA's two-in/two-out requirement (29 CFR 1910.134), confirmed water supply, and a backup line are all critical pre-entry checks. The property tax assessment is not a fireground consideration. Size-up focuses on construction type, fire conditions, life safety, and resource readiness. - id: int-atk-p2 type: multiple_choice - question: "What does the 'two-in/two-out' rule require?" + question: What does the 'two-in/two-out' rule require? options: - - "Two engines and two trucks on scene before beginning operations" - - "A minimum of two firefighters operating inside the IDLH atmosphere, with at least two firefighters outside equipped and ready to perform rescue" - - "Two hose lines and two ladders deployed before entry" - - "Two ventilation openings created before entry" + - Two engines and two trucks on scene before beginning operations + - A minimum of two firefighters operating inside the IDLH atmosphere, with at least two firefighters outside equipped and ready to perform rescue + - Two hose lines and two ladders deployed before entry + - Two ventilation openings created before entry correct: 1 - explanation: "The two-in/two-out rule (OSHA 29 CFR 1910.134(g)(4)) mandates that when firefighters operate in an IDLH atmosphere, at least two must enter together and at least two must remain outside, fully equipped and ready for immediate rescue. The only exception is a confirmed life-safety rescue situation." - + explanation: The two-in/two-out rule (OSHA 29 CFR 1910.134(g)(4)) mandates that when firefighters operate in an IDLH atmosphere, at least two must enter together and at least two must remain outside, fully equipped and ready for immediate rescue. The only exception is a confirmed life-safety rescue situation. + keyPrerequisite: fire-behavior-fundamentals - id: interior-attack-hose-advance - instruction: "content/ab-ff1/interior-attack-hose.md" - workedExample: "content/ab-ff1/interior-attack-hose-ex.md" + instruction: content/ab-ff1/interior-attack-hose.md + workedExample: content/ab-ff1/interior-attack-hose-ex.md problems: - id: int-hose-p1 type: multiple_choice - question: "When advancing a charged attack line through an interior doorway into a fire room, the nozzle operator should:" + question: 'When advancing a charged attack line through an interior doorway into a fire room, the nozzle operator should:' options: - - "Open the door fully and advance quickly into the center of the room" - - "Stay low, crack the door to read conditions (heat, smoke), apply a brief burst toward the ceiling if needed, then advance along the wall maintaining orientation" - - "Stand upright at the doorway threshold and apply a straight stream directly at the base of visible flames" - - "Wait outside the door until the fire self-ventilates through a window" + - Open the door fully and advance quickly into the center of the room + - Stay low, crack the door to read conditions (heat, smoke), apply a brief burst toward the ceiling if needed, then advance along the wall maintaining orientation + - Stand upright at the doorway threshold and apply a straight stream directly at the base of visible flames + - Wait outside the door until the fire self-ventilates through a window correct: 1 - explanation: "Staying low keeps the firefighter below the thermal layer. Cracking the door first allows reading fire conditions and prevents sudden introduction of air that could worsen conditions. A brief ceiling-level burst (penciling) can cool the thermal layer. Advancing along the wall maintains orientation and a known path back to the exit." + explanation: Staying low keeps the firefighter below the thermal layer. Cracking the door first allows reading fire conditions and prevents sudden introduction of air that could worsen conditions. A brief ceiling-level burst (penciling) can cool the thermal layer. Advancing along the wall maintains orientation and a known path back to the exit. - id: int-hose-p2 type: multiple_choice - question: "Which nozzle pattern is MOST appropriate for an initial interior attack on a room-and-contents fire at grade level?" + question: Which nozzle pattern is MOST appropriate for an initial interior attack on a room-and-contents fire at grade level? options: - - "Wide fog pattern to maximize water distribution" - - "Straight stream or narrow fog for reach, penetration, and minimal steam production in the occupied space" - - "Full fog pattern to create a water curtain shield" - - "It does not matter — all patterns are equally effective" + - Wide fog pattern to maximize water distribution + - Straight stream or narrow fog for reach, penetration, and minimal steam production in the occupied space + - Full fog pattern to create a water curtain shield + - It does not matter — all patterns are equally effective correct: 1 - explanation: "A straight stream or narrow fog provides the best combination of reach, penetration into the fuel package, and minimal disruption of the thermal balance. A wide fog pattern can push heat and steam onto firefighters and victims, disrupt thermal layering, and reduce forward reach. Stream selection is a deliberate tactical choice." - + explanation: A straight stream or narrow fog provides the best combination of reach, penetration into the fuel package, and minimal disruption of the thermal balance. A wide fog pattern can push heat and steam onto firefighters and victims, disrupt thermal layering, and reduce forward reach. Stream selection is a deliberate tactical choice. + keyPrerequisite: hose-line-management - id: interior-attack-team-coordination - instruction: "content/ab-ff1/interior-attack-coordination.md" + instruction: content/ab-ff1/interior-attack-coordination.md problems: - id: int-coord-p1 type: multiple_choice - question: "An interior attack team has advanced to the seat of the fire. The low-air alarm activates on the nozzle operator's SCBA. The correct action is:" + question: 'An interior attack team has advanced to the seat of the fire. The low-air alarm activates on the nozzle operator''s SCBA. The correct action is:' options: - - "The nozzle operator passes the nozzle to the backup firefighter and continues working" - - "The entire team withdraws together along the hose line to the exit, communicating the withdrawal to command via radio" - - "The nozzle operator exits alone while the backup firefighter continues the attack" - - "The nozzle operator silences the alarm and continues for 5 more minutes" + - The nozzle operator passes the nozzle to the backup firefighter and continues working + - The entire team withdraws together along the hose line to the exit, communicating the withdrawal to command via radio + - The nozzle operator exits alone while the backup firefighter continues the attack + - The nozzle operator silences the alarm and continues for 5 more minutes correct: 1 - explanation: "When any team member's low-air alarm activates, the entire team withdraws together. No firefighter should be left operating alone in an IDLH atmosphere. The team follows the hose line out (it's their lifeline to the exit) and communicates the withdrawal to incident command. Silencing the alarm and continuing is never acceptable." + explanation: When any team member's low-air alarm activates, the entire team withdraws together. No firefighter should be left operating alone in an IDLH atmosphere. The team follows the hose line out (it's their lifeline to the exit) and communicates the withdrawal to incident command. Silencing the alarm and continuing is never acceptable. - id: int-coord-p2 type: fill_blank - question: "During interior fire attack, the hose line serves two critical functions: delivering water to the fire and acting as a ___ for the attack team to follow back to the exit point." - correct: "lifeline" - explanation: "In zero-visibility conditions, the hose line is the attack team's primary orientation tool and escape route. Firefighters maintain contact with the hose at all times. If disoriented, the coupling lugs indicate direction — the male coupling points toward the nozzle (fire), the female coupling points toward the exit (water supply)." - + question: 'During interior fire attack, the hose line serves two critical functions: delivering water to the fire and acting as a ___ for the attack team to follow back to the exit point.' + correct: lifeline + explanation: In zero-visibility conditions, the hose line is the attack team's primary orientation tool and escape route. Firefighters maintain contact with the hose at all times. If disoriented, the coupling lugs indicate direction — the male coupling points toward the nozzle (fire), the female coupling points toward the exit (water supply). + keyPrerequisite: interior-fire-attack-grade - id: interior-attack-reading-fire - instruction: "content/ab-ff1/interior-attack-reading-fire.md" + instruction: content/ab-ff1/interior-attack-reading-fire.md problems: - id: int-read-p1 type: multiple_choice - question: "Dark, turbulent smoke pushing rapidly from all openings and pulsing indicates which dangerous fire condition?" + question: Dark, turbulent smoke pushing rapidly from all openings and pulsing indicates which dangerous fire condition? options: - - "The fire is nearly extinguished" - - "Normal free-burning stage" - - "Conditions consistent with impending flashover or backdraft" - - "A ventilation-limited fire that is dying out" + - The fire is nearly extinguished + - Normal free-burning stage + - Conditions consistent with impending flashover or backdraft + - A ventilation-limited fire that is dying out correct: 2 - explanation: "Pulsing, turbulent, dark (carbon-rich) smoke pushing under pressure from openings indicates a ventilation-limited fire with massive heat energy and unburned fuel gases accumulating. These are classic warning signs of impending flashover or backdraft. Recognizing these conditions and adjusting tactics (do not introduce air, cool from exterior, ventilate before entry) is a critical survival skill." + explanation: Pulsing, turbulent, dark (carbon-rich) smoke pushing under pressure from openings indicates a ventilation-limited fire with massive heat energy and unburned fuel gases accumulating. These are classic warning signs of impending flashover or backdraft. Recognizing these conditions and adjusting tactics (do not introduce air, cool from exterior, ventilate before entry) is a critical survival skill. - id: int-read-p2 type: multiple_choice - question: "Which of the following is a primary indicator that flashover is imminent?" + question: Which of the following is a primary indicator that flashover is imminent? options: - - "Decreasing smoke volume from the structure" - - "Rollover (flames rolling across the ceiling in the hot gas layer)" - - "The fire is contained to a single object" - - "Ambient room temperature is comfortable at floor level" + - Decreasing smoke volume from the structure + - Rollover (flames rolling across the ceiling in the hot gas layer) + - The fire is contained to a single object + - Ambient room temperature is comfortable at floor level correct: 1 - explanation: "Rollover — flames appearing in and moving through the hot gas layer at ceiling level — is one of the most reliable indicators that flashover is imminent. When unburned pyrolysis products in the smoke layer reach ignition temperature, they ignite and rapidly spread across the ceiling. Upon seeing rollover, crews should apply water to cool the overhead gases or withdraw immediately." - + explanation: Rollover — flames appearing in and moving through the hot gas layer at ceiling level — is one of the most reliable indicators that flashover is imminent. When unburned pyrolysis products in the smoke layer reach ignition temperature, they ignite and rapidly spread across the ceiling. Upon seeing rollover, crews should apply water to cool the overhead gases or withdraw immediately. + keyPrerequisite: fire-behavior-fundamentals - id: interior-fire-attack-above-grade - name: "Interior Fire Attack — Above Grade" + name: Interior Fire Attack — Above Grade difficulty: 8 estimatedMinutes: 25 - tags: [s4.3-fireground, interior-fire, above-grade, multi-story] - sourceRef: "NFPA 1001-2019 JPR 4.3.10" + tags: + - s4.3-fireground + - interior-fire + - above-grade + - multi-story + sourceRef: NFPA 1001-2019 JPR 4.3.10 prerequisites: - interior-fire-attack-grade - ground-ladder-operations @@ -891,26 +921,30 @@ concepts: problems: - id: above-grade-p1 type: multiple_choice - question: "When conducting an interior fire attack above grade in a multi-story building, the attack line should be advanced to which position before charging?" + question: When conducting an interior fire attack above grade in a multi-story building, the attack line should be advanced to which position before charging? options: - - "The ground floor entrance" - - "One floor below the fire floor, then advanced up the stairwell to the fire floor" - - "Directly to the fire floor via the elevator" - - "The roof via an exterior ladder" + - The ground floor entrance + - One floor below the fire floor, then advanced up the stairwell to the fire floor + - Directly to the fire floor via the elevator + - The roof via an exterior ladder correct: 1 - explanation: "The attack line is advanced uncharged to one floor below the fire floor (the staging floor), then charged before advancing up the stairwell to the fire floor. This prevents the heavy, charged line from needing to be dragged up multiple flights, provides a safe staging area, and keeps the stairwell — the primary egress route — accessible. Elevators are never used during active fire operations." + explanation: The attack line is advanced uncharged to one floor below the fire floor (the staging floor), then charged before advancing up the stairwell to the fire floor. This prevents the heavy, charged line from needing to be dragged up multiple flights, provides a safe staging area, and keeps the stairwell — the primary egress route — accessible. Elevators are never used during active fire operations. - id: above-grade-p2 type: true_false - question: "Firefighters should never use elevators during active fire operations in a multi-story building." - correct: "true" - explanation: "Elevators can malfunction, open on the fire floor due to heat-activated call buttons, lose power, or fill with smoke — trapping firefighters in a lethal environment. Stairwells are the standard means of accessing upper floors during fire operations. If an elevator must be used (e.g., high-rise standpipe operations), strict protocols are followed and it is stopped two floors below the fire floor." - + question: Firefighters should never use elevators during active fire operations in a multi-story building. + correct: 'true' + explanation: Elevators can malfunction, open on the fire floor due to heat-activated call buttons, lose power, or fill with smoke — trapping firefighters in a lethal environment. Stairwells are the standard means of accessing upper floors during fire operations. If an elevator must be used (e.g., high-rise standpipe operations), strict protocols are followed and it is stopped two floors below the fire floor. + keyPrerequisite: interior-fire-attack-grade - id: interior-fire-attack-below-grade - name: "Interior Fire Attack — Below Grade" + name: Interior Fire Attack — Below Grade difficulty: 8 estimatedMinutes: 25 - tags: [s4.3-fireground, interior-fire, below-grade, basement] - sourceRef: "NFPA 1001-2019 JPR 4.3.10" + tags: + - s4.3-fireground + - interior-fire + - below-grade + - basement + sourceRef: NFPA 1001-2019 JPR 4.3.10 prerequisites: - interior-fire-attack-grade encompassing: @@ -923,28 +957,29 @@ concepts: problems: - id: below-grade-p1 type: multiple_choice - question: "What makes below-grade (basement) fire attack significantly more dangerous than grade-level attacks?" + question: What makes below-grade (basement) fire attack significantly more dangerous than grade-level attacks? options: - - "Basement fires burn cooler than grade-level fires" - - "Firefighters must descend into the heat and products of combustion (which rise), limiting egress options to the same stairway used for entry" - - "Water supply pressure is always insufficient for basement operations" - - "Basements are always unoccupied, so there is no rescue urgency" + - Basement fires burn cooler than grade-level fires + - Firefighters must descend into the heat and products of combustion (which rise), limiting egress options to the same stairway used for entry + - Water supply pressure is always insufficient for basement operations + - Basements are always unoccupied, so there is no rescue urgency correct: 1 - explanation: "In basement fires, heat and toxic gases naturally rise toward the stairway — the same path firefighters must use for both entry and egress. This means the attack team descends into worsening conditions, and their escape route becomes increasingly hazardous. Limited alternative egress (typically only one stairway and possibly small windows), reduced visibility, and difficulty ventilating compound the danger." + explanation: In basement fires, heat and toxic gases naturally rise toward the stairway — the same path firefighters must use for both entry and egress. This means the attack team descends into worsening conditions, and their escape route becomes increasingly hazardous. Limited alternative egress (typically only one stairway and possibly small windows), reduced visibility, and difficulty ventilating compound the danger. - id: below-grade-p2 type: fill_blank - question: "Before committing to an interior basement fire attack, the incident commander should consider requesting ___ operations to address heat and smoke banking on the first floor above the fire." - correct: "ventilation" - explanation: "Ventilation of the basement and the floor above is critical before or coordinated with interior attack. Without ventilation, heat and smoke accumulate on the first floor (making conditions untenable there too) and bank down the stairwell into the attack team's path. Horizontal ventilation of basement windows and vertical ventilation through the first floor can improve conditions dramatically." - - # --- Hose line management --- - + question: Before committing to an interior basement fire attack, the incident commander should consider requesting ___ operations to address heat and smoke banking on the first floor above the fire. + correct: ventilation + explanation: Ventilation of the basement and the floor above is critical before or coordinated with interior attack. Without ventilation, heat and smoke accumulate on the first floor (making conditions untenable there too) and bank down the stairwell into the attack team's path. Horizontal ventilation of basement windows and vertical ventilation through the first floor can improve conditions dramatically. + keyPrerequisite: interior-fire-attack-grade - id: hose-line-management - name: "Hose Line Management" + name: Hose Line Management difficulty: 5 estimatedMinutes: 30 - tags: [s4.3-fireground, hose-operations, nozzles] - sourceRef: "NFPA 1001-2019 JPR 4.3.10" + tags: + - s4.3-fireground + - hose-operations + - nozzles + sourceRef: NFPA 1001-2019 JPR 4.3.10 prerequisites: - ppe-donning-doffing - water-supply-hydrant @@ -953,26 +988,29 @@ concepts: problems: - id: hose-mgmt-p1 type: multiple_choice - question: "For an interior attack on a typical residential structure fire, the MINIMUM recommended attack line size is:" + question: 'For an interior attack on a typical residential structure fire, the MINIMUM recommended attack line size is:' options: - - "1-inch booster line" - - "1-1/2 inch or 1-3/4 inch attack line flowing a minimum of 150 GPM" - - "2-1/2 inch supply line" - - "3-inch large diameter hose" + - 1-inch booster line + - 1-1/2 inch or 1-3/4 inch attack line flowing a minimum of 150 GPM + - 2-1/2 inch supply line + - 3-inch large diameter hose correct: 1 - explanation: "A 1-3/4 inch (or 1-1/2 inch) attack line flowing a minimum of 150 GPM is the standard for residential interior attack. This provides adequate flow to overcome the heat release rate of a typical room-and-contents fire while remaining manageable for a two-person crew. Booster lines lack adequate flow. Larger lines are used for commercial or heavy fire conditions." + explanation: A 1-3/4 inch (or 1-1/2 inch) attack line flowing a minimum of 150 GPM is the standard for residential interior attack. This provides adequate flow to overcome the heat release rate of a typical room-and-contents fire while remaining manageable for a two-person crew. Booster lines lack adequate flow. Larger lines are used for commercial or heavy fire conditions. - id: hose-mgmt-p2 type: true_false - question: "When flaking out (deploying) a hose line for interior attack, excess hose should be pre-positioned at the entry point so the attack team has enough hose to reach the seat of the fire without needing to pull more from outside." - correct: "true" - explanation: "Pre-positioning (flaking) sufficient hose at the entry point — typically the full working length needed to reach the farthest point of the building — prevents the attack team from running short inside. Running out of hose before reaching the fire stalls the attack, wastes air, and can leave the team in an untenable position. Proper hose estimation and deployment is a fundamental fireground skill." - + question: When flaking out (deploying) a hose line for interior attack, excess hose should be pre-positioned at the entry point so the attack team has enough hose to reach the seat of the fire without needing to pull more from outside. + correct: 'true' + explanation: Pre-positioning (flaking) sufficient hose at the entry point — typically the full working length needed to reach the farthest point of the building — prevents the attack team from running short inside. Running out of hose before reaching the fire stalls the attack, wastes air, and can leave the team in an untenable position. Proper hose estimation and deployment is a fundamental fireground skill. + keyPrerequisite: water-supply-hydrant - id: hose-replace-burst-section - name: "Hose Operations — Replace Burst Section" + name: Hose Operations — Replace Burst Section difficulty: 4 estimatedMinutes: 15 - tags: [s4.3-fireground, hose-operations, emergency] - sourceRef: "NFPA 1001-2019 JPR 4.3.10" + tags: + - s4.3-fireground + - hose-operations + - emergency + sourceRef: NFPA 1001-2019 JPR 4.3.10 prerequisites: - hose-line-management knowledgePoints: @@ -980,26 +1018,28 @@ concepts: problems: - id: burst-hose-p1 type: multiple_choice - question: "When a section of charged hose line bursts during firefighting operations, the FIRST action is to:" + question: 'When a section of charged hose line bursts during firefighting operations, the FIRST action is to:' options: - - "Abandon the hose line and deploy a new line from the apparatus" - - "Notify the pump operator to shut down the line, then clamp or replace the burst section" - - "Ignore the burst and continue the attack with reduced water flow" - - "Disconnect all hose sections and start over" + - Abandon the hose line and deploy a new line from the apparatus + - Notify the pump operator to shut down the line, then clamp or replace the burst section + - Ignore the burst and continue the attack with reduced water flow + - Disconnect all hose sections and start over correct: 1 - explanation: "The pump operator must shut down (gate off) the affected line immediately to stop water loss and allow the burst section to be replaced. The damaged section is disconnected, a replacement section is inserted, and the line is recharged. Meanwhile, the backup line provides continued fire protection. Communication with the pump operator is critical throughout." + explanation: The pump operator must shut down (gate off) the affected line immediately to stop water loss and allow the burst section to be replaced. The damaged section is disconnected, a replacement section is inserted, and the line is recharged. Meanwhile, the backup line provides continued fire protection. Communication with the pump operator is critical throughout. - id: burst-hose-p2 type: fill_blank - question: "A hose ___ can be applied to a small leak or pinhole in a hose line as a temporary repair to maintain water flow during active operations." - correct: "clamp" - explanation: "A hose clamp can be applied to temporarily seal a small leak or pinhole, allowing continued operations until the line can be shut down and the damaged section properly replaced. For a complete burst, replacement of the section is required. Hose clamps are a standard tool carried on most apparatus." - + question: A hose ___ can be applied to a small leak or pinhole in a hose line as a temporary repair to maintain water flow during active operations. + correct: clamp + explanation: A hose clamp can be applied to temporarily seal a small leak or pinhole, allowing continued operations until the line can be shut down and the damaged section properly replaced. For a complete burst, replacement of the section is required. Hose clamps are a standard tool carried on most apparatus. + keyPrerequisite: hose-line-management - id: hose-extend-line - name: "Hose Operations — Extend a Line" + name: Hose Operations — Extend a Line difficulty: 4 estimatedMinutes: 15 - tags: [s4.3-fireground, hose-operations] - sourceRef: "NFPA 1001-2019 JPR 4.3.10" + tags: + - s4.3-fireground + - hose-operations + sourceRef: NFPA 1001-2019 JPR 4.3.10 prerequisites: - hose-line-management knowledgePoints: @@ -1007,26 +1047,29 @@ concepts: problems: - id: extend-line-p1 type: multiple_choice - question: "To extend a hose line that is too short to reach the fire, the correct procedure is to:" + question: 'To extend a hose line that is too short to reach the fire, the correct procedure is to:' options: - - "Stretch the existing hose to make it longer" - - "Shut down the line, disconnect at the last coupling, add one or more sections, reconnect, and recharge the line" - - "Use a nozzle with longer reach instead" - - "Simply drag the apparatus closer to the fire" + - Stretch the existing hose to make it longer + - Shut down the line, disconnect at the last coupling, add one or more sections, reconnect, and recharge the line + - Use a nozzle with longer reach instead + - Simply drag the apparatus closer to the fire correct: 1 - explanation: "Extending a hose line requires shutting down the line (by the pump operator), breaking the last coupling, adding additional sections of matching diameter hose, reconnecting, and recharging. The nozzle team must notify command and maintain a safe position during the shutdown. The backup line provides fire protection during this operation." + explanation: Extending a hose line requires shutting down the line (by the pump operator), breaking the last coupling, adding additional sections of matching diameter hose, reconnecting, and recharging. The nozzle team must notify command and maintain a safe position during the shutdown. The backup line provides fire protection during this operation. - id: extend-line-p2 type: true_false - question: "When extending a hose line, the additional sections should be the same diameter as the existing attack line to maintain consistent flow and pressure." - correct: "true" - explanation: "Mismatched hose diameters cause friction loss changes that affect nozzle pressure and flow rate. Using the same diameter hose maintains the hydraulic calculations the pump operator has set. Adding smaller diameter hose reduces flow; adding larger diameter is wasteful and creates coupling compatibility issues. Consistent diameter ensures predictable performance." - + question: When extending a hose line, the additional sections should be the same diameter as the existing attack line to maintain consistent flow and pressure. + correct: 'true' + explanation: Mismatched hose diameters cause friction loss changes that affect nozzle pressure and flow rate. Using the same diameter hose maintains the hydraulic calculations the pump operator has set. Adding smaller diameter hose reduces flow; adding larger diameter is wasteful and creates coupling compatibility issues. Consistent diameter ensures predictable performance. + keyPrerequisite: hose-line-management - id: hose-advance-uncharged-stairway - name: "Hose Operations — Advance Uncharged Line Up Stairway" + name: Hose Operations — Advance Uncharged Line Up Stairway difficulty: 5 estimatedMinutes: 15 - tags: [s4.3-fireground, hose-operations, above-grade] - sourceRef: "NFPA 1001-2019 JPR 4.3.10" + tags: + - s4.3-fireground + - hose-operations + - above-grade + sourceRef: NFPA 1001-2019 JPR 4.3.10 prerequisites: - hose-line-management knowledgePoints: @@ -1034,26 +1077,29 @@ concepts: problems: - id: stair-hose-p1 type: multiple_choice - question: "When advancing an uncharged hose line up a stairway for an above-grade fire attack, the recommended technique is to:" + question: 'When advancing an uncharged hose line up a stairway for an above-grade fire attack, the recommended technique is to:' options: - - "Charge the line first, then drag it up the stairs" - - "Flake sufficient hose at the base of the stairs, advance the uncharged line up the stairwell keeping it along the wall, and charge it only after reaching the fire floor landing" - - "Throw the bundled hose up the stairwell from the bottom" - - "Use the elevator to transport the hose to the fire floor" + - Charge the line first, then drag it up the stairs + - Flake sufficient hose at the base of the stairs, advance the uncharged line up the stairwell keeping it along the wall, and charge it only after reaching the fire floor landing + - Throw the bundled hose up the stairwell from the bottom + - Use the elevator to transport the hose to the fire floor correct: 1 - explanation: "An uncharged line is significantly lighter and easier to maneuver up stairways. Sufficient hose is flaked at the stairway base to avoid snags. The line is advanced along the wall (keeping the stairway passable for egress) to the landing below the fire floor. It is charged only after the team is in position and ready to advance, ensuring the crew has water when they need it." + explanation: An uncharged line is significantly lighter and easier to maneuver up stairways. Sufficient hose is flaked at the stairway base to avoid snags. The line is advanced along the wall (keeping the stairway passable for egress) to the landing below the fire floor. It is charged only after the team is in position and ready to advance, ensuring the crew has water when they need it. - id: stair-hose-p2 type: fill_blank - question: "When advancing hose up a stairway, the line should be positioned along the ___ to keep the center of the stairway clear for egress." - correct: "wall" - explanation: "Keeping the hose line along the wall (typically the outside wall of the stairwell) leaves the center and handrail side of the stairway clear for firefighter egress. In an emergency evacuation, a charged hose line in the center of a stairway is a serious tripping hazard that can delay escape. Good hose discipline saves lives." - + question: When advancing hose up a stairway, the line should be positioned along the ___ to keep the center of the stairway clear for egress. + correct: wall + explanation: Keeping the hose line along the wall (typically the outside wall of the stairwell) leaves the center and handrail side of the stairway clear for firefighter egress. In an emergency evacuation, a charged hose line in the center of a stairway is a serious tripping hazard that can delay escape. Good hose discipline saves lives. + keyPrerequisite: hose-line-management - id: hose-advance-up-ladder - name: "Hose Operations — Advance Hose Up a Ladder" + name: Hose Operations — Advance Hose Up a Ladder difficulty: 6 estimatedMinutes: 15 - tags: [s4.3-fireground, hose-operations, ladders] - sourceRef: "NFPA 1001-2019 JPR 4.3.10" + tags: + - s4.3-fireground + - hose-operations + - ladders + sourceRef: NFPA 1001-2019 JPR 4.3.10 prerequisites: - hose-line-management - ground-ladder-operations @@ -1062,26 +1108,29 @@ concepts: problems: - id: ladder-hose-p1 type: multiple_choice - question: "When advancing an uncharged hose line up a ground ladder, the firefighter should:" + question: 'When advancing an uncharged hose line up a ground ladder, the firefighter should:' options: - - "Carry the hose over one shoulder and climb with one hand" - - "Secure the hose to the ladder using a hose strap or utility strap at the tip, then climb with the hose draped over the shoulder, maintaining three points of contact" - - "Have a second firefighter throw the hose up from the ground" - - "Charge the line first, then climb with it" + - Carry the hose over one shoulder and climb with one hand + - Secure the hose to the ladder using a hose strap or utility strap at the tip, then climb with the hose draped over the shoulder, maintaining three points of contact + - Have a second firefighter throw the hose up from the ground + - Charge the line first, then climb with it correct: 1 - explanation: "Securing the hose at the ladder tip with a strap prevents it from sliding back down. The climbing firefighter drapes the hose over the climbing shoulder, maintaining three points of contact at all times. The line should be uncharged for the climb — a charged line is extremely heavy and creates dangerous reaction forces if the nozzle opens accidentally." + explanation: Securing the hose at the ladder tip with a strap prevents it from sliding back down. The climbing firefighter drapes the hose over the climbing shoulder, maintaining three points of contact at all times. The line should be uncharged for the climb — a charged line is extremely heavy and creates dangerous reaction forces if the nozzle opens accidentally. - id: ladder-hose-p2 type: true_false - question: "A hose line should always be charged before it is advanced up a ground ladder." - correct: "false" - explanation: "A charged hose line is extremely heavy (a 50-foot section of 1-3/4 inch hose weighs approximately 80 pounds when charged vs. 20 pounds dry) and creates dangerous nozzle reaction forces. The line should be advanced up the ladder uncharged and only charged once the nozzle operator is in position and secured at the top. Charging first creates an unsafe climbing situation." - + question: A hose line should always be charged before it is advanced up a ground ladder. + correct: 'false' + explanation: A charged hose line is extremely heavy (a 50-foot section of 1-3/4 inch hose weighs approximately 80 pounds when charged vs. 20 pounds dry) and creates dangerous nozzle reaction forces. The line should be advanced up the ladder uncharged and only charged once the nozzle operator is in position and secured at the top. Charging first creates an unsafe climbing situation. + keyPrerequisite: ground-ladder-operations - id: hose-operate-charged-from-ladder - name: "Hose Operations — Operate Charged Line from Ladder" + name: Hose Operations — Operate Charged Line from Ladder difficulty: 6 estimatedMinutes: 15 - tags: [s4.3-fireground, hose-operations, ladders] - sourceRef: "NFPA 1001-2019 JPR 4.3.10" + tags: + - s4.3-fireground + - hose-operations + - ladders + sourceRef: NFPA 1001-2019 JPR 4.3.10 prerequisites: - hose-advance-up-ladder - ground-ladder-operations @@ -1090,28 +1139,30 @@ concepts: problems: - id: charged-ladder-p1 type: multiple_choice - question: "When operating a charged hose line from a ground ladder, the firefighter must:" + question: 'When operating a charged hose line from a ground ladder, the firefighter must:' options: - - "Stand on the top rung for maximum reach" - - "Secure themselves to the ladder with a leg lock or ladder belt, brace for nozzle reaction, and ensure the ladder is heeled or tied" - - "Hold the nozzle with one hand and the ladder with the other" - - "Operate from the middle of the ladder to distribute weight evenly" + - Stand on the top rung for maximum reach + - Secure themselves to the ladder with a leg lock or ladder belt, brace for nozzle reaction, and ensure the ladder is heeled or tied + - Hold the nozzle with one hand and the ladder with the other + - Operate from the middle of the ladder to distribute weight evenly correct: 1 - explanation: "Nozzle reaction force (approximately 60-75 pounds for a 150 GPM flow at 100 psi) will push the firefighter backward off the ladder if not properly secured. A leg lock (wrapping one leg around a rung and behind the beam) or ladder belt provides the necessary anchorage. The ladder must be heeled or mechanically secured to handle the lateral forces." + explanation: Nozzle reaction force (approximately 60-75 pounds for a 150 GPM flow at 100 psi) will push the firefighter backward off the ladder if not properly secured. A leg lock (wrapping one leg around a rung and behind the beam) or ladder belt provides the necessary anchorage. The ladder must be heeled or mechanically secured to handle the lateral forces. - id: charged-ladder-p2 type: fill_blank - question: "The technique of wrapping one leg around a rung and behind the beam of a ladder to free both hands for tool or nozzle operation is called a ___." - correct: "leg lock" - explanation: "The leg lock secures the firefighter to the ladder by threading one leg over the rung above, behind the beam, and hooking the foot on the rung below (or the same rung). This frees both hands for operating a nozzle, breaking a window, or using tools. It is a fundamental ladder skill that must be practiced until automatic." - - # --- Ventilation --- - + question: The technique of wrapping one leg around a rung and behind the beam of a ladder to free both hands for tool or nozzle operation is called a ___. + correct: leg lock + explanation: The leg lock secures the firefighter to the ladder by threading one leg over the rung above, behind the beam, and hooking the foot on the rung below (or the same rung). This frees both hands for operating a nozzle, breaking a window, or using tools. It is a fundamental ladder skill that must be practiced until automatic. + keyPrerequisite: hose-advance-up-ladder - id: positive-pressure-ventilation - name: "Positive Pressure Ventilation (Horizontal)" + name: Positive Pressure Ventilation (Horizontal) difficulty: 4 estimatedMinutes: 20 - tags: [s4.3-fireground, ventilation, ppv, horizontal] - sourceRef: "NFPA 1001-2019 JPR 4.3.11" + tags: + - s4.3-fireground + - ventilation + - ppv + - horizontal + sourceRef: NFPA 1001-2019 JPR 4.3.11 prerequisites: - ppe-donning-doffing - fire-behavior-fundamentals @@ -1120,26 +1171,29 @@ concepts: problems: - id: ppv-p1 type: multiple_choice - question: "When setting up a positive pressure ventilation (PPV) fan at a doorway, the fan should be positioned:" + question: 'When setting up a positive pressure ventilation (PPV) fan at a doorway, the fan should be positioned:' options: - - "Inside the doorway, aimed outward" - - "Outside the doorway, set back far enough to cover the entire door opening with the cone of air (typically 4-6 feet from the opening)" - - "Directly in the doorway threshold" - - "On the roof, aimed downward" + - Inside the doorway, aimed outward + - Outside the doorway, set back far enough to cover the entire door opening with the cone of air (typically 4-6 feet from the opening) + - Directly in the doorway threshold + - On the roof, aimed downward correct: 1 - explanation: "The PPV fan is positioned outside the structure, set back from the doorway so the cone of air seals the entire opening. This creates positive pressure inside, pushing smoke and heat out through a designated exhaust opening. If the fan is too close, air leaks around the edges of the door. The exhaust opening must be created (or opened) before or simultaneously with fan activation." + explanation: The PPV fan is positioned outside the structure, set back from the doorway so the cone of air seals the entire opening. This creates positive pressure inside, pushing smoke and heat out through a designated exhaust opening. If the fan is too close, air leaks around the edges of the door. The exhaust opening must be created (or opened) before or simultaneously with fan activation. - id: ppv-p2 type: true_false - question: "Positive pressure ventilation should only be initiated after coordinating with the interior attack team and ensuring an exhaust opening has been established." - correct: "true" - explanation: "Uncoordinated PPV can push fire and smoke onto interior crews, spread fire to uninvolved areas, or worsen conditions by introducing fresh air without an adequate exhaust path. The exhaust opening (typically a window on the fire floor) must be established, and the interior team must be ready for the change in conditions. Communication between ventilation and attack teams is essential." - + question: Positive pressure ventilation should only be initiated after coordinating with the interior attack team and ensuring an exhaust opening has been established. + correct: 'true' + explanation: Uncoordinated PPV can push fire and smoke onto interior crews, spread fire to uninvolved areas, or worsen conditions by introducing fresh air without an adequate exhaust path. The exhaust opening (typically a window on the fire floor) must be established, and the interior team must be ready for the change in conditions. Communication between ventilation and attack teams is essential. + keyPrerequisite: fire-behavior-fundamentals - id: negative-pressure-ventilation - name: "Negative Pressure Forced Ventilation" + name: Negative Pressure Forced Ventilation difficulty: 4 estimatedMinutes: 15 - tags: [s4.3-fireground, ventilation, negative-pressure] - sourceRef: "NFPA 1001-2019 JPR 4.3.11" + tags: + - s4.3-fireground + - ventilation + - negative-pressure + sourceRef: NFPA 1001-2019 JPR 4.3.11 prerequisites: - ppe-donning-doffing - fire-behavior-fundamentals @@ -1148,26 +1202,30 @@ concepts: problems: - id: neg-vent-p1 type: multiple_choice - question: "Negative pressure ventilation involves placing an exhaust fan or smoke ejector:" + question: 'Negative pressure ventilation involves placing an exhaust fan or smoke ejector:' options: - - "Outside the building aimed at the entry door" - - "Inside the building at the exhaust opening (typically a window), pulling smoke and gases out of the structure" - - "On the roof aimed at a vent hole" - - "In the basement aimed upward" + - Outside the building aimed at the entry door + - Inside the building at the exhaust opening (typically a window), pulling smoke and gases out of the structure + - On the roof aimed at a vent hole + - In the basement aimed upward correct: 1 - explanation: "Negative pressure ventilation places the fan at the exhaust point (typically a window), pulling contaminated air out of the structure. This creates negative pressure inside, drawing fresh air in through other openings. It is less efficient than PPV but is useful when PPV cannot be used or as a supplement. The fan must be positioned inside the window opening to be effective." + explanation: Negative pressure ventilation places the fan at the exhaust point (typically a window), pulling contaminated air out of the structure. This creates negative pressure inside, drawing fresh air in through other openings. It is less efficient than PPV but is useful when PPV cannot be used or as a supplement. The fan must be positioned inside the window opening to be effective. - id: neg-vent-p2 type: fill_blank - question: "Negative pressure ventilation is also commonly referred to as ___ ejector ventilation." - correct: "smoke" - explanation: "Smoke ejectors are fans specifically designed for negative pressure ventilation. They are placed in a window or opening to pull (exhaust) smoke and heated gases from the interior. While PPV has become more common due to its efficiency, smoke ejectors remain an important tool, especially for post-fire ventilation and overhaul operations." - + question: Negative pressure ventilation is also commonly referred to as ___ ejector ventilation. + correct: smoke + explanation: Smoke ejectors are fans specifically designed for negative pressure ventilation. They are placed in a window or opening to pull (exhaust) smoke and heated gases from the interior. While PPV has become more common due to its efficiency, smoke ejectors remain an important tool, especially for post-fire ventilation and overhaul operations. + keyPrerequisite: fire-behavior-fundamentals - id: hydraulic-ventilation - name: "Hydraulic Ventilation" + name: Hydraulic Ventilation difficulty: 4 estimatedMinutes: 15 - tags: [s4.3-fireground, ventilation, hydraulic, hose-operations] - sourceRef: "NFPA 1001-2019 JPR 4.3.11" + tags: + - s4.3-fireground + - ventilation + - hydraulic + - hose-operations + sourceRef: NFPA 1001-2019 JPR 4.3.11 prerequisites: - ppe-donning-doffing - hose-line-management @@ -1177,26 +1235,30 @@ concepts: problems: - id: hydra-vent-p1 type: multiple_choice - question: "Hydraulic ventilation is performed by directing a fog stream out a window opening. For maximum effectiveness, the fog pattern should cover approximately what percentage of the window opening?" + question: Hydraulic ventilation is performed by directing a fog stream out a window opening. For maximum effectiveness, the fog pattern should cover approximately what percentage of the window opening? options: - - "25%" - - "50%" - - "85-90%" - - "100%" + - 25% + - 50% + - 85-90% + - 100% correct: 2 - explanation: "The fog pattern should cover 85-90% of the window opening. This creates maximum air movement (venturi effect) while leaving a small gap around the edges for additional air to be entrained by the moving water droplets. Covering 100% blocks airflow. Covering less than 85% significantly reduces effectiveness." + explanation: The fog pattern should cover 85-90% of the window opening. This creates maximum air movement (venturi effect) while leaving a small gap around the edges for additional air to be entrained by the moving water droplets. Covering 100% blocks airflow. Covering less than 85% significantly reduces effectiveness. - id: hydra-vent-p2 type: true_false - question: "Hydraulic ventilation can be performed using the existing attack line, making it immediately available without additional equipment." - correct: "true" - explanation: "One of the primary advantages of hydraulic ventilation is that it uses the hose line already in place. After fire knockdown, the nozzle operator simply directs a wide fog pattern out a window to exhaust smoke. No additional fans or equipment are needed. This makes it the fastest ventilation method to deploy in many situations, though it does commit the attack line to ventilation duty temporarily." - + question: Hydraulic ventilation can be performed using the existing attack line, making it immediately available without additional equipment. + correct: 'true' + explanation: One of the primary advantages of hydraulic ventilation is that it uses the hose line already in place. After fire knockdown, the nozzle operator simply directs a wide fog pattern out a window to exhaust smoke. No additional fans or equipment are needed. This makes it the fastest ventilation method to deploy in many situations, though it does commit the attack line to ventilation duty temporarily. + keyPrerequisite: hose-line-management - id: vertical-ventilation-flat-roof - name: "Vertical Ventilation (Flat Roof)" + name: Vertical Ventilation (Flat Roof) difficulty: 7 estimatedMinutes: 25 - tags: [s4.3-fireground, ventilation, vertical, flat-roof] - sourceRef: "NFPA 1001-2019 JPR 4.3.12" + tags: + - s4.3-fireground + - ventilation + - vertical + - flat-roof + sourceRef: NFPA 1001-2019 JPR 4.3.12 prerequisites: - ppe-donning-doffing - ground-ladder-operations @@ -1213,26 +1275,30 @@ concepts: problems: - id: flat-roof-vent-p1 type: multiple_choice - question: "When cutting a ventilation hole in a flat roof, the hole should be positioned:" + question: 'When cutting a ventilation hole in a flat roof, the hole should be positioned:' options: - - "At the lowest point of the roof" - - "Directly over the fire, as close to the seat of the fire as can be safely determined" - - "At the edge of the roof near the parapet wall" - - "As far from the fire as possible to avoid collapse" + - At the lowest point of the roof + - Directly over the fire, as close to the seat of the fire as can be safely determined + - At the edge of the roof near the parapet wall + - As far from the fire as possible to avoid collapse correct: 1 - explanation: "The ventilation opening must be directly over the fire to effectively release the heat, smoke, and gases trapped beneath the roof. An opening placed away from the fire will not vent the fire compartment effectively and may create horizontal air movement that spreads the fire. Sounding the roof for structural integrity before and during cutting is essential." + explanation: The ventilation opening must be directly over the fire to effectively release the heat, smoke, and gases trapped beneath the roof. An opening placed away from the fire will not vent the fire compartment effectively and may create horizontal air movement that spreads the fire. Sounding the roof for structural integrity before and during cutting is essential. - id: flat-roof-vent-p2 type: fill_blank - question: "Before stepping onto a flat roof for vertical ventilation, a firefighter must ___ the roof surface with a tool to assess structural integrity." - correct: "sound" - explanation: "Sounding the roof involves striking the surface with an axe or tool while reading the feel and sound of the response. A solid roof produces a firm, solid sound and feel. A compromised (spongy, soft, or hollow-sounding) roof indicates structural weakening from fire below and is unsafe to walk on. Firefighters should sound the roof continuously as they move across it." - + question: Before stepping onto a flat roof for vertical ventilation, a firefighter must ___ the roof surface with a tool to assess structural integrity. + correct: sound + explanation: Sounding the roof involves striking the surface with an axe or tool while reading the feel and sound of the response. A solid roof produces a firm, solid sound and feel. A compromised (spongy, soft, or hollow-sounding) roof indicates structural weakening from fire below and is unsafe to walk on. Firefighters should sound the roof continuously as they move across it. + keyPrerequisite: ground-ladder-operations - id: vertical-ventilation-pitched-roof - name: "Vertical Ventilation (Pitched Roof)" + name: Vertical Ventilation (Pitched Roof) difficulty: 7 estimatedMinutes: 25 - tags: [s4.3-fireground, ventilation, vertical, pitched-roof] - sourceRef: "NFPA 1001-2019 JPR 4.3.12" + tags: + - s4.3-fireground + - ventilation + - vertical + - pitched-roof + sourceRef: NFPA 1001-2019 JPR 4.3.12 prerequisites: - ppe-donning-doffing - ground-ladder-operations @@ -1249,28 +1315,29 @@ concepts: problems: - id: pitched-roof-vent-p1 type: multiple_choice - question: "When performing vertical ventilation on a pitched roof, the firefighter works from a roof ladder to:" + question: 'When performing vertical ventilation on a pitched roof, the firefighter works from a roof ladder to:' options: - - "Get closer to the chimney" - - "Distribute their weight across multiple structural members and prevent sliding on the sloped surface" - - "Avoid damaging the roof shingles" - - "Create a platform for staging tools only" + - Get closer to the chimney + - Distribute their weight across multiple structural members and prevent sliding on the sloped surface + - Avoid damaging the roof shingles + - Create a platform for staging tools only correct: 1 - explanation: "A roof ladder hooks over the ridge and distributes the firefighter's weight across multiple rafters, reducing the risk of localized collapse. It also provides secure footing on the sloped surface, preventing the firefighter from sliding off the roof. Working from a roof ladder is mandatory on pitched roofs — walking directly on the roof surface concentrates weight and provides no fall protection." + explanation: A roof ladder hooks over the ridge and distributes the firefighter's weight across multiple rafters, reducing the risk of localized collapse. It also provides secure footing on the sloped surface, preventing the firefighter from sliding off the roof. Working from a roof ladder is mandatory on pitched roofs — walking directly on the roof surface concentrates weight and provides no fall protection. - id: pitched-roof-vent-p2 type: true_false - question: "On a pitched roof, the ventilation cut should be made on the leeward side (downwind) to prevent wind from pushing smoke and heat back onto the cutting crew." - correct: "true" - explanation: "Positioning the ventilation opening on the leeward side allows wind to carry heat and smoke away from the crew working on the roof. If the cut is made on the windward side, wind pushes the venting heat and gases directly into the cutting crew, creating an extremely dangerous situation. Wind direction assessment is a critical part of ventilation planning." - - # --- Overhaul --- - + question: On a pitched roof, the ventilation cut should be made on the leeward side (downwind) to prevent wind from pushing smoke and heat back onto the cutting crew. + correct: 'true' + explanation: Positioning the ventilation opening on the leeward side allows wind to carry heat and smoke away from the crew working on the roof. If the cut is made on the windward side, wind pushes the venting heat and gases directly into the cutting crew, creating an extremely dangerous situation. Wind direction assessment is a critical part of ventilation planning. + keyPrerequisite: ground-ladder-operations - id: overhaul-operations - name: "Overhaul Operations" + name: Overhaul Operations difficulty: 5 estimatedMinutes: 20 - tags: [s4.3-fireground, overhaul, investigation] - sourceRef: "NFPA 1001-2019 JPR 4.3.13" + tags: + - s4.3-fireground + - overhaul + - investigation + sourceRef: NFPA 1001-2019 JPR 4.3.13 prerequisites: - scba-donning-doffing-breathing - forcible-entry @@ -1287,28 +1354,29 @@ concepts: problems: - id: overhaul-p1 type: multiple_choice - question: "During overhaul, why must firefighters continue wearing SCBA even though visible fire has been extinguished?" + question: During overhaul, why must firefighters continue wearing SCBA even though visible fire has been extinguished? options: - - "For protection against falling debris only" - - "The atmosphere remains IDLH due to carbon monoxide, hydrogen cyanide, and other toxic products of combustion that persist after visible fire is out" - - "SCBA is only needed if smoke is still visible" - - "SCBA is optional during overhaul if windows are open" + - For protection against falling debris only + - The atmosphere remains IDLH due to carbon monoxide, hydrogen cyanide, and other toxic products of combustion that persist after visible fire is out + - SCBA is only needed if smoke is still visible + - SCBA is optional during overhaul if windows are open correct: 1 - explanation: "Toxic gases — particularly carbon monoxide (CO) and hydrogen cyanide (HCN) — remain at dangerous concentrations long after visible fire is extinguished. These are odorless/colorless at hazardous levels and cause acute poisoning. SCBA must be worn until air monitoring confirms the atmosphere is safe. Natural ventilation alone does not guarantee safe air quality. Cancer-causing particulates are also present." + explanation: Toxic gases — particularly carbon monoxide (CO) and hydrogen cyanide (HCN) — remain at dangerous concentrations long after visible fire is extinguished. These are odorless/colorless at hazardous levels and cause acute poisoning. SCBA must be worn until air monitoring confirms the atmosphere is safe. Natural ventilation alone does not guarantee safe air quality. Cancer-causing particulates are also present. - id: overhaul-p2 type: fill_blank - question: "During overhaul, firefighters use pike poles and other tools to open walls and ceilings to check for hidden ___ extension." - correct: "fire" - explanation: "Fire can travel through concealed spaces — wall cavities, ceiling voids, pipe chases, and attic spaces — without being visible from the interior. During overhaul, these spaces must be opened and inspected for hidden fire extension. Using thermal imaging cameras (TICs) can guide this process, but physical opening and inspection remain necessary to confirm complete extinguishment." - - # --- Salvage --- - + question: During overhaul, firefighters use pike poles and other tools to open walls and ceilings to check for hidden ___ extension. + correct: fire + explanation: Fire can travel through concealed spaces — wall cavities, ceiling voids, pipe chases, and attic spaces — without being visible from the interior. During overhaul, these spaces must be opened and inspected for hidden fire extension. Using thermal imaging cameras (TICs) can guide this process, but physical opening and inspection remain necessary to confirm complete extinguishment. + keyPrerequisite: scba-donning-doffing-breathing - id: salvage-property-conservation - name: "Salvage and Property Conservation" + name: Salvage and Property Conservation difficulty: 4 estimatedMinutes: 20 - tags: [s4.3-fireground, salvage, property-conservation] - sourceRef: "NFPA 1001-2019 JPR 4.3.14" + tags: + - s4.3-fireground + - salvage + - property-conservation + sourceRef: NFPA 1001-2019 JPR 4.3.14 prerequisites: - ppe-donning-doffing knowledgePoints: @@ -1316,28 +1384,29 @@ concepts: problems: - id: salvage-p1 type: multiple_choice - question: "Which salvage cover deployment technique is MOST appropriate for protecting a large area of room contents from water damage?" + question: Which salvage cover deployment technique is MOST appropriate for protecting a large area of room contents from water damage? options: - - "Balloon throw — two firefighters deploy the cover by trapping air underneath to float it over the contents" - - "Rolling the cover tightly and sliding it across the floor" - - "Draping individual items one at a time" - - "Duct-taping plastic sheeting to each piece of furniture" + - Balloon throw — two firefighters deploy the cover by trapping air underneath to float it over the contents + - Rolling the cover tightly and sliding it across the floor + - Draping individual items one at a time + - Duct-taping plastic sheeting to each piece of furniture correct: 0 - explanation: "The balloon throw (also called balloon toss) is the standard technique for deploying a salvage cover over a large area. Two firefighters fold and then unfurl the cover, trapping air beneath it to create a balloon effect that floats the cover over furniture and contents. This is fast, covers a large area in one deployment, and minimizes handling of contents." + explanation: The balloon throw (also called balloon toss) is the standard technique for deploying a salvage cover over a large area. Two firefighters fold and then unfurl the cover, trapping air beneath it to create a balloon effect that floats the cover over furniture and contents. This is fast, covers a large area in one deployment, and minimizes handling of contents. - id: salvage-p2 type: true_false - question: "Salvage operations should begin as early as possible during fireground operations — they do not need to wait until the fire is fully extinguished." - correct: "true" - explanation: "Salvage operations can and should begin concurrent with fire attack. Water damage from hose operations often causes more property damage than the fire itself. Deploying salvage covers in unaffected rooms, channeling water out of the building with water chutes, and moving valuable items can all be done while the fire attack is underway, provided it does not interfere with firefighting operations or compromise crew safety." - - # --- Water supply --- - + question: Salvage operations should begin as early as possible during fireground operations — they do not need to wait until the fire is fully extinguished. + correct: 'true' + explanation: Salvage operations can and should begin concurrent with fire attack. Water damage from hose operations often causes more property damage than the fire itself. Deploying salvage covers in unaffected rooms, channeling water out of the building with water chutes, and moving valuable items can all be done while the fire attack is underway, provided it does not interfere with firefighting operations or compromise crew safety. + keyPrerequisite: ppe-donning-doffing - id: water-supply-hydrant - name: "Water Supply — Hydrant Operations" + name: Water Supply — Hydrant Operations difficulty: 3 estimatedMinutes: 20 - tags: [s4.3-fireground, water-supply, hydrant] - sourceRef: "NFPA 1001-2019 JPR 4.3.15" + tags: + - s4.3-fireground + - water-supply + - hydrant + sourceRef: NFPA 1001-2019 JPR 4.3.15 prerequisites: - ppe-donning-doffing knowledgePoints: @@ -1345,26 +1414,30 @@ concepts: problems: - id: hydrant-ops-p1 type: multiple_choice - question: "When connecting to a fire hydrant, what is the correct sequence of operations?" + question: When connecting to a fire hydrant, what is the correct sequence of operations? options: - - "Open the hydrant fully, then connect the supply line" - - "Remove the cap, inspect the outlet and threads, connect the supply line hand-tight, then signal the driver/operator to charge the line, then fully open the hydrant valve" - - "Partially open the hydrant to flush debris, close it, connect the hose, then open fully" - - "Connect the hose to the steamer port only, then open to half-turn" + - Open the hydrant fully, then connect the supply line + - Remove the cap, inspect the outlet and threads, connect the supply line hand-tight, then signal the driver/operator to charge the line, then fully open the hydrant valve + - Partially open the hydrant to flush debris, close it, connect the hose, then open fully + - Connect the hose to the steamer port only, then open to half-turn correct: 2 - explanation: "The correct sequence includes flushing the hydrant briefly (partially opening to clear debris and sediment from the barrel), closing it, making connections on clean threads, then fully opening the hydrant valve. Flushing prevents debris from entering the hose and apparatus pump. Connections should be hand-tight to allow emergency disconnection. The hydrant valve is opened fully to prevent cavitation." + explanation: The correct sequence includes flushing the hydrant briefly (partially opening to clear debris and sediment from the barrel), closing it, making connections on clean threads, then fully opening the hydrant valve. Flushing prevents debris from entering the hose and apparatus pump. Connections should be hand-tight to allow emergency disconnection. The hydrant valve is opened fully to prevent cavitation. - id: hydrant-ops-p2 type: fill_blank - question: "The large outlet on a fire hydrant (typically 4 or 4.5 inches) used for connecting large diameter supply hose is called the ___ connection." - correct: "steamer" - explanation: "The steamer connection (also called the pumper connection) is the large-diameter outlet (typically 4 or 4.5 inches) on a fire hydrant. It provides the maximum flow capacity and is used to supply the apparatus via large diameter hose (LDH). The smaller outlets (typically 2.5 inches) are used for direct hose connections or when LDH is not available." - + question: The large outlet on a fire hydrant (typically 4 or 4.5 inches) used for connecting large diameter supply hose is called the ___ connection. + correct: steamer + explanation: The steamer connection (also called the pumper connection) is the large-diameter outlet (typically 4 or 4.5 inches) on a fire hydrant. It provides the maximum flow capacity and is used to supply the apparatus via large diameter hose (LDH). The smaller outlets (typically 2.5 inches) are used for direct hose connections or when LDH is not available. + keyPrerequisite: ppe-donning-doffing - id: water-supply-static-drafting - name: "Water Supply — Static Source (Drafting)" + name: Water Supply — Static Source (Drafting) difficulty: 5 estimatedMinutes: 20 - tags: [s4.3-fireground, water-supply, drafting, static-source] - sourceRef: "NFPA 1001-2019 JPR 4.3.15" + tags: + - s4.3-fireground + - water-supply + - drafting + - static-source + sourceRef: NFPA 1001-2019 JPR 4.3.15 prerequisites: - water-supply-hydrant encompassing: @@ -1375,28 +1448,29 @@ concepts: problems: - id: drafting-p1 type: multiple_choice - question: "When drafting water from a static source (pond, lake, or portable tank), the hard suction hose strainer must be:" + question: 'When drafting water from a static source (pond, lake, or portable tank), the hard suction hose strainer must be:' options: - - "Placed flat on the bottom of the water source" - - "Submerged at least 24 inches (60 cm) below the water surface and kept off the bottom to prevent clogging with debris" - - "Floating on the surface of the water" - - "Placed above the waterline to prevent priming issues" + - Placed flat on the bottom of the water source + - Submerged at least 24 inches (60 cm) below the water surface and kept off the bottom to prevent clogging with debris + - Floating on the surface of the water + - Placed above the waterline to prevent priming issues correct: 1 - explanation: "The strainer must be fully submerged (at least 24 inches below the surface) to prevent air entrainment through surface vortex, and elevated off the bottom (using a rope or the strainer's built-in feet) to prevent debris from blocking the screen. Air leaks anywhere in the hard suction line will break the prime and stop water flow." + explanation: The strainer must be fully submerged (at least 24 inches below the surface) to prevent air entrainment through surface vortex, and elevated off the bottom (using a rope or the strainer's built-in feet) to prevent debris from blocking the screen. Air leaks anywhere in the hard suction line will break the prime and stop water flow. - id: drafting-p2 type: true_false - question: "A fire apparatus can draft water from a static source that is higher than the pump intake — gravity will feed the water into the pump." - correct: "false" - explanation: "Drafting relies on atmospheric pressure pushing water up into the pump when the pump creates a partial vacuum. The pump must be positioned above the water source, and there is a maximum practical lift of approximately 20-25 feet vertically. Water cannot be 'drafted' from a source above the pump — that would be a pressurized or gravity-fed supply, not drafting." - - # --- Fire extinguishers --- - + question: A fire apparatus can draft water from a static source that is higher than the pump intake — gravity will feed the water into the pump. + correct: 'false' + explanation: Drafting relies on atmospheric pressure pushing water up into the pump when the pump creates a partial vacuum. The pump must be positioned above the water source, and there is a maximum practical lift of approximately 20-25 feet vertically. Water cannot be 'drafted' from a source above the pump — that would be a pressurized or gravity-fed supply, not drafting. + keyPrerequisite: water-supply-hydrant - id: fire-extinguisher-operations - name: "Fire Extinguisher Operations (Class A, B, C)" + name: Fire Extinguisher Operations (Class A, B, C) difficulty: 2 estimatedMinutes: 15 - tags: [s4.3-fireground, extinguishers, foundational] - sourceRef: "NFPA 1001-2019 JPR 4.3.16" + tags: + - s4.3-fireground + - extinguishers + - foundational + sourceRef: NFPA 1001-2019 JPR 4.3.16 prerequisites: - ppe-donning-doffing knowledgePoints: @@ -1404,28 +1478,29 @@ concepts: problems: - id: extinguisher-p1 type: multiple_choice - question: "The PASS technique for operating a portable fire extinguisher stands for:" + question: 'The PASS technique for operating a portable fire extinguisher stands for:' options: - - "Push, Aim, Spray, Sweep" - - "Pull the pin, Aim at the base of the fire, Squeeze the handle, Sweep side to side" - - "Point, Activate, Spray, Stop" - - "Prepare, Approach, Squeeze, Secure" + - Push, Aim, Spray, Sweep + - Pull the pin, Aim at the base of the fire, Squeeze the handle, Sweep side to side + - Point, Activate, Spray, Stop + - Prepare, Approach, Squeeze, Secure correct: 1 - explanation: "PASS stands for: Pull the pin (or remove the safety device), Aim the nozzle at the base of the fire (not at the flames), Squeeze the handle to discharge the agent, and Sweep side to side across the base of the fire. Aiming at the base is critical because the fire must be attacked at its fuel source, not at the visible flames above." + explanation: 'PASS stands for: Pull the pin (or remove the safety device), Aim the nozzle at the base of the fire (not at the flames), Squeeze the handle to discharge the agent, and Sweep side to side across the base of the fire. Aiming at the base is critical because the fire must be attacked at its fuel source, not at the visible flames above.' - id: extinguisher-p2 type: fill_blank - question: "A Class ___ fire extinguisher is appropriate for fires involving energized electrical equipment." - correct: "C" - explanation: "Class C extinguishers are rated for fires involving energized electrical equipment. The extinguishing agent (typically CO2 or dry chemical) is non-conductive, preventing electrical shock to the operator. Once the electrical equipment is de-energized, the fire becomes a Class A or B fire depending on the fuel involved. ABC-rated dry chemical extinguishers cover all three classes." - - # --- Scene support --- - + question: A Class ___ fire extinguisher is appropriate for fires involving energized electrical equipment. + correct: C + explanation: Class C extinguishers are rated for fires involving energized electrical equipment. The extinguishing agent (typically CO2 or dry chemical) is non-conductive, preventing electrical shock to the operator. Once the electrical equipment is de-energized, the fire becomes a Class A or B fire depending on the fuel involved. ABC-rated dry chemical extinguishers cover all three classes. + keyPrerequisite: ppe-donning-doffing - id: emergency-scene-illumination - name: "Emergency Scene Illumination" + name: Emergency Scene Illumination difficulty: 2 estimatedMinutes: 10 - tags: [s4.3-fireground, scene-support, lighting] - sourceRef: "NFPA 1001-2019 JPR 4.3.17" + tags: + - s4.3-fireground + - scene-support + - lighting + sourceRef: NFPA 1001-2019 JPR 4.3.17 prerequisites: - ppe-donning-doffing knowledgePoints: @@ -1433,26 +1508,31 @@ concepts: problems: - id: scene-light-p1 type: multiple_choice - question: "When deploying portable scene lighting at a nighttime emergency, lights should be positioned to:" + question: 'When deploying portable scene lighting at a nighttime emergency, lights should be positioned to:' options: - - "Shine directly into the eyes of approaching traffic for maximum visibility" - - "Illuminate the work area without blinding firefighters or oncoming traffic, and be placed on stable ground away from trip hazards" - - "Point upward to create general ambient light" - - "Be placed as high as possible regardless of stability" + - Shine directly into the eyes of approaching traffic for maximum visibility + - Illuminate the work area without blinding firefighters or oncoming traffic, and be placed on stable ground away from trip hazards + - Point upward to create general ambient light + - Be placed as high as possible regardless of stability correct: 1 - explanation: "Effective scene lighting illuminates the work area while avoiding glare that can blind firefighters, victims, or drivers. Lights are positioned at the perimeter of the work zone, angled to illuminate the scene. They must be on stable surfaces to prevent tipping. Generators powering the lights should be placed downwind to keep exhaust fumes away from the work area." + explanation: Effective scene lighting illuminates the work area while avoiding glare that can blind firefighters, victims, or drivers. Lights are positioned at the perimeter of the work zone, angled to illuminate the scene. They must be on stable surfaces to prevent tipping. Generators powering the lights should be placed downwind to keep exhaust fumes away from the work area. - id: scene-light-p2 type: true_false - question: "Portable generators used for scene lighting should be grounded according to the manufacturer's instructions to prevent electrical shock." - correct: "true" - explanation: "Portable generators must be properly grounded per manufacturer specifications and electrical safety standards. Operating a generator without proper grounding creates electrical shock hazards, particularly in wet conditions common on the fireground. Ground fault circuit interrupters (GFCIs) should be used on all circuits when available." - + question: Portable generators used for scene lighting should be grounded according to the manufacturer's instructions to prevent electrical shock. + correct: 'true' + explanation: Portable generators must be properly grounded per manufacturer specifications and electrical safety standards. Operating a generator without proper grounding creates electrical shock hazards, particularly in wet conditions common on the fireground. Ground fault circuit interrupters (GFCIs) should be used on all circuits when available. + keyPrerequisite: ppe-donning-doffing - id: building-utilities-shutoff - name: "Building Utilities — Shut-Off Procedures" + name: Building Utilities — Shut-Off Procedures difficulty: 4 estimatedMinutes: 20 - tags: [s4.3-fireground, utilities, gas, electric, water] - sourceRef: "NFPA 1001-2019 JPR 4.3.18" + tags: + - s4.3-fireground + - utilities + - gas + - electric + - water + sourceRef: NFPA 1001-2019 JPR 4.3.18 prerequisites: - ppe-donning-doffing - scene-safety-electrical @@ -1461,28 +1541,30 @@ concepts: problems: - id: utilities-p1 type: multiple_choice - question: "When shutting off natural gas to a building at an emergency scene, the gas meter valve is turned to the OFF position using:" + question: 'When shutting off natural gas to a building at an emergency scene, the gas meter valve is turned to the OFF position using:' options: - - "Bare hands only" - - "A crescent wrench or gas shut-off wrench, turning the valve one-quarter turn so the handle is perpendicular to the pipe" - - "A flat-head screwdriver inserted into the valve" - - "The building's electrical main breaker" + - Bare hands only + - A crescent wrench or gas shut-off wrench, turning the valve one-quarter turn so the handle is perpendicular to the pipe + - A flat-head screwdriver inserted into the valve + - The building's electrical main breaker correct: 1 - explanation: "The gas meter valve is turned one-quarter turn with an adjustable wrench or specialized gas key so the valve handle sits perpendicular (crosswise) to the pipe, indicating the closed position. When the handle is parallel to the pipe, gas is flowing. Only the gas utility company should restore gas service after a shutoff — firefighters shut off but do not turn gas back on." + explanation: The gas meter valve is turned one-quarter turn with an adjustable wrench or specialized gas key so the valve handle sits perpendicular (crosswise) to the pipe, indicating the closed position. When the handle is parallel to the pipe, gas is flowing. Only the gas utility company should restore gas service after a shutoff — firefighters shut off but do not turn gas back on. - id: utilities-p2 type: fill_blank - question: "After shutting off electrical power to a building at the main breaker panel, firefighters should treat all wiring as ___ until confirmed de-energized by the utility company." - correct: "energized" - explanation: "Even after shutting off the main breaker, other power sources may exist — solar panels, backup generators, battery systems, or utility-side wiring that remains live above the main breaker. Treat all wiring as energized until the utility company confirms complete de-energization. This conservative approach prevents electrocution from unexpected power sources." - - # --- Wildland --- - + question: After shutting off electrical power to a building at the main breaker panel, firefighters should treat all wiring as ___ until confirmed de-energized by the utility company. + correct: energized + explanation: Even after shutting off the main breaker, other power sources may exist — solar panels, backup generators, battery systems, or utility-side wiring that remains live above the main breaker. Treat all wiring as energized until the utility company confirms complete de-energization. This conservative approach prevents electrocution from unexpected power sources. + keyPrerequisite: scene-safety-electrical - id: ground-cover-wildland-fire - name: "Ground Cover and Wildland Fire Operations" + name: Ground Cover and Wildland Fire Operations difficulty: 5 estimatedMinutes: 25 - tags: [s4.3-fireground, wildland, ground-cover, interface] - sourceRef: "NFPA 1001-2019 JPR 4.3.19" + tags: + - s4.3-fireground + - wildland + - ground-cover + - interface + sourceRef: NFPA 1001-2019 JPR 4.3.19 prerequisites: - ppe-donning-doffing - fire-behavior-fundamentals @@ -1491,28 +1573,30 @@ concepts: problems: - id: wildland-p1 type: multiple_choice - question: "The three environmental factors that most influence wildland fire behavior are:" + question: 'The three environmental factors that most influence wildland fire behavior are:' options: - - "Humidity, cloud cover, and soil moisture" - - "Weather (wind, temperature, humidity), topography (slope, aspect), and fuel (type, moisture, arrangement)" - - "Time of day, season, and latitude" - - "Proximity to water sources, soil type, and elevation" + - Humidity, cloud cover, and soil moisture + - Weather (wind, temperature, humidity), topography (slope, aspect), and fuel (type, moisture, arrangement) + - Time of day, season, and latitude + - Proximity to water sources, soil type, and elevation correct: 1 - explanation: "The wildland fire behavior triangle consists of weather (particularly wind speed/direction, temperature, and relative humidity), topography (slope accelerates fire spread uphill, aspect affects fuel moisture), and fuel (type, arrangement, moisture content, and loading). These three factors interact to determine fire intensity, rate of spread, and behavior. Understanding this triangle is fundamental to wildland firefighting safety." + explanation: The wildland fire behavior triangle consists of weather (particularly wind speed/direction, temperature, and relative humidity), topography (slope accelerates fire spread uphill, aspect affects fuel moisture), and fuel (type, arrangement, moisture content, and loading). These three factors interact to determine fire intensity, rate of spread, and behavior. Understanding this triangle is fundamental to wildland firefighting safety. - id: wildland-p2 type: true_false - question: "Fire spreads faster uphill than downhill because the slope preheats fuels above the fire through radiant heat and convection." - correct: "true" - explanation: "On sloped terrain, flames lean toward the uphill fuels, preheating them through radiant heat and convection. The steeper the slope, the faster the fire spreads uphill. As a general rule, the rate of spread doubles for every 10-degree increase in slope. This is why firefighters are trained to never position themselves above a fire on a slope — an uphill run of fire can be extremely fast and deadly." - - # --- Rope operations --- - + question: Fire spreads faster uphill than downhill because the slope preheats fuels above the fire through radiant heat and convection. + correct: 'true' + explanation: On sloped terrain, flames lean toward the uphill fuels, preheating them through radiant heat and convection. The steeper the slope, the faster the fire spreads uphill. As a general rule, the rate of spread doubles for every 10-degree increase in slope. This is why firefighters are trained to never position themselves above a fire on a slope — an uphill run of fire can be extremely fast and deadly. + keyPrerequisite: fire-behavior-fundamentals - id: hoisting-tools-rope - name: "Hoisting Tools and Equipment with Rope" + name: Hoisting Tools and Equipment with Rope difficulty: 4 estimatedMinutes: 20 - tags: [s4.3-fireground, ropes, hoisting, tools] - sourceRef: "NFPA 1001-2019 JPR 4.3.20" + tags: + - s4.3-fireground + - ropes + - hoisting + - tools + sourceRef: NFPA 1001-2019 JPR 4.3.20 prerequisites: - knots-bends-hitches - ppe-donning-doffing @@ -1521,28 +1605,30 @@ concepts: problems: - id: hoist-tech-p1 type: multiple_choice - question: "When hoisting an axe to a roof using a rope, the correct rigging method is to:" + question: 'When hoisting an axe to a roof using a rope, the correct rigging method is to:' options: - - "Tie the rope around the axe handle only" - - "Secure the axe head with a clove hitch and half hitches on the handle, with the blade guarded, and attach a tag/guide line" - - "Place the axe in a bucket and hoist the bucket" - - "Throw the axe up to the firefighter on the roof" + - Tie the rope around the axe handle only + - Secure the axe head with a clove hitch and half hitches on the handle, with the blade guarded, and attach a tag/guide line + - Place the axe in a bucket and hoist the bucket + - Throw the axe up to the firefighter on the roof correct: 1 - explanation: "The axe head is secured with a clove hitch near the head, followed by half hitches along the handle to prevent swinging. The blade should be guarded or positioned away from the rope. A tag line allows the ground crew to guide the tool during hoisting, preventing it from swinging into windows or striking the building. Never throw tools — they can cause injury or damage." + explanation: The axe head is secured with a clove hitch near the head, followed by half hitches along the handle to prevent swinging. The blade should be guarded or positioned away from the rope. A tag line allows the ground crew to guide the tool during hoisting, preventing it from swinging into windows or striking the building. Never throw tools — they can cause injury or damage. - id: hoist-tech-p2 type: fill_blank - question: "A ___ line is a secondary rope attached to a hoisted tool or equipment to allow ground personnel to guide and steady the load during raising and lowering." - correct: "tag" - explanation: "A tag line (also called a guide line) is attached to the tool or equipment being hoisted. Ground personnel use it to control swinging, guide the load away from obstructions, and position it for the receiving firefighter. Without a tag line, hoisted equipment swings freely and can strike the building, break windows, or injure personnel." - - # --- Air monitoring --- - + question: A ___ line is a secondary rope attached to a hoisted tool or equipment to allow ground personnel to guide and steady the load during raising and lowering. + correct: tag + explanation: A tag line (also called a guide line) is attached to the tool or equipment being hoisted. Ground personnel use it to control swinging, guide the load away from obstructions, and position it for the receiving firefighter. Without a tag line, hoisted equipment swings freely and can strike the building, break windows, or injure personnel. + keyPrerequisite: knots-bends-hitches - id: air-monitoring-atmospheric - name: "Air Monitoring and Atmospheric Assessment" + name: Air Monitoring and Atmospheric Assessment difficulty: 5 estimatedMinutes: 20 - tags: [s4.3-fireground, air-monitoring, hazmat, safety] - sourceRef: "NFPA 1001-2019 JPR 4.3.1" + tags: + - s4.3-fireground + - air-monitoring + - hazmat + - safety + sourceRef: NFPA 1001-2019 JPR 4.3.1 prerequisites: - ppe-donning-doffing - scba-donning-doffing-breathing @@ -1551,30 +1637,29 @@ concepts: problems: - id: air-mon-p1 type: multiple_choice - question: "A four-gas atmospheric monitor typically measures which four gases?" + question: A four-gas atmospheric monitor typically measures which four gases? options: - - "Nitrogen, argon, helium, and neon" - - "Oxygen (O2), carbon monoxide (CO), hydrogen sulfide (H2S), and lower explosive limit (LEL/combustible gases)" - - "Carbon dioxide, methane, propane, and acetylene" - - "Oxygen, nitrogen, water vapor, and ozone" + - Nitrogen, argon, helium, and neon + - Oxygen (O2), carbon monoxide (CO), hydrogen sulfide (H2S), and lower explosive limit (LEL/combustible gases) + - Carbon dioxide, methane, propane, and acetylene + - Oxygen, nitrogen, water vapor, and ozone correct: 1 - explanation: "A standard four-gas monitor measures oxygen concentration (normal is 20.9%, danger below 19.5% or above 23.5%), carbon monoxide (toxic at low concentrations), hydrogen sulfide (highly toxic, common in confined spaces), and the lower explosive limit (percentage of combustible gas concentration relative to its ignition point). These four readings provide a basic hazard assessment for atmospheric safety." + explanation: A standard four-gas monitor measures oxygen concentration (normal is 20.9%, danger below 19.5% or above 23.5%), carbon monoxide (toxic at low concentrations), hydrogen sulfide (highly toxic, common in confined spaces), and the lower explosive limit (percentage of combustible gas concentration relative to its ignition point). These four readings provide a basic hazard assessment for atmospheric safety. - id: air-mon-p2 type: fill_blank - question: "The normal oxygen concentration in ambient air is ___%, and an atmosphere is considered oxygen-deficient below 19.5%." - correct: "20.9" - explanation: "Normal atmospheric oxygen is 20.9%. OSHA defines an oxygen-deficient atmosphere as below 19.5% and an oxygen-enriched atmosphere as above 23.5%. Both are hazardous. Oxygen-deficient atmospheres cause impaired judgment, loss of consciousness, and death. Oxygen-enriched atmospheres dramatically increase fire and explosion risk. Continuous monitoring is required in any potentially compromised atmosphere." - - # ============================================================ - # 4.5 Maintenance - # ============================================================ - + question: The normal oxygen concentration in ambient air is ___%, and an atmosphere is considered oxygen-deficient below 19.5%. + correct: '20.9' + explanation: Normal atmospheric oxygen is 20.9%. OSHA defines an oxygen-deficient atmosphere as below 19.5% and an oxygen-enriched atmosphere as above 23.5%. Both are hazardous. Oxygen-deficient atmospheres cause impaired judgment, loss of consciousness, and death. Oxygen-enriched atmospheres dramatically increase fire and explosion risk. Continuous monitoring is required in any potentially compromised atmosphere. + keyPrerequisite: scba-donning-doffing-breathing - id: equipment-inspection-cleaning - name: "Equipment Inspection and Cleaning (Ladders, Ropes, SCBA, Tools)" + name: Equipment Inspection and Cleaning (Ladders, Ropes, SCBA, Tools) difficulty: 2 estimatedMinutes: 20 - tags: [s4.5-maintenance, inspection, cleaning] - sourceRef: "NFPA 1001-2019 JPR 4.5.1" + tags: + - s4.5-maintenance + - inspection + - cleaning + sourceRef: NFPA 1001-2019 JPR 4.5.1 prerequisites: - ppe-donning-doffing knowledgePoints: @@ -1582,26 +1667,30 @@ concepts: problems: - id: equip-maint-p1 type: multiple_choice - question: "During a post-incident inspection of a ground ladder, which finding would require the ladder to be immediately removed from service?" + question: During a post-incident inspection of a ground ladder, which finding would require the ladder to be immediately removed from service? options: - - "Dirt or soot on the beams" - - "A bent or cracked rung, heat damage/discoloration, or a frayed halyard" - - "Minor paint scratches on the beams" - - "A loose label or decal" + - Dirt or soot on the beams + - A bent or cracked rung, heat damage/discoloration, or a frayed halyard + - Minor paint scratches on the beams + - A loose label or decal correct: 1 - explanation: "A bent or cracked rung, heat damage (indicated by discoloration, blistering, or delamination), or a frayed halyard indicates structural compromise that could cause catastrophic failure under load. These conditions require the ladder to be tagged out of service immediately and sent for professional repair or replacement. Cosmetic issues (dirt, paint scratches, labels) do not affect structural integrity." + explanation: A bent or cracked rung, heat damage (indicated by discoloration, blistering, or delamination), or a frayed halyard indicates structural compromise that could cause catastrophic failure under load. These conditions require the ladder to be tagged out of service immediately and sent for professional repair or replacement. Cosmetic issues (dirt, paint scratches, labels) do not affect structural integrity. - id: equip-maint-p2 type: true_false - question: "Life safety rope that has been used to support a load during emergency operations must be retired from life safety use." - correct: "true" - explanation: "Per NFPA 1983, life safety rope that has been subjected to impact loading or has supported a load during an emergency must be removed from life safety service. It may be downgraded to utility use, but it can never again be used where failure would result in death or serious injury. This is because internal fiber damage may not be visible externally but can significantly reduce the rope's strength." - + question: Life safety rope that has been used to support a load during emergency operations must be retired from life safety use. + correct: 'true' + explanation: Per NFPA 1983, life safety rope that has been subjected to impact loading or has supported a load during an emergency must be removed from life safety service. It may be downgraded to utility use, but it can never again be used where failure would result in death or serious injury. This is because internal fiber damage may not be visible externally but can significantly reduce the rope's strength. + keyPrerequisite: ground-ladder-operations - id: fire-hose-inspection-service - name: "Fire Hose Inspection, Cleaning, and Return to Service" + name: Fire Hose Inspection, Cleaning, and Return to Service difficulty: 3 estimatedMinutes: 20 - tags: [s4.5-maintenance, hose, inspection, cleaning] - sourceRef: "NFPA 1001-2019 JPR 4.5.2" + tags: + - s4.5-maintenance + - hose + - inspection + - cleaning + sourceRef: NFPA 1001-2019 JPR 4.5.2 prerequisites: - hose-line-management knowledgePoints: @@ -1609,16 +1698,17 @@ concepts: problems: - id: hose-insp-p1 type: multiple_choice - question: "After a fire, hose should be cleaned and inspected before being returned to service. Which of the following is a reason to remove a section of hose from service?" + question: After a fire, hose should be cleaned and inspected before being returned to service. Which of the following is a reason to remove a section of hose from service? options: - - "The hose is wet" - - "The jacket shows cuts, abrasion wear-through, or the coupling is damaged (cracked swivel, damaged threads, or a leaking gasket that cannot be replaced)" - - "The hose is a different color than other sections" - - "The hose was used on a vehicle fire" + - The hose is wet + - The jacket shows cuts, abrasion wear-through, or the coupling is damaged (cracked swivel, damaged threads, or a leaking gasket that cannot be replaced) + - The hose is a different color than other sections + - The hose was used on a vehicle fire correct: 1 - explanation: "Physical damage to the jacket (cuts, abrasion through to the liner), liner damage (delamination, bubbling under pressure), and coupling damage (cracked swivels, damaged threads, non-replaceable gasket damage) are all grounds for removing hose from service. Minor gasket replacement is routine maintenance, but structural damage to the hose or couplings compromises pressure integrity and firefighter safety." + explanation: Physical damage to the jacket (cuts, abrasion through to the liner), liner damage (delamination, bubbling under pressure), and coupling damage (cracked swivels, damaged threads, non-replaceable gasket damage) are all grounds for removing hose from service. Minor gasket replacement is routine maintenance, but structural damage to the hose or couplings compromises pressure integrity and firefighter safety. - id: hose-insp-p2 type: fill_blank - question: "Fire hose should be tested annually at its rated service test pressure, a process known as ___ testing." - correct: "service" - explanation: "Annual service testing (also called proof testing) involves pressurizing each section of hose to its rated service test pressure (typically 250 psi for attack hose, 200 psi for supply hose) and inspecting for leaks, bulges, or coupling slippage. Hose that fails service testing is removed from service. This annual test is required by NFPA 1962 and ensures hose reliability under fireground conditions." + question: Fire hose should be tested annually at its rated service test pressure, a process known as ___ testing. + correct: service + explanation: Annual service testing (also called proof testing) involves pressurizing each section of hose to its rated service test pressure (typically 250 psi for attack hose, 200 psi for supply hose) and inspecting for leaks, bulges, or coupling slippage. Hose that fails service testing is removed from service. This annual test is required by NFPA 1962 and ensures hose reliability under fireground conditions. + keyPrerequisite: hose-line-management diff --git a/content/courses/examples/python-basics.yaml b/content/courses/examples/python-basics.yaml index a31612b..c1256fd 100644 --- a/content/courses/examples/python-basics.yaml +++ b/content/courses/examples/python-basics.yaml @@ -1,172 +1,168 @@ course: id: python-basics - name: "Python Basics" - description: "Core Python concepts for beginners. Covers variables, control flow, functions, and basic data structures." + name: Python Basics + description: Core Python concepts for beginners. Covers variables, control flow, functions, and basic data structures. estimatedHours: 10 - version: "2026.1" - sourceDocument: "The Python Tutorial (docs.python.org/3/tutorial)" - + version: '2026.1' + sourceDocument: The Python Tutorial (docs.python.org/3/tutorial) concepts: - - # ============================================================ - # 1. Variables and Types - # ============================================================ - - id: variables-and-types - name: "Variables and Types" + name: Variables and Types difficulty: 1 estimatedMinutes: 15 - tags: [foundational, variables] + tags: + - foundational + - variables knowledgePoints: - id: dynamic-typing - instruction: "Python is dynamically typed -- you don't declare a variable's type. The type is determined at runtime by the value assigned. `x = 5` makes x an int, `x = 'hello'` makes it a str. Use `type()` to check a value's type at runtime." + instruction: Python is dynamically typed -- you don't declare a variable's type. The type is determined at runtime by the value assigned. `x = 5` makes x an int, `x = 'hello'` makes it a str. Use `type()` to check a value's type at runtime. problems: - id: py-var-p1 type: multiple_choice - question: "What does `type(3.14)` return in Python?" + question: What does `type(3.14)` return in Python? options: - - "" - - "" - - "" - - "" + - + - + - + - correct: 1 - explanation: "3.14 is a floating-point literal, so Python assigns it the `float` type. Python distinguishes between `int` (whole numbers) and `float` (decimal numbers)." + explanation: 3.14 is a floating-point literal, so Python assigns it the `float` type. Python distinguishes between `int` (whole numbers) and `float` (decimal numbers). - id: py-var-p2 type: true_false - question: "In Python, you must declare a variable's type before assigning a value to it." - correct: "false" - explanation: "Python is dynamically typed. You simply assign a value and the type is inferred: `x = 42` creates an int, no type declaration needed. This is different from statically typed languages like Java or C." + question: In Python, you must declare a variable's type before assigning a value to it. + correct: 'false' + explanation: 'Python is dynamically typed. You simply assign a value and the type is inferred: `x = 42` creates an int, no type declaration needed. This is different from statically typed languages like Java or C.' - id: strings-basics - instruction: "Strings in Python are immutable sequences of characters. You can use single quotes ('hello'), double quotes (\"hello\"), or triple quotes for multiline strings. f-strings (f\"Hello {name}\") allow inline expression evaluation and are the preferred way to format strings in modern Python." + instruction: Strings in Python are immutable sequences of characters. You can use single quotes ('hello'), double quotes ("hello"), or triple quotes for multiline strings. f-strings (f"Hello {name}") allow inline expression evaluation and are the preferred way to format strings in modern Python. problems: - id: py-var-p3 type: fill_blank - question: "To embed a variable `name` inside a string, you write f\"Hello ___\"." - correct: "{name}" - explanation: "f-strings use curly braces to embed expressions. f\"Hello {name}\" evaluates the variable `name` and inserts its string representation." + question: To embed a variable `name` inside a string, you write f"Hello ___". + correct: '{name}' + explanation: f-strings use curly braces to embed expressions. f"Hello {name}" evaluates the variable `name` and inserts its string representation. - id: py-var-p4 type: multiple_choice - question: "What happens when you try to modify a character in a string with `s[0] = 'X'`?" + question: What happens when you try to modify a character in a string with `s[0] = 'X'`? options: - - "It changes the first character" - - "It raises a TypeError" - - "It creates a new string" - - "It returns None" + - It changes the first character + - It raises a TypeError + - It creates a new string + - It returns None correct: 1 - explanation: "Strings in Python are immutable. You cannot change individual characters. Attempting `s[0] = 'X'` raises a TypeError. To modify a string, create a new one: `s = 'X' + s[1:]`." - - # ============================================================ - # 2. Control Flow - # ============================================================ - + explanation: 'Strings in Python are immutable. You cannot change individual characters. Attempting `s[0] = ''X''` raises a TypeError. To modify a string, create a new one: `s = ''X'' + s[1:]`.' + keyPrerequisite: variables-and-types - id: control-flow - name: "Control Flow" + name: Control Flow difficulty: 2 estimatedMinutes: 20 - tags: [foundational, control-flow] - prerequisites: [variables-and-types] + tags: + - foundational + - control-flow + prerequisites: + - variables-and-types knowledgePoints: - id: if-elif-else - instruction: "Python uses `if`, `elif`, and `else` for conditional branching. Blocks are defined by indentation (no braces). Python has no switch/case statement (prior to 3.10's match/case). Truthy/falsy: 0, empty string, empty list, None are all falsy. Everything else is truthy." + instruction: 'Python uses `if`, `elif`, and `else` for conditional branching. Blocks are defined by indentation (no braces). Python has no switch/case statement (prior to 3.10''s match/case). Truthy/falsy: 0, empty string, empty list, None are all falsy. Everything else is truthy.' problems: - id: py-cf-p1 type: multiple_choice - question: "Which of the following values is truthy in Python?" + question: Which of the following values is truthy in Python? options: - - "0" - - "''" - - "None" - - "[0]" + - '0' + - '''''' + - None + - '[0]' correct: 3 - explanation: "A list containing an element -- even if that element is 0 -- is truthy. Only empty containers ([], {}, '', set()) are falsy. [0] has length 1, so it's truthy." + explanation: A list containing an element -- even if that element is 0 -- is truthy. Only empty containers ([], {}, '', set()) are falsy. [0] has length 1, so it's truthy. - id: py-cf-p2 type: true_false - question: "Python uses curly braces `{}` to define code blocks in if statements." - correct: "false" - explanation: "Python uses indentation (typically 4 spaces) to define code blocks. This is not just a style convention -- it's part of the syntax. Incorrect indentation causes IndentationError." + question: Python uses curly braces `{}` to define code blocks in if statements. + correct: 'false' + explanation: Python uses indentation (typically 4 spaces) to define code blocks. This is not just a style convention -- it's part of the syntax. Incorrect indentation causes IndentationError. + keyPrerequisite: variables-and-types - id: for-and-while - instruction: "Python's `for` loop iterates over any iterable (list, string, range, etc.), not a counter. `for x in range(5)` loops 0-4. `while` loops repeat as long as a condition is true. `break` exits the loop, `continue` skips to the next iteration. Python also supports `for/else` -- the else block runs if the loop completes without hitting `break`." + instruction: Python's `for` loop iterates over any iterable (list, string, range, etc.), not a counter. `for x in range(5)` loops 0-4. `while` loops repeat as long as a condition is true. `break` exits the loop, `continue` skips to the next iteration. Python also supports `for/else` -- the else block runs if the loop completes without hitting `break`. problems: - id: py-cf-p3 type: fill_blank - question: "`range(3)` produces the values ___, 1, and 2." - correct: "0" - explanation: "range() starts at 0 by default. range(3) produces 0, 1, 2 -- three values starting from 0, stopping before 3." - - # ============================================================ - # 3. Functions - # ============================================================ - + question: '`range(3)` produces the values ___, 1, and 2.' + correct: '0' + explanation: range() starts at 0 by default. range(3) produces 0, 1, 2 -- three values starting from 0, stopping before 3. + keyPrerequisite: control-flow - id: functions - name: "Functions" + name: Functions difficulty: 2 estimatedMinutes: 20 - tags: [foundational, functions] - prerequisites: [control-flow] + tags: + - foundational + - functions + prerequisites: + - control-flow knowledgePoints: - id: defining-functions - instruction: "Functions are defined with the `def` keyword. Python supports default arguments (`def greet(name='World')`), keyword arguments (`greet(name='Alice')`), and *args/**kwargs for variable arguments. Functions are first-class objects -- you can assign them to variables, pass them as arguments, and return them from other functions." + instruction: Functions are defined with the `def` keyword. Python supports default arguments (`def greet(name='World')`), keyword arguments (`greet(name='Alice')`), and *args/**kwargs for variable arguments. Functions are first-class objects -- you can assign them to variables, pass them as arguments, and return them from other functions. problems: - id: py-fn-p1 type: multiple_choice - question: "What does a Python function return if there is no `return` statement?" + question: What does a Python function return if there is no `return` statement? options: - - "0" - - "An empty string" - - "None" - - "It raises an error" + - '0' + - An empty string + - None + - It raises an error correct: 2 - explanation: "If a function doesn't explicitly return a value, it implicitly returns None. This is Python's equivalent of null/undefined in other languages." + explanation: If a function doesn't explicitly return a value, it implicitly returns None. This is Python's equivalent of null/undefined in other languages. - id: py-fn-p2 type: true_false - question: "In Python, functions can be assigned to variables and passed as arguments to other functions." - correct: "true" - explanation: "Functions are first-class objects in Python. You can do `my_func = len` and then call `my_func([1,2,3])`. This enables patterns like map(), filter(), and decorators." + question: In Python, functions can be assigned to variables and passed as arguments to other functions. + correct: 'true' + explanation: Functions are first-class objects in Python. You can do `my_func = len` and then call `my_func([1,2,3])`. This enables patterns like map(), filter(), and decorators. - id: py-fn-p3 type: fill_blank - question: "To accept any number of positional arguments, a function parameter is prefixed with ___." - correct: "*" - explanation: "The *args syntax collects extra positional arguments into a tuple. `def f(*args)` means f(1, 2, 3) sets args to (1, 2, 3). Similarly, **kwargs collects keyword arguments into a dict." - - # ============================================================ - # 4. Lists and Dicts - # ============================================================ - + question: To accept any number of positional arguments, a function parameter is prefixed with ___. + correct: '*' + explanation: The *args syntax collects extra positional arguments into a tuple. `def f(*args)` means f(1, 2, 3) sets args to (1, 2, 3). Similarly, **kwargs collects keyword arguments into a dict. + keyPrerequisite: control-flow - id: lists-and-dicts - name: "Lists and Dictionaries" + name: Lists and Dictionaries difficulty: 2 estimatedMinutes: 20 - tags: [foundational, data-structures] - prerequisites: [variables-and-types] + tags: + - foundational + - data-structures + prerequisites: + - variables-and-types knowledgePoints: - id: lists - instruction: "Lists are ordered, mutable sequences. Create with `[]` or `list()`. Access by index (0-based), slice with `[start:stop:step]`. Key methods: `append()`, `extend()`, `pop()`, `sort()`, `reverse()`. List comprehensions (`[x*2 for x in range(5)]`) are idiomatic Python for transforming sequences." + instruction: 'Lists are ordered, mutable sequences. Create with `[]` or `list()`. Access by index (0-based), slice with `[start:stop:step]`. Key methods: `append()`, `extend()`, `pop()`, `sort()`, `reverse()`. List comprehensions (`[x*2 for x in range(5)]`) are idiomatic Python for transforming sequences.' problems: - id: py-ld-p1 type: multiple_choice - question: "What does `[1, 2, 3][1:]` return?" + question: What does `[1, 2, 3][1:]` return? options: - - "[1]" - - "[2, 3]" - - "[1, 2]" - - "[3]" + - '[1]' + - '[2, 3]' + - '[1, 2]' + - '[3]' correct: 1 - explanation: "Slicing with [1:] starts at index 1 and goes to the end. So [1, 2, 3][1:] returns [2, 3]. The element at index 0 (which is 1) is excluded." + explanation: Slicing with [1:] starts at index 1 and goes to the end. So [1, 2, 3][1:] returns [2, 3]. The element at index 0 (which is 1) is excluded. - id: py-ld-p2 type: fill_blank - question: "A list comprehension that squares each number: [x**2 for x in ___]" - correct: "range(5)" - explanation: "range(5) produces 0, 1, 2, 3, 4. The comprehension [x**2 for x in range(5)] produces [0, 1, 4, 9, 16]. Any iterable works here, but range() is the most common for generating number sequences." + question: 'A list comprehension that squares each number: [x**2 for x in ___]' + correct: range(5) + explanation: range(5) produces 0, 1, 2, 3, 4. The comprehension [x**2 for x in range(5)] produces [0, 1, 4, 9, 16]. Any iterable works here, but range() is the most common for generating number sequences. + keyPrerequisite: variables-and-types - id: dicts - instruction: "Dictionaries are key-value mappings. Create with `{}` or `dict()`. Keys must be hashable (strings, numbers, tuples). Access with `d[key]` (raises KeyError if missing) or `d.get(key, default)` (returns default if missing). Key methods: `keys()`, `values()`, `items()`. Dict comprehensions: `{k: v for k, v in pairs}`." + instruction: 'Dictionaries are key-value mappings. Create with `{}` or `dict()`. Keys must be hashable (strings, numbers, tuples). Access with `d[key]` (raises KeyError if missing) or `d.get(key, default)` (returns default if missing). Key methods: `keys()`, `values()`, `items()`. Dict comprehensions: `{k: v for k, v in pairs}`.' problems: - id: py-ld-p3 type: multiple_choice - question: "What does `{'a': 1, 'b': 2}.get('c', 0)` return?" + question: 'What does `{''a'': 1, ''b'': 2}.get(''c'', 0)` return?' options: - - "None" - - "KeyError" - - "0" - - "'c'" + - None + - KeyError + - '0' + - '''c''' correct: 2 - explanation: "The .get() method returns the default value (second argument) when the key is not found. Since 'c' is not in the dict, it returns 0. Without the default, .get() returns None instead of raising KeyError." + explanation: The .get() method returns the default value (second argument) when the key is not found. Since 'c' is not in the dict, it returns 0. Without the default, .get() returns None instead of raising KeyError. + keyPrerequisite: lists-and-dicts diff --git a/content/courses/examples/sql-fundamentals.yaml b/content/courses/examples/sql-fundamentals.yaml index c6904cc..cd6e0fe 100644 --- a/content/courses/examples/sql-fundamentals.yaml +++ b/content/courses/examples/sql-fundamentals.yaml @@ -1,151 +1,145 @@ course: id: sql-fundamentals - name: "SQL Fundamentals" - description: "Core SQL concepts for querying relational databases. Covers SELECT, filtering, joins, and aggregations." + name: SQL Fundamentals + description: Core SQL concepts for querying relational databases. Covers SELECT, filtering, joins, and aggregations. estimatedHours: 10 - version: "2026.1" - sourceDocument: "SQL:2023 Standard (ISO/IEC 9075)" - + version: '2026.1' + sourceDocument: SQL:2023 Standard (ISO/IEC 9075) concepts: - - # ============================================================ - # 1. SELECT Queries - # ============================================================ - - id: select-queries - name: "SELECT Queries" + name: SELECT Queries difficulty: 1 estimatedMinutes: 15 - tags: [foundational, queries] + tags: + - foundational + - queries knowledgePoints: - id: basic-select - instruction: "SELECT retrieves data from one or more tables. `SELECT *` returns all columns; `SELECT col1, col2` returns specific columns. Use `DISTINCT` to remove duplicates. Use `AS` to alias column names in results. Execution order: FROM -> WHERE -> SELECT -> ORDER BY -> LIMIT." + instruction: 'SELECT retrieves data from one or more tables. `SELECT *` returns all columns; `SELECT col1, col2` returns specific columns. Use `DISTINCT` to remove duplicates. Use `AS` to alias column names in results. Execution order: FROM -> WHERE -> SELECT -> ORDER BY -> LIMIT.' problems: - id: sql-sel-p1 type: multiple_choice - question: "Which clause limits the columns returned by a query?" + question: Which clause limits the columns returned by a query? options: - - "WHERE" - - "SELECT" - - "FROM" - - "LIMIT" + - WHERE + - SELECT + - FROM + - LIMIT correct: 1 - explanation: "SELECT determines which columns appear in the result. WHERE filters rows, FROM specifies the table, and LIMIT restricts the number of rows returned." + explanation: SELECT determines which columns appear in the result. WHERE filters rows, FROM specifies the table, and LIMIT restricts the number of rows returned. - id: sql-sel-p2 type: true_false - question: "`SELECT DISTINCT city FROM users` can return duplicate city values." - correct: "false" - explanation: "DISTINCT eliminates duplicate rows from the result set. If multiple users share the same city, that city appears only once in the output." + question: '`SELECT DISTINCT city FROM users` can return duplicate city values.' + correct: 'false' + explanation: DISTINCT eliminates duplicate rows from the result set. If multiple users share the same city, that city appears only once in the output. - id: sql-sel-p3 type: fill_blank - question: "To rename a column in the output, use the ___ keyword: `SELECT name AS full_name`." - correct: "AS" - explanation: "AS creates a column alias. `SELECT name AS full_name` returns the name column with the header 'full_name'. The alias only affects the result set, not the underlying table." - - # ============================================================ - # 2. Filtering and Sorting - # ============================================================ - + question: 'To rename a column in the output, use the ___ keyword: `SELECT name AS full_name`.' + correct: AS + explanation: AS creates a column alias. `SELECT name AS full_name` returns the name column with the header 'full_name'. The alias only affects the result set, not the underlying table. - id: filtering-and-sorting - name: "Filtering and Sorting" + name: Filtering and Sorting difficulty: 2 estimatedMinutes: 20 - tags: [foundational, filtering] - prerequisites: [select-queries] + tags: + - foundational + - filtering + prerequisites: + - select-queries knowledgePoints: - id: where-clause - instruction: "WHERE filters rows before they're returned. Supports comparison operators (=, <>, <, >, <=, >=), logical operators (AND, OR, NOT), pattern matching (LIKE with % and _ wildcards), range checks (BETWEEN), set membership (IN), and NULL checks (IS NULL, IS NOT NULL). Note: you cannot use = to check for NULL -- only IS NULL works." + instruction: 'WHERE filters rows before they''re returned. Supports comparison operators (=, <>, <, >, <=, >=), logical operators (AND, OR, NOT), pattern matching (LIKE with % and _ wildcards), range checks (BETWEEN), set membership (IN), and NULL checks (IS NULL, IS NOT NULL). Note: you cannot use = to check for NULL -- only IS NULL works.' problems: - id: sql-filt-p1 type: multiple_choice - question: "Which operator checks for NULL values in SQL?" + question: Which operator checks for NULL values in SQL? options: - - "= NULL" - - "== NULL" - - "IS NULL" - - "EQUALS NULL" + - '= NULL' + - '== NULL' + - IS NULL + - EQUALS NULL correct: 2 - explanation: "NULL represents an unknown value, so equality comparisons don't work with it. `WHERE col = NULL` always evaluates to unknown (not true). You must use `IS NULL` or `IS NOT NULL`." + explanation: NULL represents an unknown value, so equality comparisons don't work with it. `WHERE col = NULL` always evaluates to unknown (not true). You must use `IS NULL` or `IS NOT NULL`. - id: sql-filt-p2 type: true_false - question: "`WHERE name LIKE 'A%'` matches any name that contains the letter A." - correct: "false" - explanation: "The pattern 'A%' matches names that START with A. The % wildcard matches zero or more characters. To match names containing A anywhere, use '%A%'." + question: '`WHERE name LIKE ''A%''` matches any name that contains the letter A.' + correct: 'false' + explanation: The pattern 'A%' matches names that START with A. The % wildcard matches zero or more characters. To match names containing A anywhere, use '%A%'. + keyPrerequisite: select-queries - id: order-by-limit - instruction: "ORDER BY sorts results. Default is ASC (ascending); add DESC for descending. You can sort by multiple columns: `ORDER BY country ASC, name DESC`. LIMIT restricts the number of rows returned. OFFSET skips rows before returning results. Combined: `ORDER BY created_at DESC LIMIT 10 OFFSET 20` gets the third page of 10 results." + instruction: 'ORDER BY sorts results. Default is ASC (ascending); add DESC for descending. You can sort by multiple columns: `ORDER BY country ASC, name DESC`. LIMIT restricts the number of rows returned. OFFSET skips rows before returning results. Combined: `ORDER BY created_at DESC LIMIT 10 OFFSET 20` gets the third page of 10 results.' problems: - id: sql-filt-p3 type: fill_blank - question: "To get the 5 most recent orders: `SELECT * FROM orders ORDER BY created_at ___ LIMIT 5`." - correct: "DESC" - explanation: "DESC sorts in descending order (newest first). Without DESC, ORDER BY defaults to ASC (oldest first), which would give you the 5 oldest orders instead." - - # ============================================================ - # 3. Joins - # ============================================================ - + question: 'To get the 5 most recent orders: `SELECT * FROM orders ORDER BY created_at ___ LIMIT 5`.' + correct: DESC + explanation: DESC sorts in descending order (newest first). Without DESC, ORDER BY defaults to ASC (oldest first), which would give you the 5 oldest orders instead. + keyPrerequisite: select-queries - id: joins - name: "Joins" + name: Joins difficulty: 3 estimatedMinutes: 25 - tags: [core-concept, joins] - prerequisites: [filtering-and-sorting] + tags: + - core-concept + - joins + prerequisites: + - filtering-and-sorting knowledgePoints: - id: inner-and-outer-joins - instruction: "Joins combine rows from two or more tables based on a related column. INNER JOIN returns only rows with matches in both tables. LEFT JOIN returns all rows from the left table plus matching rows from the right (NULLs where no match). RIGHT JOIN is the opposite. FULL OUTER JOIN returns all rows from both tables. The join condition is specified with ON." + instruction: Joins combine rows from two or more tables based on a related column. INNER JOIN returns only rows with matches in both tables. LEFT JOIN returns all rows from the left table plus matching rows from the right (NULLs where no match). RIGHT JOIN is the opposite. FULL OUTER JOIN returns all rows from both tables. The join condition is specified with ON. problems: - id: sql-join-p1 type: multiple_choice - question: "Which join type returns all rows from the left table, even if there is no match in the right table?" + question: Which join type returns all rows from the left table, even if there is no match in the right table? options: - - "INNER JOIN" - - "LEFT JOIN" - - "CROSS JOIN" - - "SELF JOIN" + - INNER JOIN + - LEFT JOIN + - CROSS JOIN + - SELF JOIN correct: 1 - explanation: "LEFT JOIN (or LEFT OUTER JOIN) returns every row from the left table. If a left row has no matching right row, the right columns are filled with NULL. INNER JOIN would exclude those unmatched rows entirely." + explanation: LEFT JOIN (or LEFT OUTER JOIN) returns every row from the left table. If a left row has no matching right row, the right columns are filled with NULL. INNER JOIN would exclude those unmatched rows entirely. - id: sql-join-p2 type: true_false - question: "An INNER JOIN can return more rows than either input table if there are multiple matches." - correct: "true" - explanation: "If a row in table A matches multiple rows in table B, the join produces one output row per match. A one-to-many relationship can produce more rows than either original table contains." + question: An INNER JOIN can return more rows than either input table if there are multiple matches. + correct: 'true' + explanation: If a row in table A matches multiple rows in table B, the join produces one output row per match. A one-to-many relationship can produce more rows than either original table contains. - id: sql-join-p3 type: fill_blank - question: "SELECT * FROM users ___ orders ON users.id = orders.user_id" - correct: "JOIN" - explanation: "JOIN (or INNER JOIN) combines rows where the condition matches. Here it links each user to their orders via the user_id foreign key. JOIN and INNER JOIN are synonymous." - - # ============================================================ - # 4. Aggregations - # ============================================================ - + question: SELECT * FROM users ___ orders ON users.id = orders.user_id + correct: JOIN + explanation: JOIN (or INNER JOIN) combines rows where the condition matches. Here it links each user to their orders via the user_id foreign key. JOIN and INNER JOIN are synonymous. + keyPrerequisite: filtering-and-sorting - id: aggregations - name: "Aggregations" + name: Aggregations difficulty: 3 estimatedMinutes: 25 - tags: [core-concept, aggregations] - prerequisites: [filtering-and-sorting] + tags: + - core-concept + - aggregations + prerequisites: + - filtering-and-sorting knowledgePoints: - id: aggregate-functions - instruction: "Aggregate functions compute a single value from a set of rows: COUNT(), SUM(), AVG(), MIN(), MAX(). COUNT(*) counts all rows; COUNT(col) counts non-NULL values. GROUP BY splits rows into groups, and the aggregate function runs per group. HAVING filters groups after aggregation (WHERE filters rows before aggregation)." + instruction: 'Aggregate functions compute a single value from a set of rows: COUNT(), SUM(), AVG(), MIN(), MAX(). COUNT(*) counts all rows; COUNT(col) counts non-NULL values. GROUP BY splits rows into groups, and the aggregate function runs per group. HAVING filters groups after aggregation (WHERE filters rows before aggregation).' problems: - id: sql-agg-p1 type: multiple_choice - question: "What is the difference between WHERE and HAVING?" + question: What is the difference between WHERE and HAVING? options: - - "They are interchangeable" - - "WHERE filters rows before grouping; HAVING filters groups after aggregation" - - "HAVING filters rows; WHERE filters groups" - - "WHERE works with JOINs; HAVING does not" + - They are interchangeable + - WHERE filters rows before grouping; HAVING filters groups after aggregation + - HAVING filters rows; WHERE filters groups + - WHERE works with JOINs; HAVING does not correct: 1 - explanation: "WHERE runs before GROUP BY and filters individual rows. HAVING runs after GROUP BY and filters aggregated groups. For example: WHERE status = 'active' filters rows first, then HAVING COUNT(*) > 5 filters groups with more than 5 rows." + explanation: 'WHERE runs before GROUP BY and filters individual rows. HAVING runs after GROUP BY and filters aggregated groups. For example: WHERE status = ''active'' filters rows first, then HAVING COUNT(*) > 5 filters groups with more than 5 rows.' - id: sql-agg-p2 type: true_false - question: "`COUNT(column_name)` includes NULL values in its count." - correct: "false" - explanation: "COUNT(column_name) counts only non-NULL values in that column. To count all rows including NULLs, use COUNT(*). This distinction matters when columns have missing data." + question: '`COUNT(column_name)` includes NULL values in its count.' + correct: 'false' + explanation: COUNT(column_name) counts only non-NULL values in that column. To count all rows including NULLs, use COUNT(*). This distinction matters when columns have missing data. - id: sql-agg-p3 type: fill_blank - question: "To find the average order total per customer: `SELECT customer_id, AVG(total) FROM orders ___ customer_id`." - correct: "GROUP BY" - explanation: "GROUP BY partitions rows into groups by the specified column(s). The AVG() function then computes the average within each group. Every non-aggregated column in SELECT must appear in GROUP BY." + question: 'To find the average order total per customer: `SELECT customer_id, AVG(total) FROM orders ___ customer_id`.' + correct: GROUP BY + explanation: GROUP BY partitions rows into groups by the specified column(s). The AVG() function then computes the average within each group. Every non-aggregated column in SELECT must appear in GROUP BY. + keyPrerequisite: filtering-and-sorting diff --git a/content/courses/javascript-fundamentals.yaml b/content/courses/javascript-fundamentals.yaml index c77bc03..0e236e4 100644 --- a/content/courses/javascript-fundamentals.yaml +++ b/content/courses/javascript-fundamentals.yaml @@ -1,537 +1,565 @@ course: id: javascript-fundamentals - name: "JavaScript Fundamentals" - description: "Core JavaScript concepts for web developers. Covers ES2024, from variables and types through async patterns, closures, and the event loop." + name: JavaScript Fundamentals + description: Core JavaScript concepts for web developers. Covers ES2024, from variables and types through async patterns, closures, and the event loop. estimatedHours: 30 - version: "2024.1" - sourceDocument: "ECMAScript 2024 Language Specification (ECMA-262)" - + version: '2024.1' + sourceDocument: ECMAScript 2024 Language Specification (ECMA-262) concepts: - - # ============================================================ - # 1. Variables & Types - # ============================================================ - - id: variables-and-declarations - name: "Variables and Declarations (let, const, var)" + name: Variables and Declarations (let, const, var) difficulty: 1 estimatedMinutes: 15 - tags: [s01-basics, variables, foundational] - sourceRef: "ECMA-262 §14.3" + tags: + - s01-basics + - variables + - foundational + sourceRef: ECMA-262 §14.3 knowledgePoints: - id: let-const-var-differences - instruction: "JavaScript has three ways to declare variables: `var`, `let`, and `const`. `var` is function-scoped and hoisted. `let` and `const` are block-scoped. `const` prevents reassignment but does not make objects immutable. In modern JS, default to `const`, use `let` when you need reassignment, and avoid `var`." + instruction: 'JavaScript has three ways to declare variables: `var`, `let`, and `const`. `var` is function-scoped and hoisted. `let` and `const` are block-scoped. `const` prevents reassignment but does not make objects immutable. In modern JS, default to `const`, use `let` when you need reassignment, and avoid `var`.' problems: - id: var-decl-p1 type: multiple_choice - question: "What happens when you try to access a `let` variable before its declaration in the same block?" + question: What happens when you try to access a `let` variable before its declaration in the same block? options: - - "It returns undefined (like var)" - - "It throws a ReferenceError (temporal dead zone)" - - "It returns null" - - "It silently creates a global variable" + - It returns undefined (like var) + - It throws a ReferenceError (temporal dead zone) + - It returns null + - It silently creates a global variable correct: 1 - explanation: "Variables declared with `let` and `const` exist in a 'temporal dead zone' from the start of the block until the declaration is reached. Accessing them before declaration throws a ReferenceError. This is different from `var`, which is hoisted and initialized to undefined." + explanation: Variables declared with `let` and `const` exist in a 'temporal dead zone' from the start of the block until the declaration is reached. Accessing them before declaration throws a ReferenceError. This is different from `var`, which is hoisted and initialized to undefined. - id: var-decl-p2 type: true_false - question: "A variable declared with `const` that holds an object can still have its properties modified." - correct: "true" - explanation: "`const` prevents reassignment of the variable binding, not mutation of the value. `const obj = {a: 1}; obj.a = 2;` is perfectly valid. To prevent mutation, use Object.freeze()." + question: A variable declared with `const` that holds an object can still have its properties modified. + correct: 'true' + explanation: '`const` prevents reassignment of the variable binding, not mutation of the value. `const obj = {a: 1}; obj.a = 2;` is perfectly valid. To prevent mutation, use Object.freeze().' - id: var-decl-p3 type: multiple_choice - question: "Which declaration is function-scoped rather than block-scoped?" + question: Which declaration is function-scoped rather than block-scoped? options: - - "let" - - "const" - - "var" - - "All three are block-scoped" + - let + - const + - var + - All three are block-scoped correct: 2 - explanation: "`var` is function-scoped — it's visible throughout the entire function it's declared in, ignoring block boundaries like if/for. `let` and `const` are block-scoped, confined to the nearest enclosing `{}`." - + explanation: '`var` is function-scoped — it''s visible throughout the entire function it''s declared in, ignoring block boundaries like if/for. `let` and `const` are block-scoped, confined to the nearest enclosing `{}`.' - id: primitive-types - name: "Primitive Types and Type Coercion" + name: Primitive Types and Type Coercion difficulty: 2 estimatedMinutes: 20 - tags: [s01-basics, types, foundational] - sourceRef: "ECMA-262 §6.1" - prerequisites: [variables-and-declarations] + tags: + - s01-basics + - types + - foundational + sourceRef: ECMA-262 §6.1 + prerequisites: + - variables-and-declarations knowledgePoints: - id: seven-primitives - instruction: "JavaScript has 7 primitive types: string, number, bigint, boolean, undefined, null, and symbol. Everything else is an object. Primitives are immutable and compared by value. The `typeof` operator returns a string indicating the type, with the famous quirk that `typeof null` returns 'object'." + instruction: 'JavaScript has 7 primitive types: string, number, bigint, boolean, undefined, null, and symbol. Everything else is an object. Primitives are immutable and compared by value. The `typeof` operator returns a string indicating the type, with the famous quirk that `typeof null` returns ''object''.' problems: - id: primitives-p1 type: multiple_choice - question: "What does `typeof null` return in JavaScript?" + question: What does `typeof null` return in JavaScript? options: - - "'null'" - - "'undefined'" - - "'object'" - - "'NaN'" + - '''null''' + - '''undefined''' + - '''object''' + - '''NaN''' correct: 2 - explanation: "This is a well-known bug inherited from the first version of JavaScript. `typeof null` returns 'object' even though null is a primitive. This has never been fixed because too much existing code depends on this behavior." + explanation: This is a well-known bug inherited from the first version of JavaScript. `typeof null` returns 'object' even though null is a primitive. This has never been fixed because too much existing code depends on this behavior. - id: primitives-p2 type: fill_blank - question: "JavaScript has ___ primitive types." - correct: "7" - explanation: "The 7 primitives are: string, number, bigint, boolean, undefined, null, and symbol. BigInt was added in ES2020 and Symbol in ES2015." + question: JavaScript has ___ primitive types. + correct: '7' + explanation: 'The 7 primitives are: string, number, bigint, boolean, undefined, null, and symbol. BigInt was added in ES2020 and Symbol in ES2015.' - id: primitives-p3 type: true_false - question: "The expression `0 == ''` evaluates to true in JavaScript." - correct: "true" - explanation: "The loose equality operator (==) performs type coercion. The empty string '' is coerced to the number 0, so `0 == ''` is true. This is why you should use strict equality (===) which does not coerce types." - - # ============================================================ - # 2. Functions - # ============================================================ - + question: The expression `0 == ''` evaluates to true in JavaScript. + correct: 'true' + explanation: The loose equality operator (==) performs type coercion. The empty string '' is coerced to the number 0, so `0 == ''` is true. This is why you should use strict equality (===) which does not coerce types. + keyPrerequisite: variables-and-declarations - id: function-declarations - name: "Function Declarations, Expressions, and Arrow Functions" + name: Function Declarations, Expressions, and Arrow Functions difficulty: 2 estimatedMinutes: 20 - tags: [s02-functions, foundational] - sourceRef: "ECMA-262 §15.2" - prerequisites: [variables-and-declarations] + tags: + - s02-functions + - foundational + sourceRef: ECMA-262 §15.2 + prerequisites: + - variables-and-declarations knowledgePoints: - id: three-ways-to-define - instruction: "Functions can be defined three ways: declarations (`function foo() {}`), expressions (`const foo = function() {}`), and arrow functions (`const foo = () => {}`). Declarations are hoisted — you can call them before they appear in code. Expressions and arrows are not. Arrow functions don't have their own `this` — they inherit it from the enclosing scope." + instruction: 'Functions can be defined three ways: declarations (`function foo() {}`), expressions (`const foo = function() {}`), and arrow functions (`const foo = () => {}`). Declarations are hoisted — you can call them before they appear in code. Expressions and arrows are not. Arrow functions don''t have their own `this` — they inherit it from the enclosing scope.' problems: - id: func-decl-p1 type: multiple_choice - question: "Which of the following can be called before it appears in the source code?" + question: Which of the following can be called before it appears in the source code? options: - - "const greet = function() { return 'hi'; }" - - "function greet() { return 'hi'; }" - - "const greet = () => 'hi';" - - "All of the above" + - const greet = function() { return 'hi'; } + - function greet() { return 'hi'; } + - const greet = () => 'hi'; + - All of the above correct: 1 - explanation: "Only function declarations are hoisted completely (both the name and the body). Function expressions and arrow functions assigned to variables are hoisted as variable declarations only — the value is undefined until the assignment executes." + explanation: Only function declarations are hoisted completely (both the name and the body). Function expressions and arrow functions assigned to variables are hoisted as variable declarations only — the value is undefined until the assignment executes. - id: func-decl-p2 type: true_false - question: "Arrow functions have their own `this` binding." - correct: "false" - explanation: "Arrow functions do not create their own `this` context. They lexically inherit `this` from the enclosing scope. This makes them ideal for callbacks where you want to preserve the outer `this`, but unsuitable as object methods or constructors." + question: Arrow functions have their own `this` binding. + correct: 'false' + explanation: Arrow functions do not create their own `this` context. They lexically inherit `this` from the enclosing scope. This makes them ideal for callbacks where you want to preserve the outer `this`, but unsuitable as object methods or constructors. - id: func-decl-p3 type: fill_blank - question: "Arrow functions cannot be used as ___ because they lack a [[Construct]] internal method." - correct: "constructors" - explanation: "Arrow functions don't have a [[Construct]] method, so calling `new` on them throws a TypeError. They also don't have a `prototype` property. Use regular function declarations or class syntax when you need constructors." - + question: Arrow functions cannot be used as ___ because they lack a [[Construct]] internal method. + correct: constructors + explanation: Arrow functions don't have a [[Construct]] method, so calling `new` on them throws a TypeError. They also don't have a `prototype` property. Use regular function declarations or class syntax when you need constructors. + keyPrerequisite: variables-and-declarations - id: closures - name: "Closures and Lexical Scope" + name: Closures and Lexical Scope difficulty: 5 estimatedMinutes: 25 - tags: [s02-functions, closures, core-concept] - sourceRef: "ECMA-262 §9.2" - prerequisites: [function-declarations] + tags: + - s02-functions + - closures + - core-concept + sourceRef: ECMA-262 §9.2 + prerequisites: + - function-declarations knowledgePoints: - id: closure-definition - instruction: "A closure is a function that retains access to variables from its outer (enclosing) scope even after the outer function has returned. Every function in JavaScript forms a closure over its lexical environment. This is how data privacy, factory functions, and module patterns work." - workedExample: "function makeCounter() { let count = 0; return { increment() { return ++count; }, get() { return count; } }; } — The returned object's methods close over `count`. Each call to makeCounter() creates a separate `count` variable." + instruction: A closure is a function that retains access to variables from its outer (enclosing) scope even after the outer function has returned. Every function in JavaScript forms a closure over its lexical environment. This is how data privacy, factory functions, and module patterns work. + workedExample: function makeCounter() { let count = 0; return { increment() { return ++count; }, get() { return count; } }; } — The returned object's methods close over `count`. Each call to makeCounter() creates a separate `count` variable. problems: - id: closure-p1 type: multiple_choice - question: "What does this code output? `function make() { let x = 1; return function() { return x++; }; } const fn = make(); console.log(fn(), fn());`" + question: What does this code output? `function make() { let x = 1; return function() { return x++; }; } const fn = make(); console.log(fn(), fn());` options: - - "1, 1" - - "1, 2" - - "undefined, undefined" - - "ReferenceError" + - 1, 1 + - 1, 2 + - undefined, undefined + - ReferenceError correct: 1 - explanation: "The inner function closes over `x`. First call returns 1 (then increments x to 2). Second call returns 2 (then increments to 3). The variable `x` persists in the closure's scope between calls." + explanation: The inner function closes over `x`. First call returns 1 (then increments x to 2). Second call returns 2 (then increments to 3). The variable `x` persists in the closure's scope between calls. - id: closure-p2 type: true_false - question: "Each call to an outer function creates a new closure with its own copy of the enclosed variables." - correct: "true" - explanation: "Every invocation of the outer function creates a new lexical environment with fresh variable bindings. So `make()` called twice produces two independent closures, each with its own `x`." + question: Each call to an outer function creates a new closure with its own copy of the enclosed variables. + correct: 'true' + explanation: Every invocation of the outer function creates a new lexical environment with fresh variable bindings. So `make()` called twice produces two independent closures, each with its own `x`. - id: closure-p3 type: multiple_choice - question: "Which pattern relies on closures to provide data privacy?" + question: Which pattern relies on closures to provide data privacy? options: - - "Prototype chain" - - "Module pattern (IIFE returning public API)" - - "Event delegation" - - "CSS-in-JS" + - Prototype chain + - Module pattern (IIFE returning public API) + - Event delegation + - CSS-in-JS correct: 1 - explanation: "The module pattern uses an IIFE that returns an object exposing only public methods. Private variables declared inside the IIFE are accessible to the returned methods via closure but invisible to outside code." - - # ============================================================ - # 3. Objects & Arrays - # ============================================================ - + explanation: The module pattern uses an IIFE that returns an object exposing only public methods. Private variables declared inside the IIFE are accessible to the returned methods via closure but invisible to outside code. + keyPrerequisite: function-declarations - id: objects-and-prototypes - name: "Objects, Prototypes, and the Prototype Chain" + name: Objects, Prototypes, and the Prototype Chain difficulty: 5 estimatedMinutes: 25 - tags: [s03-objects, prototypes, core-concept] - sourceRef: "ECMA-262 §10.1" - prerequisites: [primitive-types, function-declarations] + tags: + - s03-objects + - prototypes + - core-concept + sourceRef: ECMA-262 §10.1 + prerequisites: + - primitive-types + - function-declarations knowledgePoints: - id: prototype-chain - instruction: "Every JavaScript object has an internal [[Prototype]] link to another object (or null). When you access a property, the engine walks up the prototype chain until it finds the property or reaches null. `Object.create(proto)` creates an object with a specific prototype. Constructor functions set the prototype via their `.prototype` property." + instruction: Every JavaScript object has an internal [[Prototype]] link to another object (or null). When you access a property, the engine walks up the prototype chain until it finds the property or reaches null. `Object.create(proto)` creates an object with a specific prototype. Constructor functions set the prototype via their `.prototype` property. problems: - id: proto-p1 type: multiple_choice - question: "What is at the top of every prototype chain in JavaScript?" + question: What is at the top of every prototype chain in JavaScript? options: - - "Object" - - "Object.prototype" - - "null" - - "undefined" + - Object + - Object.prototype + - 'null' + - undefined correct: 2 - explanation: "The prototype chain ends at null. Object.prototype's [[Prototype]] is null. So the chain is: your object → ... → Object.prototype → null." + explanation: 'The prototype chain ends at null. Object.prototype''s [[Prototype]] is null. So the chain is: your object → ... → Object.prototype → null.' - id: proto-p2 type: true_false - question: "`Object.create(null)` creates an object with no prototype chain — it has no inherited methods like toString() or hasOwnProperty()." - correct: "true" - explanation: "Object.create(null) creates a 'pure dictionary' object with [[Prototype]] set to null. It has no inherited properties at all. This is sometimes used for clean lookup tables." + question: '`Object.create(null)` creates an object with no prototype chain — it has no inherited methods like toString() or hasOwnProperty().' + correct: 'true' + explanation: Object.create(null) creates a 'pure dictionary' object with [[Prototype]] set to null. It has no inherited properties at all. This is sometimes used for clean lookup tables. - id: proto-p3 type: fill_blank - question: "The method `obj.hasOwnProperty('key')` returns true only for properties defined directly on ___, not inherited from the prototype chain." - correct: "obj" - explanation: "hasOwnProperty checks only the object's own properties, skipping anything inherited through the prototype chain. In modern JS, `Object.hasOwn(obj, 'key')` is preferred as it works even on objects created with Object.create(null)." - + question: The method `obj.hasOwnProperty('key')` returns true only for properties defined directly on ___, not inherited from the prototype chain. + correct: obj + explanation: hasOwnProperty checks only the object's own properties, skipping anything inherited through the prototype chain. In modern JS, `Object.hasOwn(obj, 'key')` is preferred as it works even on objects created with Object.create(null). + keyPrerequisite: function-declarations - id: array-methods - name: "Array Methods (map, filter, reduce, and Friends)" + name: Array Methods (map, filter, reduce, and Friends) difficulty: 3 estimatedMinutes: 20 - tags: [s03-objects, arrays, foundational] - sourceRef: "ECMA-262 §23.1" - prerequisites: [function-declarations] + tags: + - s03-objects + - arrays + - foundational + sourceRef: ECMA-262 §23.1 + prerequisites: + - function-declarations knowledgePoints: - id: functional-array-methods - instruction: "The key functional array methods: `map` transforms each element and returns a new array. `filter` returns a new array with elements that pass a test. `reduce` accumulates values into a single result. `find` returns the first matching element. `some`/`every` return booleans. None of these mutate the original array." + instruction: 'The key functional array methods: `map` transforms each element and returns a new array. `filter` returns a new array with elements that pass a test. `reduce` accumulates values into a single result. `find` returns the first matching element. `some`/`every` return booleans. None of these mutate the original array.' problems: - id: array-p1 type: multiple_choice - question: "What does `[1,2,3].map(x => x * 2).filter(x => x > 2)` return?" + question: What does `[1,2,3].map(x => x * 2).filter(x => x > 2)` return? options: - - "[2, 4, 6]" - - "[4, 6]" - - "[2, 6]" - - "[1, 2, 3]" + - '[2, 4, 6]' + - '[4, 6]' + - '[2, 6]' + - '[1, 2, 3]' correct: 1 - explanation: "map doubles each: [2, 4, 6]. Then filter keeps values > 2: [4, 6]." + explanation: 'map doubles each: [2, 4, 6]. Then filter keeps values > 2: [4, 6].' - id: array-p2 type: true_false - question: "`Array.prototype.sort()` mutates the original array." - correct: "true" - explanation: "sort() is one of the few array methods that mutates in place. It returns the same array reference, not a copy. Use `[...arr].sort()` or `arr.toSorted()` (ES2023) for a non-mutating sort." + question: '`Array.prototype.sort()` mutates the original array.' + correct: 'true' + explanation: sort() is one of the few array methods that mutates in place. It returns the same array reference, not a copy. Use `[...arr].sort()` or `arr.toSorted()` (ES2023) for a non-mutating sort. - id: array-p3 type: fill_blank - question: "The array method ___ combines all elements into a single value using an accumulator function." - correct: "reduce" - explanation: "reduce takes a callback(accumulator, currentValue) and an optional initial value. It iterates through the array, passing the return value of each iteration as the accumulator to the next." - - # ============================================================ - # 4. this, Classes, and OOP - # ============================================================ - + question: The array method ___ combines all elements into a single value using an accumulator function. + correct: reduce + explanation: reduce takes a callback(accumulator, currentValue) and an optional initial value. It iterates through the array, passing the return value of each iteration as the accumulator to the next. + keyPrerequisite: function-declarations - id: this-keyword - name: "The `this` Keyword and Binding Rules" + name: The `this` Keyword and Binding Rules difficulty: 6 estimatedMinutes: 25 - tags: [s04-oop, this, core-concept] - sourceRef: "ECMA-262 §8.3" - prerequisites: [function-declarations, objects-and-prototypes] + tags: + - s04-oop + - this + - core-concept + sourceRef: ECMA-262 §8.3 + prerequisites: + - function-declarations + - objects-and-prototypes knowledgePoints: - id: four-binding-rules - instruction: "The value of `this` depends on how a function is called, not where it's defined. Four rules, in precedence order: (1) `new` binding — `this` is the new object. (2) Explicit binding — `call`, `apply`, `bind` set `this`. (3) Implicit binding — `obj.method()` sets `this` to `obj`. (4) Default binding — standalone call, `this` is `undefined` in strict mode, `globalThis` in sloppy mode. Arrow functions skip all rules and use lexical `this`." + instruction: 'The value of `this` depends on how a function is called, not where it''s defined. Four rules, in precedence order: (1) `new` binding — `this` is the new object. (2) Explicit binding — `call`, `apply`, `bind` set `this`. (3) Implicit binding — `obj.method()` sets `this` to `obj`. (4) Default binding — standalone call, `this` is `undefined` in strict mode, `globalThis` in sloppy mode. Arrow functions skip all rules and use lexical `this`.' problems: - id: this-p1 type: multiple_choice - question: "In strict mode, what is `this` inside a standalone function call like `foo()`?" + question: In strict mode, what is `this` inside a standalone function call like `foo()`? options: - - "The global object (window/globalThis)" - - "undefined" - - "null" - - "The function itself" + - The global object (window/globalThis) + - undefined + - 'null' + - The function itself correct: 1 - explanation: "In strict mode, the default binding sets `this` to undefined. In sloppy mode, it would be the global object. This is a common source of bugs when extracting methods from objects." + explanation: In strict mode, the default binding sets `this` to undefined. In sloppy mode, it would be the global object. This is a common source of bugs when extracting methods from objects. - id: this-p2 type: multiple_choice - question: "Given `const obj = { name: 'A', greet() { return this.name; } }; const fn = obj.greet; fn();` — what happens in strict mode?" + question: 'Given `const obj = { name: ''A'', greet() { return this.name; } }; const fn = obj.greet; fn();` — what happens in strict mode?' options: - - "Returns 'A'" - - "Returns undefined" - - "Throws TypeError (cannot read property 'name' of undefined)" - - "Returns an empty string" + - Returns 'A' + - Returns undefined + - Throws TypeError (cannot read property 'name' of undefined) + - Returns an empty string correct: 2 - explanation: "Assigning obj.greet to fn loses the implicit binding. Calling fn() standalone in strict mode sets this to undefined. Accessing undefined.name throws a TypeError." + explanation: Assigning obj.greet to fn loses the implicit binding. Calling fn() standalone in strict mode sets this to undefined. Accessing undefined.name throws a TypeError. - id: this-p3 type: fill_blank - question: "The method `fn.___()` creates a new function with `this` permanently set to a specific value." - correct: "bind" - explanation: "Function.prototype.bind() returns a new function with `this` fixed to the provided value. Unlike call/apply which invoke immediately, bind returns a function for later use." - + question: The method `fn.___()` creates a new function with `this` permanently set to a specific value. + correct: bind + explanation: Function.prototype.bind() returns a new function with `this` fixed to the provided value. Unlike call/apply which invoke immediately, bind returns a function for later use. + keyPrerequisite: objects-and-prototypes - id: classes-and-inheritance - name: "ES6 Classes and Inheritance" + name: ES6 Classes and Inheritance difficulty: 4 estimatedMinutes: 20 - tags: [s04-oop, classes] - sourceRef: "ECMA-262 §15.7" - prerequisites: [this-keyword] + tags: + - s04-oop + - classes + sourceRef: ECMA-262 §15.7 + prerequisites: + - this-keyword knowledgePoints: - id: class-syntax - instruction: "ES6 classes are syntactic sugar over prototype-based inheritance. `class Foo { constructor() {} method() {} }` creates a constructor function with methods on its prototype. `class Bar extends Foo` sets up the prototype chain. `super()` calls the parent constructor. Private fields use `#` prefix (ES2022). Static methods belong to the class itself, not instances." + instruction: ES6 classes are syntactic sugar over prototype-based inheritance. `class Foo { constructor() {} method() {} }` creates a constructor function with methods on its prototype. `class Bar extends Foo` sets up the prototype chain. `super()` calls the parent constructor. Private fields use `#` prefix (ES2022). Static methods belong to the class itself, not instances. problems: - id: class-p1 type: true_false - question: "ES6 classes introduce a new object-oriented inheritance model different from JavaScript's prototype chain." - correct: "false" - explanation: "Classes are syntactic sugar over the existing prototype-based system. `class Foo {}` still creates a constructor function with a .prototype object. The prototype chain works exactly the same way underneath." + question: ES6 classes introduce a new object-oriented inheritance model different from JavaScript's prototype chain. + correct: 'false' + explanation: Classes are syntactic sugar over the existing prototype-based system. `class Foo {}` still creates a constructor function with a .prototype object. The prototype chain works exactly the same way underneath. - id: class-p2 type: multiple_choice - question: "What happens if a child class constructor doesn't call `super()` before accessing `this`?" + question: What happens if a child class constructor doesn't call `super()` before accessing `this`? options: - - "this is undefined" - - "It uses the parent's default values" - - "ReferenceError is thrown" - - "It works fine with default values" + - this is undefined + - It uses the parent's default values + - ReferenceError is thrown + - It works fine with default values correct: 2 - explanation: "In a derived class, `this` is uninitialized until `super()` is called. Accessing `this` before `super()` throws a ReferenceError. This ensures the parent constructor initializes the object first." + explanation: In a derived class, `this` is uninitialized until `super()` is called. Accessing `this` before `super()` throws a ReferenceError. This ensures the parent constructor initializes the object first. - id: class-p3 type: fill_blank - question: "Private class fields in modern JavaScript are declared with the ___ prefix." - correct: "#" - explanation: "ES2022 introduced truly private fields: `#name` is only accessible inside the class body. Unlike the _ convention, # fields are enforced by the engine — accessing them from outside throws a SyntaxError." - - # ============================================================ - # 5. Async JavaScript - # ============================================================ - + question: Private class fields in modern JavaScript are declared with the ___ prefix. + correct: '#' + explanation: 'ES2022 introduced truly private fields: `#name` is only accessible inside the class body. Unlike the _ convention, # fields are enforced by the engine — accessing them from outside throws a SyntaxError.' + keyPrerequisite: this-keyword - id: event-loop - name: "The Event Loop, Call Stack, and Task Queues" + name: The Event Loop, Call Stack, and Task Queues difficulty: 7 estimatedMinutes: 30 - tags: [s05-async, event-loop, core-concept] - sourceRef: "HTML Living Standard §8.1.7" - prerequisites: [closures] + tags: + - s05-async + - event-loop + - core-concept + sourceRef: HTML Living Standard §8.1.7 + prerequisites: + - closures knowledgePoints: - id: event-loop-mechanics - instruction: "JavaScript is single-threaded. The event loop manages concurrency by processing one task at a time from the call stack. When the stack is empty, it checks: (1) the microtask queue (Promises, queueMicrotask) — drained completely, then (2) the macrotask queue (setTimeout, setInterval, I/O) — one task. Microtasks always run before the next macrotask. This is why Promise.then() fires before setTimeout(..., 0)." + instruction: 'JavaScript is single-threaded. The event loop manages concurrency by processing one task at a time from the call stack. When the stack is empty, it checks: (1) the microtask queue (Promises, queueMicrotask) — drained completely, then (2) the macrotask queue (setTimeout, setInterval, I/O) — one task. Microtasks always run before the next macrotask. This is why Promise.then() fires before setTimeout(..., 0).' problems: - id: evloop-p1 type: multiple_choice - question: "What's the output? `console.log('A'); setTimeout(() => console.log('B'), 0); Promise.resolve().then(() => console.log('C')); console.log('D');`" + question: What's the output? `console.log('A'); setTimeout(() => console.log('B'), 0); Promise.resolve().then(() => console.log('C')); console.log('D');` options: - - "A, B, C, D" - - "A, D, B, C" - - "A, D, C, B" - - "A, C, D, B" + - A, B, C, D + - A, D, B, C + - A, D, C, B + - A, C, D, B correct: 2 - explanation: "Synchronous code runs first: A, D. Then the microtask queue (Promise.then): C. Then the macrotask queue (setTimeout): B. Microtasks always drain before the next macrotask." + explanation: 'Synchronous code runs first: A, D. Then the microtask queue (Promise.then): C. Then the macrotask queue (setTimeout): B. Microtasks always drain before the next macrotask.' - id: evloop-p2 type: true_false - question: "A `setTimeout(fn, 0)` guarantees the callback runs immediately after the current synchronous code finishes." - correct: "false" - explanation: "setTimeout(fn, 0) schedules a macrotask. Any pending microtasks (Promise callbacks, MutationObserver) run first. The actual delay is also subject to browser-imposed minimums (usually 4ms for nested timeouts)." + question: A `setTimeout(fn, 0)` guarantees the callback runs immediately after the current synchronous code finishes. + correct: 'false' + explanation: setTimeout(fn, 0) schedules a macrotask. Any pending microtasks (Promise callbacks, MutationObserver) run first. The actual delay is also subject to browser-imposed minimums (usually 4ms for nested timeouts). - id: evloop-p3 type: fill_blank - question: "Promise callbacks (.then, .catch, .finally) are placed in the ___ queue, which has higher priority than setTimeout callbacks." - correct: "microtask" - explanation: "The microtask queue (also called the job queue) is drained completely after each task. Promise handlers, queueMicrotask(), and MutationObserver callbacks all go here." - + question: Promise callbacks (.then, .catch, .finally) are placed in the ___ queue, which has higher priority than setTimeout callbacks. + correct: microtask + explanation: The microtask queue (also called the job queue) is drained completely after each task. Promise handlers, queueMicrotask(), and MutationObserver callbacks all go here. + keyPrerequisite: closures - id: promises - name: "Promises" + name: Promises difficulty: 5 estimatedMinutes: 25 - tags: [s05-async, promises, core-concept] - sourceRef: "ECMA-262 §27.2" - prerequisites: [closures, event-loop] + tags: + - s05-async + - promises + - core-concept + sourceRef: ECMA-262 §27.2 + prerequisites: + - closures + - event-loop knowledgePoints: - id: promise-lifecycle - instruction: "A Promise represents a value that may not exist yet. It's in one of three states: pending, fulfilled, or rejected. Once settled (fulfilled or rejected), it never changes. `.then()` handles fulfillment, `.catch()` handles rejection, `.finally()` runs either way. Promises chain — each `.then()` returns a new Promise. `Promise.all()` waits for all, `Promise.race()` for the first, `Promise.allSettled()` for all regardless of outcome." + instruction: 'A Promise represents a value that may not exist yet. It''s in one of three states: pending, fulfilled, or rejected. Once settled (fulfilled or rejected), it never changes. `.then()` handles fulfillment, `.catch()` handles rejection, `.finally()` runs either way. Promises chain — each `.then()` returns a new Promise. `Promise.all()` waits for all, `Promise.race()` for the first, `Promise.allSettled()` for all regardless of outcome.' problems: - id: promise-p1 type: multiple_choice - question: "What does `Promise.all()` do if one of the input promises rejects?" + question: What does `Promise.all()` do if one of the input promises rejects? options: - - "Returns an array with the error in the rejected position" - - "Waits for all promises to settle, then rejects" - - "Rejects immediately with the first rejection reason" - - "Ignores the rejection and returns fulfilled results" + - Returns an array with the error in the rejected position + - Waits for all promises to settle, then rejects + - Rejects immediately with the first rejection reason + - Ignores the rejection and returns fulfilled results correct: 2 - explanation: "Promise.all() is 'fail-fast' — it rejects as soon as any input promise rejects, with that rejection reason. Use Promise.allSettled() if you want to wait for all promises regardless of outcome." + explanation: Promise.all() is 'fail-fast' — it rejects as soon as any input promise rejects, with that rejection reason. Use Promise.allSettled() if you want to wait for all promises regardless of outcome. - id: promise-p2 type: true_false - question: "A Promise can transition from fulfilled back to pending." - correct: "false" - explanation: "Promises are settled exactly once. Once a Promise is fulfilled or rejected, its state and value are locked forever. This immutability is a core design principle." + question: A Promise can transition from fulfilled back to pending. + correct: 'false' + explanation: Promises are settled exactly once. Once a Promise is fulfilled or rejected, its state and value are locked forever. This immutability is a core design principle. - id: promise-p3 type: fill_blank - question: "`Promise.___()` returns a promise that resolves after ALL input promises settle, giving you the status and value/reason of each." - correct: "allSettled" - explanation: "Promise.allSettled() never rejects. It resolves with an array of {status, value} or {status, reason} objects for each input promise. Added in ES2020." - + question: '`Promise.___()` returns a promise that resolves after ALL input promises settle, giving you the status and value/reason of each.' + correct: allSettled + explanation: Promise.allSettled() never rejects. It resolves with an array of {status, value} or {status, reason} objects for each input promise. Added in ES2020. + keyPrerequisite: event-loop - id: async-await - name: "async/await" + name: async/await difficulty: 4 estimatedMinutes: 20 - tags: [s05-async, async-await] - sourceRef: "ECMA-262 §27.7" - prerequisites: [promises] + tags: + - s05-async + - async-await + sourceRef: ECMA-262 §27.7 + prerequisites: + - promises knowledgePoints: - id: async-await-mechanics - instruction: "`async` functions always return a Promise. `await` pauses execution of the async function until the Promise settles — but it doesn't block the thread. The rest of the function is scheduled as a microtask. Error handling uses try/catch instead of .catch(). Top-level await is available in ES modules." + instruction: '`async` functions always return a Promise. `await` pauses execution of the async function until the Promise settles — but it doesn''t block the thread. The rest of the function is scheduled as a microtask. Error handling uses try/catch instead of .catch(). Top-level await is available in ES modules.' problems: - id: async-p1 type: multiple_choice - question: "What does an `async` function return if you `return 42` from it?" + question: What does an `async` function return if you `return 42` from it? options: - - "The number 42" - - "A Promise that resolves to 42" - - "undefined" - - "A Promise that resolves to undefined" + - The number 42 + - A Promise that resolves to 42 + - undefined + - A Promise that resolves to undefined correct: 1 - explanation: "async functions always wrap the return value in a Promise. `return 42` becomes `Promise.resolve(42)`. If you return a Promise, it's not double-wrapped — the engine unwraps it." + explanation: async functions always wrap the return value in a Promise. `return 42` becomes `Promise.resolve(42)`. If you return a Promise, it's not double-wrapped — the engine unwraps it. - id: async-p2 type: true_false - question: "`await` blocks the JavaScript main thread until the awaited Promise resolves." - correct: "false" - explanation: "await suspends only the async function's execution, not the entire thread. The event loop continues processing other tasks. When the awaited Promise settles, the rest of the async function is queued as a microtask." + question: '`await` blocks the JavaScript main thread until the awaited Promise resolves.' + correct: 'false' + explanation: await suspends only the async function's execution, not the entire thread. The event loop continues processing other tasks. When the awaited Promise settles, the rest of the async function is queued as a microtask. - id: async-p3 type: multiple_choice - question: "How do you handle errors from an awaited Promise?" + question: How do you handle errors from an awaited Promise? options: - - "Use .catch() after await" - - "Wrap the await in try/catch" - - "Use window.onerror" - - "Errors are silently ignored" + - Use .catch() after await + - Wrap the await in try/catch + - Use window.onerror + - Errors are silently ignored correct: 1 - explanation: "try/catch is the standard pattern with async/await. If the awaited Promise rejects, the rejection reason is thrown as an exception. You can also add .catch() to the Promise before awaiting, or use a wrapper utility." - - # ============================================================ - # 6. Scope, Modules, and Modern Features - # ============================================================ - + explanation: try/catch is the standard pattern with async/await. If the awaited Promise rejects, the rejection reason is thrown as an exception. You can also add .catch() to the Promise before awaiting, or use a wrapper utility. + keyPrerequisite: promises - id: destructuring-and-spread - name: "Destructuring, Spread, and Rest" + name: Destructuring, Spread, and Rest difficulty: 3 estimatedMinutes: 15 - tags: [s06-modern, destructuring] - sourceRef: "ECMA-262 §13.15" - prerequisites: [variables-and-declarations, array-methods] + tags: + - s06-modern + - destructuring + sourceRef: ECMA-262 §13.15 + prerequisites: + - variables-and-declarations + - array-methods knowledgePoints: - id: destructuring-patterns - instruction: "Destructuring extracts values from arrays and objects into variables. Array: `const [a, b] = [1, 2]`. Object: `const {name, age} = person`. You can set defaults, rename (`{name: n}`), and nest. Spread (`...`) copies/merges arrays and objects. Rest (`...rest`) collects remaining items in destructuring or function params." + instruction: 'Destructuring extracts values from arrays and objects into variables. Array: `const [a, b] = [1, 2]`. Object: `const {name, age} = person`. You can set defaults, rename (`{name: n}`), and nest. Spread (`...`) copies/merges arrays and objects. Rest (`...rest`) collects remaining items in destructuring or function params.' problems: - id: destr-p1 type: multiple_choice - question: "What does `const {a: x, b: y} = {a: 1, b: 2}` create?" + question: 'What does `const {a: x, b: y} = {a: 1, b: 2}` create?' options: - - "Variables a=1 and b=2" - - "Variables x=1 and y=2" - - "Variables a=x and b=y" - - "A SyntaxError" + - Variables a=1 and b=2 + - Variables x=1 and y=2 + - Variables a=x and b=y + - A SyntaxError correct: 1 - explanation: "In object destructuring, {a: x} means 'take property a, assign it to variable x'. The left side of the colon is the source property, the right side is the target variable name." + explanation: 'In object destructuring, {a: x} means ''take property a, assign it to variable x''. The left side of the colon is the source property, the right side is the target variable name.' - id: destr-p2 type: true_false - question: "The spread operator `{...obj}` creates a deep copy of the object." - correct: "false" - explanation: "Spread creates a shallow copy. Nested objects are still shared references. For deep cloning, use structuredClone() (modern browsers) or a library." + question: The spread operator `{...obj}` creates a deep copy of the object. + correct: 'false' + explanation: Spread creates a shallow copy. Nested objects are still shared references. For deep cloning, use structuredClone() (modern browsers) or a library. - id: destr-p3 type: fill_blank - question: "In `function sum(...nums) {}`, the `...nums` syntax is called the ___ parameter." - correct: "rest" - explanation: "Rest parameters collect all remaining arguments into an array. Unlike the deprecated `arguments` object, rest gives you a real Array with all array methods. A function can only have one rest parameter, and it must be last." - + question: In `function sum(...nums) {}`, the `...nums` syntax is called the ___ parameter. + correct: rest + explanation: Rest parameters collect all remaining arguments into an array. Unlike the deprecated `arguments` object, rest gives you a real Array with all array methods. A function can only have one rest parameter, and it must be last. + keyPrerequisite: variables-and-declarations - id: modules - name: "ES Modules (import/export)" + name: ES Modules (import/export) difficulty: 3 estimatedMinutes: 15 - tags: [s06-modern, modules] - sourceRef: "ECMA-262 §16.2" - prerequisites: [variables-and-declarations] + tags: + - s06-modern + - modules + sourceRef: ECMA-262 §16.2 + prerequisites: + - variables-and-declarations knowledgePoints: - id: module-syntax - instruction: "ES Modules use `export` and `import` for code sharing. Named exports: `export function foo() {}` / `import { foo } from './mod'`. Default exports: `export default class Foo {}` / `import Foo from './mod'`. Modules are strict mode by default, have their own scope (no global leaking), and are evaluated once (singleton). Dynamic import: `const mod = await import('./mod')` for code splitting." + instruction: 'ES Modules use `export` and `import` for code sharing. Named exports: `export function foo() {}` / `import { foo } from ''./mod''`. Default exports: `export default class Foo {}` / `import Foo from ''./mod''`. Modules are strict mode by default, have their own scope (no global leaking), and are evaluated once (singleton). Dynamic import: `const mod = await import(''./mod'')` for code splitting.' problems: - id: module-p1 type: multiple_choice - question: "How many default exports can a module have?" + question: How many default exports can a module have? options: - - "Unlimited" - - "One" - - "Zero (default exports aren't real)" - - "One per function type" + - Unlimited + - One + - Zero (default exports aren't real) + - One per function type correct: 1 - explanation: "Each module can have exactly one default export. It's syntactic sugar for a named export called 'default'. You can have one default export alongside any number of named exports." + explanation: Each module can have exactly one default export. It's syntactic sugar for a named export called 'default'. You can have one default export alongside any number of named exports. - id: module-p2 type: true_false - question: "ES Modules are executed in strict mode automatically." - correct: "true" - explanation: "Module code is always strict mode — no need for 'use strict'. This means no implicit globals, no `with` statement, and `this` at the top level is undefined." + question: ES Modules are executed in strict mode automatically. + correct: 'true' + explanation: Module code is always strict mode — no need for 'use strict'. This means no implicit globals, no `with` statement, and `this` at the top level is undefined. - id: module-p3 type: fill_blank - question: "`const module = await ___('./heavy-lib.js')` loads a module dynamically at runtime." - correct: "import" - explanation: "Dynamic import() returns a Promise that resolves to the module's namespace object. It's useful for code splitting, lazy loading, and conditional imports. Unlike static import declarations, it can be used anywhere in your code." - - # ============================================================ - # 7. Error Handling & Iteration - # ============================================================ - + question: '`const module = await ___(''./heavy-lib.js'')` loads a module dynamically at runtime.' + correct: import + explanation: Dynamic import() returns a Promise that resolves to the module's namespace object. It's useful for code splitting, lazy loading, and conditional imports. Unlike static import declarations, it can be used anywhere in your code. + keyPrerequisite: variables-and-declarations - id: error-handling - name: "Error Handling (try/catch/finally)" + name: Error Handling (try/catch/finally) difficulty: 3 estimatedMinutes: 15 - tags: [s07-patterns, errors] - sourceRef: "ECMA-262 §14.15" - prerequisites: [function-declarations] + tags: + - s07-patterns + - errors + sourceRef: ECMA-262 §14.15 + prerequisites: + - function-declarations knowledgePoints: - id: try-catch-patterns - instruction: "try/catch catches synchronous errors. The `catch` block receives the error object. `finally` always runs — even if there's a return in try or catch. For async code, use try/catch with await. Custom errors extend the Error class. Unhandled rejections can be caught globally with `unhandledrejection` event." + instruction: try/catch catches synchronous errors. The `catch` block receives the error object. `finally` always runs — even if there's a return in try or catch. For async code, use try/catch with await. Custom errors extend the Error class. Unhandled rejections can be caught globally with `unhandledrejection` event. problems: - id: error-p1 type: true_false - question: "The `finally` block runs even if the `try` block contains a `return` statement." - correct: "true" - explanation: "finally always executes — after try, after catch, even after return or throw. The return value is still the one from try/catch, but finally runs before the function actually returns. If finally also has a return, it overrides the try/catch return." + question: The `finally` block runs even if the `try` block contains a `return` statement. + correct: 'true' + explanation: finally always executes — after try, after catch, even after return or throw. The return value is still the one from try/catch, but finally runs before the function actually returns. If finally also has a return, it overrides the try/catch return. - id: error-p2 type: multiple_choice - question: "Which is the correct way to create a custom error type?" + question: Which is the correct way to create a custom error type? options: - - "const err = new Error(); err.type = 'custom';" - - "class CustomError extends Error { constructor(msg) { super(msg); this.name = 'CustomError'; } }" - - "function CustomError(msg) { return Error(msg); }" - - "throw 'custom error string';" + - const err = new Error(); err.type = 'custom'; + - class CustomError extends Error { constructor(msg) { super(msg); this.name = 'CustomError'; } } + - function CustomError(msg) { return Error(msg); } + - throw 'custom error string'; correct: 1 - explanation: "Extending Error gives you proper stack traces, instanceof checks, and the standard name/message/stack properties. Always call super(message) in the constructor." + explanation: Extending Error gives you proper stack traces, instanceof checks, and the standard name/message/stack properties. Always call super(message) in the constructor. - id: error-p3 type: fill_blank - question: "The `window.addEventListener('___', handler)` event catches unhandled Promise rejections in the browser." - correct: "unhandledrejection" - explanation: "The 'unhandledrejection' event fires when a Promise rejects and there's no .catch() handler. In Node.js, use process.on('unhandledRejection', handler). Always handle your rejections to avoid silent failures." - + question: The `window.addEventListener('___', handler)` event catches unhandled Promise rejections in the browser. + correct: unhandledrejection + explanation: The 'unhandledrejection' event fires when a Promise rejects and there's no .catch() handler. In Node.js, use process.on('unhandledRejection', handler). Always handle your rejections to avoid silent failures. + keyPrerequisite: function-declarations - id: iterators-and-generators - name: "Iterators and Generators" + name: Iterators and Generators difficulty: 6 estimatedMinutes: 25 - tags: [s07-patterns, iterators, generators] - sourceRef: "ECMA-262 §27.1" - prerequisites: [closures, objects-and-prototypes] + tags: + - s07-patterns + - iterators + - generators + sourceRef: ECMA-262 §27.1 + prerequisites: + - closures + - objects-and-prototypes knowledgePoints: - id: iterator-protocol - instruction: "An iterable is any object with a `[Symbol.iterator]()` method that returns an iterator. An iterator has a `next()` method returning `{value, done}`. Arrays, strings, Maps, Sets are all iterable. `for...of` works on iterables. Generators (`function*`) create iterators with `yield` to pause/resume. They're lazy — values are computed on demand." + instruction: An iterable is any object with a `[Symbol.iterator]()` method that returns an iterator. An iterator has a `next()` method returning `{value, done}`. Arrays, strings, Maps, Sets are all iterable. `for...of` works on iterables. Generators (`function*`) create iterators with `yield` to pause/resume. They're lazy — values are computed on demand. problems: - id: iter-p1 type: multiple_choice - question: "What method must an object implement to be used in a `for...of` loop?" + question: What method must an object implement to be used in a `for...of` loop? options: - - "forEach()" - - "[Symbol.iterator]()" - - "next()" - - "entries()" + - forEach() + - '[Symbol.iterator]()' + - next() + - entries() correct: 1 - explanation: "for...of calls [Symbol.iterator]() on the object to get an iterator, then repeatedly calls .next() on that iterator until done is true. Any object implementing this protocol is iterable." + explanation: for...of calls [Symbol.iterator]() on the object to get an iterator, then repeatedly calls .next() on that iterator until done is true. Any object implementing this protocol is iterable. - id: iter-p2 type: true_false - question: "Generators execute their entire body when called — `yield` is just an alternative to `return`." - correct: "false" - explanation: "Generators are lazy. Calling a generator function returns an iterator but doesn't execute the body. The body runs only when .next() is called, executing until the next yield, then pausing. This enables lazy evaluation and infinite sequences." + question: Generators execute their entire body when called — `yield` is just an alternative to `return`. + correct: 'false' + explanation: Generators are lazy. Calling a generator function returns an iterator but doesn't execute the body. The body runs only when .next() is called, executing until the next yield, then pausing. This enables lazy evaluation and infinite sequences. - id: iter-p3 type: fill_blank - question: "A generator function is declared with the `function___` syntax (no space)." - correct: "*" - explanation: "function* myGen() {} declares a generator. The asterisk can be placed anywhere between function and the name: function* gen, function *gen, function * gen are all valid. Inside, yield pauses execution and produces a value." + question: A generator function is declared with the `function___` syntax (no space). + correct: '*' + explanation: 'function* myGen() {} declares a generator. The asterisk can be placed anywhere between function and the name: function* gen, function *gen, function * gen are all valid. Inside, yield pauses execution and produces a value.' + keyPrerequisite: objects-and-prototypes diff --git a/content/courses/ny-real-estate-salesperson.yaml b/content/courses/ny-real-estate-salesperson.yaml index 6cfbced..2b8a194 100644 --- a/content/courses/ny-real-estate-salesperson.yaml +++ b/content/courses/ny-real-estate-salesperson.yaml @@ -1,1071 +1,1143 @@ -# NY State Real Estate Salesperson — 77-hour pre-licensing syllabus -# Based on DOS 77-hour syllabus (2022 edition) - course: id: ny-re-salesperson - name: "New York State Real Estate Salesperson" - description: "Based on the DOS 77-hour pre-licensing syllabus (2022 edition)" + name: New York State Real Estate Salesperson + description: Based on the DOS 77-hour pre-licensing syllabus (2022 edition) estimatedHours: 77 - version: "2024.1" - sourceDocument: "NY DOS Real Estate Salesperson Syllabus 2022" - + version: '2024.1' + sourceDocument: NY DOS Real Estate Salesperson Syllabus 2022 concepts: - - # ───────────────────────────────────────────────────────────────────────────── - # Subject 1: License Law & Regulations (3 hr) - # ───────────────────────────────────────────────────────────────────────────── - - id: licensing-categories - name: "Licensing Categories" + name: Licensing Categories difficulty: 2 estimatedMinutes: 20 - tags: [s01-license-law, licensing] - sourceRef: "DOS Syllabus Subject 1: License Law & Regulations" - knowledgePoints: [] # KPs to be authored - + tags: + - s01-license-law + - licensing + sourceRef: 'DOS Syllabus Subject 1: License Law & Regulations' + knowledgePoints: [] - id: maintaining-license - name: "Maintaining a Real Estate License" + name: Maintaining a Real Estate License difficulty: 2 estimatedMinutes: 15 - tags: [s01-license-law, continuing-education] - sourceRef: "DOS Syllabus Subject 1: License Law & Regulations" + tags: + - s01-license-law + - continuing-education + sourceRef: 'DOS Syllabus Subject 1: License Law & Regulations' prerequisites: - licensing-categories - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: dos-regulations - name: "Department of State Regulations" + name: Department of State Regulations difficulty: 3 estimatedMinutes: 25 - tags: [s01-license-law, regulations] - sourceRef: "DOS Syllabus Subject 1: License Law & Regulations" + tags: + - s01-license-law + - regulations + sourceRef: 'DOS Syllabus Subject 1: License Law & Regulations' prerequisites: - licensing-categories - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: license-law-violations - name: "License Law Violations & Penalties" + name: License Law Violations & Penalties difficulty: 4 estimatedMinutes: 20 - tags: [s01-license-law, violations] - sourceRef: "DOS Syllabus Subject 1: License Law & Regulations" + tags: + - s01-license-law + - violations + sourceRef: 'DOS Syllabus Subject 1: License Law & Regulations' prerequisites: - dos-regulations - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: property-condition-disclosure-act - name: "Property Condition Disclosure Act (PCDA)" + name: Property Condition Disclosure Act (PCDA) difficulty: 3 estimatedMinutes: 15 - tags: [s01-license-law, disclosure] - sourceRef: "DOS Syllabus Subject 1: License Law & Regulations" + tags: + - s01-license-law + - disclosure + sourceRef: 'DOS Syllabus Subject 1: License Law & Regulations' prerequisites: - licensing-categories - knowledgePoints: [] # KPs to be authored - - # ───────────────────────────────────────────────────────────────────────────── - # Subject 2: Law of Agency (11 hr) - # ───────────────────────────────────────────────────────────────────────────── - + knowledgePoints: [] - id: fiduciary-duties - name: "Fiduciary Duties of an Agent" + name: Fiduciary Duties of an Agent difficulty: 5 estimatedMinutes: 45 - tags: [s02-agency, fiduciary] - sourceRef: "DOS Syllabus Subject 2: Law of Agency" + tags: + - s02-agency + - fiduciary + sourceRef: 'DOS Syllabus Subject 2: Law of Agency' prerequisites: - licensing-categories knowledgePoints: - id: fiduciary-oldcar - instruction: "content/ny-re/fiduciary-oldcar.md" - workedExample: "content/ny-re/fiduciary-oldcar-ex.md" + instruction: content/ny-re/fiduciary-oldcar.md + workedExample: content/ny-re/fiduciary-oldcar-ex.md problems: - id: fid-p1 type: multiple_choice - question: "Which acronym summarizes the six fiduciary duties an agent owes a principal?" + question: Which acronym summarizes the six fiduciary duties an agent owes a principal? options: - - "OLDCAR — Obedience, Loyalty, Disclosure, Confidentiality, Accountability, Reasonable care" - - "BRRETA — Buyer Representation, Responsibility, Ethics, Trust, Accountability" - - "CLUE — Confidentiality, Loyalty, Undivided attention, Equity" - - "FIDAR — Fiduciary, Integrity, Diligence, Accountability, Representation" + - OLDCAR — Obedience, Loyalty, Disclosure, Confidentiality, Accountability, Reasonable care + - BRRETA — Buyer Representation, Responsibility, Ethics, Trust, Accountability + - CLUE — Confidentiality, Loyalty, Undivided attention, Equity + - FIDAR — Fiduciary, Integrity, Diligence, Accountability, Representation correct: 0 - explanation: "OLDCAR stands for Obedience, Loyalty, Disclosure, Confidentiality, Accountability, and Reasonable care/skill. These are the six fiduciary duties an agent owes to a principal." + explanation: OLDCAR stands for Obedience, Loyalty, Disclosure, Confidentiality, Accountability, and Reasonable care/skill. These are the six fiduciary duties an agent owes to a principal. - id: fid-p2 type: multiple_choice - question: "A seller tells their listing agent that they will accept $20,000 less than the asking price. The agent shares this with a prospective buyer. Which fiduciary duty was violated?" + question: A seller tells their listing agent that they will accept $20,000 less than the asking price. The agent shares this with a prospective buyer. Which fiduciary duty was violated? options: - - "Obedience" - - "Loyalty" - - "Confidentiality" - - "Accountability" + - Obedience + - Loyalty + - Confidentiality + - Accountability correct: 2 - explanation: "The agent violated the duty of Confidentiality by disclosing the seller's bottom-line price to the buyer. An agent must never reveal information that could weaken the principal's negotiating position." + explanation: The agent violated the duty of Confidentiality by disclosing the seller's bottom-line price to the buyer. An agent must never reveal information that could weaken the principal's negotiating position. - id: fid-p3 type: multiple_choice - question: "A buyer's agent learns through the MLS that a property has a cracked foundation. They do not mention it to the buyer. Which duty is violated?" + question: A buyer's agent learns through the MLS that a property has a cracked foundation. They do not mention it to the buyer. Which duty is violated? options: - - "Confidentiality" - - "Disclosure" - - "Obedience" - - "Accountability" + - Confidentiality + - Disclosure + - Obedience + - Accountability correct: 1 - explanation: "The agent violated the duty of Disclosure. Agents must disclose all material facts that could affect the principal's decision, including known property defects." + explanation: The agent violated the duty of Disclosure. Agents must disclose all material facts that could affect the principal's decision, including known property defects. - id: fid-p4 type: fill_blank - question: "The fiduciary duty of ___ requires an agent to follow all lawful instructions of their principal." - correct: "Obedience" - explanation: "Obedience means the agent must carry out the principal's lawful instructions. An agent may refuse only if the instruction is illegal or unethical." + question: The fiduciary duty of ___ requires an agent to follow all lawful instructions of their principal. + correct: Obedience + explanation: Obedience means the agent must carry out the principal's lawful instructions. An agent may refuse only if the instruction is illegal or unethical. - id: fiduciary-vs-customer - instruction: "content/ny-re/fiduciary-vs-customer.md" + instruction: content/ny-re/fiduciary-vs-customer.md problems: - id: fvc-p1 type: multiple_choice - question: "What level of service does an agent owe to a customer (non-client)?" + question: What level of service does an agent owe to a customer (non-client)? options: - - "Full fiduciary duties identical to those owed to a client" - - "Honesty, fair dealing, and disclosure of material facts" - - "No duties whatsoever" - - "Only the duty of confidentiality" + - Full fiduciary duties identical to those owed to a client + - Honesty, fair dealing, and disclosure of material facts + - No duties whatsoever + - Only the duty of confidentiality correct: 1 - explanation: "An agent owes a customer (non-client) honesty, fair dealing, and disclosure of material facts—but not the full OLDCAR fiduciary duties reserved for clients." - + explanation: An agent owes a customer (non-client) honesty, fair dealing, and disclosure of material facts—but not the full OLDCAR fiduciary duties reserved for clients. + keyPrerequisite: fiduciary-duties - id: creation-of-agency - name: "Creation of Agency Relationships" + name: Creation of Agency Relationships difficulty: 4 estimatedMinutes: 35 - tags: [s02-agency, agency-creation] - sourceRef: "DOS Syllabus Subject 2: Law of Agency" + tags: + - s02-agency + - agency-creation + sourceRef: 'DOS Syllabus Subject 2: Law of Agency' prerequisites: - fiduciary-duties - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: sellers-agent - name: "Seller's Agent Relationship" + name: Seller's Agent Relationship difficulty: 4 estimatedMinutes: 30 - tags: [s02-agency, sellers-agent] - sourceRef: "DOS Syllabus Subject 2: Law of Agency" + tags: + - s02-agency + - sellers-agent + sourceRef: 'DOS Syllabus Subject 2: Law of Agency' prerequisites: - creation-of-agency - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: buyers-agent - name: "Buyer's Agent Relationship" + name: Buyer's Agent Relationship difficulty: 4 estimatedMinutes: 30 - tags: [s02-agency, buyers-agent] - sourceRef: "DOS Syllabus Subject 2: Law of Agency" + tags: + - s02-agency + - buyers-agent + sourceRef: 'DOS Syllabus Subject 2: Law of Agency' prerequisites: - creation-of-agency - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: dual-agency - name: "Dual Agency" + name: Dual Agency difficulty: 6 estimatedMinutes: 35 - tags: [s02-agency, dual-agency] - sourceRef: "DOS Syllabus Subject 2: Law of Agency" + tags: + - s02-agency + - dual-agency + sourceRef: 'DOS Syllabus Subject 2: Law of Agency' prerequisites: - sellers-agent - buyers-agent - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: designated-agency - name: "Designated Agency" + name: Designated Agency difficulty: 6 estimatedMinutes: 30 - tags: [s02-agency, designated-agency] - sourceRef: "DOS Syllabus Subject 2: Law of Agency" + tags: + - s02-agency + - designated-agency + sourceRef: 'DOS Syllabus Subject 2: Law of Agency' prerequisites: - dual-agency - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: subagency-vs-buyer-broker - name: "Subagency vs Buyer's Broker" + name: Subagency vs Buyer's Broker difficulty: 5 estimatedMinutes: 30 - tags: [s02-agency, subagency] - sourceRef: "DOS Syllabus Subject 2: Law of Agency" + tags: + - s02-agency + - subagency + sourceRef: 'DOS Syllabus Subject 2: Law of Agency' prerequisites: - sellers-agent - buyers-agent - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: dual-agency-informed-consent - name: "Dual Agency Informed Consent" + name: Dual Agency Informed Consent difficulty: 5 estimatedMinutes: 25 - tags: [s02-agency, dual-agency, consent] - sourceRef: "DOS Syllabus Subject 2: Law of Agency" + tags: + - s02-agency + - dual-agency + - consent + sourceRef: 'DOS Syllabus Subject 2: Law of Agency' prerequisites: - dual-agency - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: rpl-443-disclosure - name: "RPL Section 443 Agency Disclosure" + name: RPL Section 443 Agency Disclosure difficulty: 4 estimatedMinutes: 30 - tags: [s02-agency, disclosure, rpl-443] - sourceRef: "DOS Syllabus Subject 2: Law of Agency" + tags: + - s02-agency + - disclosure + - rpl-443 + sourceRef: 'DOS Syllabus Subject 2: Law of Agency' prerequisites: - creation-of-agency - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: independent-contractor-vs-employee - name: "Independent Contractor vs Employee" + name: Independent Contractor vs Employee difficulty: 3 estimatedMinutes: 20 - tags: [s02-agency, employment-status] - sourceRef: "DOS Syllabus Subject 2: Law of Agency" + tags: + - s02-agency + - employment-status + sourceRef: 'DOS Syllabus Subject 2: Law of Agency' prerequisites: - licensing-categories - knowledgePoints: [] # KPs to be authored - - # ───────────────────────────────────────────────────────────────────────────── - # Subject 3: Legal Issues (10 hr) - # ───────────────────────────────────────────────────────────────────────────── - + knowledgePoints: [] - id: fee-simple-estates - name: "Fee Simple Estates" + name: Fee Simple Estates difficulty: 3 estimatedMinutes: 25 - tags: [s03-legal, estates, fee-simple] - sourceRef: "DOS Syllabus Subject 3: Legal Issues" - knowledgePoints: [] # KPs to be authored - + tags: + - s03-legal + - estates + - fee-simple + sourceRef: 'DOS Syllabus Subject 3: Legal Issues' + knowledgePoints: [] - id: life-estates - name: "Life Estates" + name: Life Estates difficulty: 4 estimatedMinutes: 25 - tags: [s03-legal, estates, life-estate] - sourceRef: "DOS Syllabus Subject 3: Legal Issues" + tags: + - s03-legal + - estates + - life-estate + sourceRef: 'DOS Syllabus Subject 3: Legal Issues' prerequisites: - fee-simple-estates - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: forms-of-co-ownership - name: "Forms of Co-Ownership" + name: Forms of Co-Ownership difficulty: 5 estimatedMinutes: 40 - tags: [s03-legal, estates, co-ownership] - sourceRef: "DOS Syllabus Subject 3: Legal Issues" + tags: + - s03-legal + - estates + - co-ownership + sourceRef: 'DOS Syllabus Subject 3: Legal Issues' prerequisites: - fee-simple-estates knowledgePoints: - id: tenancy-in-common - instruction: "content/ny-re/tenancy-in-common.md" - workedExample: "content/ny-re/tenancy-in-common-ex.md" + instruction: content/ny-re/tenancy-in-common.md + workedExample: content/ny-re/tenancy-in-common-ex.md problems: - id: tic-p1 type: multiple_choice - question: "In a tenancy in common, what happens to a deceased owner's interest?" + question: In a tenancy in common, what happens to a deceased owner's interest? options: - - "It automatically passes to the surviving co-owners by right of survivorship" - - "It passes to the deceased owner's heirs or devisees through probate" - - "It reverts to the state through escheat" - - "It is divided equally among all remaining tenants" + - It automatically passes to the surviving co-owners by right of survivorship + - It passes to the deceased owner's heirs or devisees through probate + - It reverts to the state through escheat + - It is divided equally among all remaining tenants correct: 1 - explanation: "Tenancy in common does NOT include a right of survivorship. A deceased tenant's interest passes through their estate (to heirs via intestacy or devisees via will)." + explanation: Tenancy in common does NOT include a right of survivorship. A deceased tenant's interest passes through their estate (to heirs via intestacy or devisees via will). - id: tic-p2 type: multiple_choice - question: "Which statement is TRUE about tenancy in common?" + question: Which statement is TRUE about tenancy in common? options: - - "All owners must hold equal shares" - - "Owners may hold unequal shares" - - "Owners cannot sell their individual interest" - - "It requires the four unities of time, title, interest, and possession" + - All owners must hold equal shares + - Owners may hold unequal shares + - Owners cannot sell their individual interest + - It requires the four unities of time, title, interest, and possession correct: 1 - explanation: "Tenants in common may hold unequal shares (e.g., one holds 60%, another 40%). The only shared unity is possession—each tenant has the right to use the entire property." + explanation: Tenants in common may hold unequal shares (e.g., one holds 60%, another 40%). The only shared unity is possession—each tenant has the right to use the entire property. - id: joint-tenancy - instruction: "content/ny-re/joint-tenancy.md" - workedExample: "content/ny-re/joint-tenancy-ex.md" + instruction: content/ny-re/joint-tenancy.md + workedExample: content/ny-re/joint-tenancy-ex.md problems: - id: jt-p1 type: multiple_choice - question: "What are the four unities required to create a joint tenancy?" + question: What are the four unities required to create a joint tenancy? options: - - "Time, Title, Interest, and Possession" - - "Consent, Consideration, Capacity, and Legality" - - "Offer, Acceptance, Consideration, and Mutual Assent" - - "Ownership, Lien, Deed, and Conveyance" + - Time, Title, Interest, and Possession + - Consent, Consideration, Capacity, and Legality + - Offer, Acceptance, Consideration, and Mutual Assent + - Ownership, Lien, Deed, and Conveyance correct: 0 - explanation: "Joint tenancy requires the four unities: Time (acquired at the same time), Title (same deed), Interest (equal shares), and Possession (equal right to possess the whole). If any unity is broken, the joint tenancy converts to a tenancy in common." + explanation: 'Joint tenancy requires the four unities: Time (acquired at the same time), Title (same deed), Interest (equal shares), and Possession (equal right to possess the whole). If any unity is broken, the joint tenancy converts to a tenancy in common.' - id: jt-p2 type: fill_blank - question: "The key feature that distinguishes joint tenancy from tenancy in common is the right of ___." - correct: "survivorship" - explanation: "The right of survivorship means that when one joint tenant dies, their interest automatically passes to the surviving joint tenant(s) outside of probate." + question: The key feature that distinguishes joint tenancy from tenancy in common is the right of ___. + correct: survivorship + explanation: The right of survivorship means that when one joint tenant dies, their interest automatically passes to the surviving joint tenant(s) outside of probate. + keyPrerequisite: forms-of-co-ownership - id: tenancy-by-entirety - instruction: "content/ny-re/tenancy-by-entirety.md" + instruction: content/ny-re/tenancy-by-entirety.md problems: - id: tbe-p1 type: multiple_choice - question: "Tenancy by the entirety is available only to:" + question: 'Tenancy by the entirety is available only to:' options: - - "Business partners" - - "Married couples" - - "Blood relatives" - - "Any two individuals" + - Business partners + - Married couples + - Blood relatives + - Any two individuals correct: 1 - explanation: "Tenancy by the entirety is a special form of joint ownership available only to married couples (and in NY, also to domestic partners in some contexts). Neither spouse can convey or encumber their interest without the other's consent." + explanation: Tenancy by the entirety is a special form of joint ownership available only to married couples (and in NY, also to domestic partners in some contexts). Neither spouse can convey or encumber their interest without the other's consent. + keyPrerequisite: forms-of-co-ownership - id: community-property-vs-ny - instruction: "content/ny-re/community-property-vs-ny.md" + instruction: content/ny-re/community-property-vs-ny.md problems: - id: cp-p1 type: multiple_choice - question: "Does New York follow community property rules?" + question: Does New York follow community property rules? options: - - "Yes, all marital property is community property" - - "No, New York is an equitable distribution state" - - "Yes, but only for real property" - - "No, New York follows common-law dower/curtesy" + - Yes, all marital property is community property + - No, New York is an equitable distribution state + - Yes, but only for real property + - No, New York follows common-law dower/curtesy correct: 1 - explanation: "New York is an equitable distribution state, not a community property state. Upon divorce, marital property is divided equitably (fairly, not necessarily equally) by the court." - + explanation: New York is an equitable distribution state, not a community property state. Upon divorce, marital property is divided equitably (fairly, not necessarily equally) by the court. + keyPrerequisite: forms-of-co-ownership - id: general-liens - name: "General Liens" + name: General Liens difficulty: 4 estimatedMinutes: 20 - tags: [s03-legal, liens, general-liens] - sourceRef: "DOS Syllabus Subject 3: Legal Issues" - knowledgePoints: [] # KPs to be authored - + tags: + - s03-legal + - liens + - general-liens + sourceRef: 'DOS Syllabus Subject 3: Legal Issues' + knowledgePoints: [] - id: specific-liens - name: "Specific Liens" + name: Specific Liens difficulty: 4 estimatedMinutes: 20 - tags: [s03-legal, liens, specific-liens] - sourceRef: "DOS Syllabus Subject 3: Legal Issues" - knowledgePoints: [] # KPs to be authored - + tags: + - s03-legal + - liens + - specific-liens + sourceRef: 'DOS Syllabus Subject 3: Legal Issues' + knowledgePoints: [] - id: mechanics-liens - name: "Mechanic's Liens" + name: Mechanic's Liens difficulty: 5 estimatedMinutes: 25 - tags: [s03-legal, liens, mechanics-lien] - sourceRef: "DOS Syllabus Subject 3: Legal Issues" + tags: + - s03-legal + - liens + - mechanics-lien + sourceRef: 'DOS Syllabus Subject 3: Legal Issues' prerequisites: - specific-liens - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: tax-liens - name: "Tax Liens" + name: Tax Liens difficulty: 4 estimatedMinutes: 20 - tags: [s03-legal, liens, tax-liens] - sourceRef: "DOS Syllabus Subject 3: Legal Issues" + tags: + - s03-legal + - liens + - tax-liens + sourceRef: 'DOS Syllabus Subject 3: Legal Issues' prerequisites: - specific-liens - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: easement-appurtenant - name: "Easement Appurtenant" + name: Easement Appurtenant difficulty: 5 estimatedMinutes: 25 - tags: [s03-legal, easements] - sourceRef: "DOS Syllabus Subject 3: Legal Issues" + tags: + - s03-legal + - easements + sourceRef: 'DOS Syllabus Subject 3: Legal Issues' prerequisites: - fee-simple-estates - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: easement-in-gross - name: "Easement in Gross" + name: Easement in Gross difficulty: 4 estimatedMinutes: 20 - tags: [s03-legal, easements] - sourceRef: "DOS Syllabus Subject 3: Legal Issues" + tags: + - s03-legal + - easements + sourceRef: 'DOS Syllabus Subject 3: Legal Issues' prerequisites: - fee-simple-estates - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: easement-by-prescription - name: "Easement by Prescription" + name: Easement by Prescription difficulty: 5 estimatedMinutes: 20 - tags: [s03-legal, easements, adverse-possession] - sourceRef: "DOS Syllabus Subject 3: Legal Issues" + tags: + - s03-legal + - easements + - adverse-possession + sourceRef: 'DOS Syllabus Subject 3: Legal Issues' prerequisites: - easement-appurtenant - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: deed-types - name: "Types of Deeds" + name: Types of Deeds difficulty: 4 estimatedMinutes: 30 - tags: [s03-legal, deeds] - sourceRef: "DOS Syllabus Subject 3: Legal Issues" + tags: + - s03-legal + - deeds + sourceRef: 'DOS Syllabus Subject 3: Legal Issues' prerequisites: - fee-simple-estates - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: deed-essential-elements - name: "Essential Elements of a Valid Deed" + name: Essential Elements of a Valid Deed difficulty: 4 estimatedMinutes: 25 - tags: [s03-legal, deeds] - sourceRef: "DOS Syllabus Subject 3: Legal Issues" + tags: + - s03-legal + - deeds + sourceRef: 'DOS Syllabus Subject 3: Legal Issues' prerequisites: - deed-types - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: legal-descriptions - name: "Legal Descriptions of Property" + name: Legal Descriptions of Property difficulty: 5 estimatedMinutes: 30 - tags: [s03-legal, deeds, legal-descriptions] - sourceRef: "DOS Syllabus Subject 3: Legal Issues" + tags: + - s03-legal + - deeds + - legal-descriptions + sourceRef: 'DOS Syllabus Subject 3: Legal Issues' prerequisites: - deed-essential-elements - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: title-closing-costs - name: "Title Closing and Costs" + name: Title Closing and Costs difficulty: 5 estimatedMinutes: 30 - tags: [s03-legal, closing] - sourceRef: "DOS Syllabus Subject 3: Legal Issues" + tags: + - s03-legal + - closing + sourceRef: 'DOS Syllabus Subject 3: Legal Issues' prerequisites: - deed-types - general-liens - specific-liens - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: respa - name: "RESPA (Real Estate Settlement Procedures Act)" + name: RESPA (Real Estate Settlement Procedures Act) difficulty: 4 estimatedMinutes: 25 - tags: [s03-legal, closing, federal-law] - sourceRef: "DOS Syllabus Subject 3: Legal Issues" + tags: + - s03-legal + - closing + - federal-law + sourceRef: 'DOS Syllabus Subject 3: Legal Issues' prerequisites: - title-closing-costs - knowledgePoints: [] # KPs to be authored - - # ───────────────────────────────────────────────────────────────────────────── - # Subject 4: Contracts of Sale & Leases (3 hr) - # ───────────────────────────────────────────────────────────────────────────── - + knowledgePoints: [] - id: lease-types - name: "Types of Leases" + name: Types of Leases difficulty: 3 estimatedMinutes: 20 - tags: [s04-contracts, leases] - sourceRef: "DOS Syllabus Subject 4: Contracts of Sale & Leases" + tags: + - s04-contracts + - leases + sourceRef: 'DOS Syllabus Subject 4: Contracts of Sale & Leases' prerequisites: - fee-simple-estates - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: etpa-rent-stabilization - name: "ETPA and Rent Stabilization" + name: ETPA and Rent Stabilization difficulty: 5 estimatedMinutes: 25 - tags: [s04-contracts, leases, rent-stabilization] - sourceRef: "DOS Syllabus Subject 4: Contracts of Sale & Leases" + tags: + - s04-contracts + - leases + - rent-stabilization + sourceRef: 'DOS Syllabus Subject 4: Contracts of Sale & Leases' prerequisites: - lease-types - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: contract-essentials - name: "Essential Elements of a Valid Contract" + name: Essential Elements of a Valid Contract difficulty: 4 estimatedMinutes: 25 - tags: [s04-contracts, contract-law] - sourceRef: "DOS Syllabus Subject 4: Contracts of Sale & Leases" + tags: + - s04-contracts + - contract-law + sourceRef: 'DOS Syllabus Subject 4: Contracts of Sale & Leases' prerequisites: - fiduciary-duties - fee-simple-estates encompassing: - concept: fiduciary-duties weight: 0.3 - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: statute-of-frauds - name: "Statute of Frauds" + name: Statute of Frauds difficulty: 4 estimatedMinutes: 20 - tags: [s04-contracts, contract-law] - sourceRef: "DOS Syllabus Subject 4: Contracts of Sale & Leases" + tags: + - s04-contracts + - contract-law + sourceRef: 'DOS Syllabus Subject 4: Contracts of Sale & Leases' prerequisites: - contract-essentials - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: contract-preparation - name: "Contract Preparation and Provisions" + name: Contract Preparation and Provisions difficulty: 5 estimatedMinutes: 25 - tags: [s04-contracts, contract-law] - sourceRef: "DOS Syllabus Subject 4: Contracts of Sale & Leases" + tags: + - s04-contracts + - contract-law + sourceRef: 'DOS Syllabus Subject 4: Contracts of Sale & Leases' prerequisites: - contract-essentials - rpl-443-disclosure encompassing: - concept: rpl-443-disclosure weight: 0.4 - knowledgePoints: [] # KPs to be authored - - # ───────────────────────────────────────────────────────────────────────────── - # Subject 5: Real Estate Finance (5 hr) - # ───────────────────────────────────────────────────────────────────────────── - + knowledgePoints: [] - id: mortgage-basics - name: "Mortgage Fundamentals" + name: Mortgage Fundamentals difficulty: 3 estimatedMinutes: 25 - tags: [s05-finance, mortgages] - sourceRef: "DOS Syllabus Subject 5: Real Estate Finance" + tags: + - s05-finance + - mortgages + sourceRef: 'DOS Syllabus Subject 5: Real Estate Finance' prerequisites: - specific-liens - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: fixed-rate-mortgages - name: "Fixed-Rate Mortgages" + name: Fixed-Rate Mortgages difficulty: 3 estimatedMinutes: 20 - tags: [s05-finance, mortgages, fixed-rate] - sourceRef: "DOS Syllabus Subject 5: Real Estate Finance" + tags: + - s05-finance + - mortgages + - fixed-rate + sourceRef: 'DOS Syllabus Subject 5: Real Estate Finance' prerequisites: - mortgage-basics - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: adjustable-rate-mortgages - name: "Adjustable-Rate Mortgages (ARMs)" + name: Adjustable-Rate Mortgages (ARMs) difficulty: 5 estimatedMinutes: 25 - tags: [s05-finance, mortgages, arm] - sourceRef: "DOS Syllabus Subject 5: Real Estate Finance" + tags: + - s05-finance + - mortgages + - arm + sourceRef: 'DOS Syllabus Subject 5: Real Estate Finance' prerequisites: - mortgage-basics - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: balloon-mortgages - name: "Balloon Mortgages" + name: Balloon Mortgages difficulty: 4 estimatedMinutes: 15 - tags: [s05-finance, mortgages, balloon] - sourceRef: "DOS Syllabus Subject 5: Real Estate Finance" + tags: + - s05-finance + - mortgages + - balloon + sourceRef: 'DOS Syllabus Subject 5: Real Estate Finance' prerequisites: - mortgage-basics - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: fha-loans - name: "FHA Loans" + name: FHA Loans difficulty: 4 estimatedMinutes: 20 - tags: [s05-finance, government-loans, fha] - sourceRef: "DOS Syllabus Subject 5: Real Estate Finance" + tags: + - s05-finance + - government-loans + - fha + sourceRef: 'DOS Syllabus Subject 5: Real Estate Finance' prerequisites: - mortgage-basics - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: va-loans - name: "VA Loans" + name: VA Loans difficulty: 4 estimatedMinutes: 20 - tags: [s05-finance, government-loans, va] - sourceRef: "DOS Syllabus Subject 5: Real Estate Finance" + tags: + - s05-finance + - government-loans + - va + sourceRef: 'DOS Syllabus Subject 5: Real Estate Finance' prerequisites: - mortgage-basics - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: sonyma - name: "SONYMA Programs" + name: SONYMA Programs difficulty: 4 estimatedMinutes: 15 - tags: [s05-finance, government-loans, sonyma] - sourceRef: "DOS Syllabus Subject 5: Real Estate Finance" + tags: + - s05-finance + - government-loans + - sonyma + sourceRef: 'DOS Syllabus Subject 5: Real Estate Finance' prerequisites: - mortgage-basics - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: secondary-mortgage-market - name: "Secondary Mortgage Market" + name: Secondary Mortgage Market difficulty: 5 estimatedMinutes: 25 - tags: [s05-finance, secondary-market] - sourceRef: "DOS Syllabus Subject 5: Real Estate Finance" + tags: + - s05-finance + - secondary-market + sourceRef: 'DOS Syllabus Subject 5: Real Estate Finance' prerequisites: - mortgage-basics - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: truth-in-lending-reg-z - name: "Truth in Lending / Regulation Z" + name: Truth in Lending / Regulation Z difficulty: 5 estimatedMinutes: 25 - tags: [s05-finance, federal-law, tila] - sourceRef: "DOS Syllabus Subject 5: Real Estate Finance" + tags: + - s05-finance + - federal-law + - tila + sourceRef: 'DOS Syllabus Subject 5: Real Estate Finance' prerequisites: - mortgage-basics - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: predatory-lending - name: "Predatory Lending Practices" + name: Predatory Lending Practices difficulty: 4 estimatedMinutes: 20 - tags: [s05-finance, predatory-lending] - sourceRef: "DOS Syllabus Subject 5: Real Estate Finance" + tags: + - s05-finance + - predatory-lending + sourceRef: 'DOS Syllabus Subject 5: Real Estate Finance' prerequisites: - truth-in-lending-reg-z - knowledgePoints: [] # KPs to be authored - - # ───────────────────────────────────────────────────────────────────────────── - # Subject 6: Land Use Regulations (3 hr) - # ───────────────────────────────────────────────────────────────────────────── - + knowledgePoints: [] - id: zoning-fundamentals - name: "Zoning Fundamentals" + name: Zoning Fundamentals difficulty: 3 estimatedMinutes: 25 - tags: [s06-land-use, zoning] - sourceRef: "DOS Syllabus Subject 6: Land Use Regulations" - knowledgePoints: [] # KPs to be authored - + tags: + - s06-land-use + - zoning + sourceRef: 'DOS Syllabus Subject 6: Land Use Regulations' + knowledgePoints: [] - id: planning-board - name: "Planning Board Role & Functions" + name: Planning Board Role & Functions difficulty: 3 estimatedMinutes: 20 - tags: [s06-land-use, planning] - sourceRef: "DOS Syllabus Subject 6: Land Use Regulations" + tags: + - s06-land-use + - planning + sourceRef: 'DOS Syllabus Subject 6: Land Use Regulations' prerequisites: - zoning-fundamentals - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: variances-use-and-area - name: "Use Variances vs Area Variances" + name: Use Variances vs Area Variances difficulty: 5 estimatedMinutes: 25 - tags: [s06-land-use, zoning, variances] - sourceRef: "DOS Syllabus Subject 6: Land Use Regulations" + tags: + - s06-land-use + - zoning + - variances + sourceRef: 'DOS Syllabus Subject 6: Land Use Regulations' prerequisites: - zoning-fundamentals - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: planned-unit-development - name: "Planned Unit Development (PUD)" + name: Planned Unit Development (PUD) difficulty: 4 estimatedMinutes: 15 - tags: [s06-land-use, pud] - sourceRef: "DOS Syllabus Subject 6: Land Use Regulations" + tags: + - s06-land-use + - pud + sourceRef: 'DOS Syllabus Subject 6: Land Use Regulations' prerequisites: - zoning-fundamentals - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: seqr - name: "SEQR (State Environmental Quality Review)" + name: SEQR (State Environmental Quality Review) difficulty: 5 estimatedMinutes: 20 - tags: [s06-land-use, environmental, seqr] - sourceRef: "DOS Syllabus Subject 6: Land Use Regulations" + tags: + - s06-land-use + - environmental + - seqr + sourceRef: 'DOS Syllabus Subject 6: Land Use Regulations' prerequisites: - planning-board - knowledgePoints: [] # KPs to be authored - - # ───────────────────────────────────────────────────────────────────────────── - # Subject 7: Construction & Environmental (5 hr) - # ───────────────────────────────────────────────────────────────────────────── - + knowledgePoints: [] - id: building-construction-basics - name: "Building Construction Basics" + name: Building Construction Basics difficulty: 3 estimatedMinutes: 25 - tags: [s07-construction, building-systems] - sourceRef: "DOS Syllabus Subject 7: Construction & Environmental" - knowledgePoints: [] # KPs to be authored - + tags: + - s07-construction + - building-systems + sourceRef: 'DOS Syllabus Subject 7: Construction & Environmental' + knowledgePoints: [] - id: hvac-systems - name: "HVAC Systems" + name: HVAC Systems difficulty: 3 estimatedMinutes: 20 - tags: [s07-construction, building-systems, hvac] - sourceRef: "DOS Syllabus Subject 7: Construction & Environmental" + tags: + - s07-construction + - building-systems + - hvac + sourceRef: 'DOS Syllabus Subject 7: Construction & Environmental' prerequisites: - building-construction-basics - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: electrical-systems - name: "Electrical Systems" + name: Electrical Systems difficulty: 3 estimatedMinutes: 20 - tags: [s07-construction, building-systems, electrical] - sourceRef: "DOS Syllabus Subject 7: Construction & Environmental" + tags: + - s07-construction + - building-systems + - electrical + sourceRef: 'DOS Syllabus Subject 7: Construction & Environmental' prerequisites: - building-construction-basics - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: plumbing-systems - name: "Plumbing Systems" + name: Plumbing Systems difficulty: 3 estimatedMinutes: 20 - tags: [s07-construction, building-systems, plumbing] - sourceRef: "DOS Syllabus Subject 7: Construction & Environmental" + tags: + - s07-construction + - building-systems + - plumbing + sourceRef: 'DOS Syllabus Subject 7: Construction & Environmental' prerequisites: - building-construction-basics - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: asbestos-hazards - name: "Asbestos Hazards" + name: Asbestos Hazards difficulty: 4 estimatedMinutes: 20 - tags: [s07-construction, environmental-hazards, asbestos] - sourceRef: "DOS Syllabus Subject 7: Construction & Environmental" - knowledgePoints: [] # KPs to be authored - + tags: + - s07-construction + - environmental-hazards + - asbestos + sourceRef: 'DOS Syllabus Subject 7: Construction & Environmental' + knowledgePoints: [] - id: lead-based-paint - name: "Lead-Based Paint Hazards" + name: Lead-Based Paint Hazards difficulty: 4 estimatedMinutes: 20 - tags: [s07-construction, environmental-hazards, lead] - sourceRef: "DOS Syllabus Subject 7: Construction & Environmental" - knowledgePoints: [] # KPs to be authored - + tags: + - s07-construction + - environmental-hazards + - lead + sourceRef: 'DOS Syllabus Subject 7: Construction & Environmental' + knowledgePoints: [] - id: radon - name: "Radon Gas" + name: Radon Gas difficulty: 3 estimatedMinutes: 15 - tags: [s07-construction, environmental-hazards, radon] - sourceRef: "DOS Syllabus Subject 7: Construction & Environmental" - knowledgePoints: [] # KPs to be authored - + tags: + - s07-construction + - environmental-hazards + - radon + sourceRef: 'DOS Syllabus Subject 7: Construction & Environmental' + knowledgePoints: [] - id: mold-hazards - name: "Mold Hazards" + name: Mold Hazards difficulty: 3 estimatedMinutes: 15 - tags: [s07-construction, environmental-hazards, mold] - sourceRef: "DOS Syllabus Subject 7: Construction & Environmental" - knowledgePoints: [] # KPs to be authored - + tags: + - s07-construction + - environmental-hazards + - mold + sourceRef: 'DOS Syllabus Subject 7: Construction & Environmental' + knowledgePoints: [] - id: pcbs-and-usts - name: "PCBs and Underground Storage Tanks" + name: PCBs and Underground Storage Tanks difficulty: 4 estimatedMinutes: 20 - tags: [s07-construction, environmental-hazards, pcbs, usts] - sourceRef: "DOS Syllabus Subject 7: Construction & Environmental" - knowledgePoints: [] # KPs to be authored - - # ───────────────────────────────────────────────────────────────────────────── - # Subject 8: Valuation & Pricing (3 hr) - # ───────────────────────────────────────────────────────────────────────────── - + tags: + - s07-construction + - environmental-hazards + - pcbs + - usts + sourceRef: 'DOS Syllabus Subject 7: Construction & Environmental' + knowledgePoints: [] - id: market-value-definition - name: "Market Value Definition" + name: Market Value Definition difficulty: 3 estimatedMinutes: 20 - tags: [s08-valuation, market-value] - sourceRef: "DOS Syllabus Subject 8: Valuation & Pricing" - knowledgePoints: [] # KPs to be authored - + tags: + - s08-valuation + - market-value + sourceRef: 'DOS Syllabus Subject 8: Valuation & Pricing' + knowledgePoints: [] - id: sales-comparison-approach - name: "Sales Comparison Approach" + name: Sales Comparison Approach difficulty: 5 estimatedMinutes: 30 - tags: [s08-valuation, appraisal, sales-comparison] - sourceRef: "DOS Syllabus Subject 8: Valuation & Pricing" + tags: + - s08-valuation + - appraisal + - sales-comparison + sourceRef: 'DOS Syllabus Subject 8: Valuation & Pricing' prerequisites: - market-value-definition - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: cost-approach - name: "Cost Approach to Value" + name: Cost Approach to Value difficulty: 5 estimatedMinutes: 25 - tags: [s08-valuation, appraisal, cost-approach] - sourceRef: "DOS Syllabus Subject 8: Valuation & Pricing" + tags: + - s08-valuation + - appraisal + - cost-approach + sourceRef: 'DOS Syllabus Subject 8: Valuation & Pricing' prerequisites: - market-value-definition - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: income-approach - name: "Income Approach to Value" + name: Income Approach to Value difficulty: 6 estimatedMinutes: 30 - tags: [s08-valuation, appraisal, income-approach] - sourceRef: "DOS Syllabus Subject 8: Valuation & Pricing" + tags: + - s08-valuation + - appraisal + - income-approach + sourceRef: 'DOS Syllabus Subject 8: Valuation & Pricing' prerequisites: - market-value-definition - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: comparative-market-analysis - name: "Comparative Market Analysis (CMA)" + name: Comparative Market Analysis (CMA) difficulty: 5 estimatedMinutes: 25 - tags: [s08-valuation, cma] - sourceRef: "DOS Syllabus Subject 8: Valuation & Pricing" + tags: + - s08-valuation + - cma + sourceRef: 'DOS Syllabus Subject 8: Valuation & Pricing' prerequisites: - sales-comparison-approach - knowledgePoints: [] # KPs to be authored - - # ───────────────────────────────────────────────────────────────────────────── - # Subject 9: Human Rights & Fair Housing (6 hr) - # ───────────────────────────────────────────────────────────────────────────── - + knowledgePoints: [] - id: civil-rights-act-1866 - name: "Civil Rights Act of 1866" + name: Civil Rights Act of 1866 difficulty: 3 estimatedMinutes: 15 - tags: [s09-fair-housing, federal-law, civil-rights] - sourceRef: "DOS Syllabus Subject 9: Human Rights & Fair Housing" - knowledgePoints: [] # KPs to be authored - + tags: + - s09-fair-housing + - federal-law + - civil-rights + sourceRef: 'DOS Syllabus Subject 9: Human Rights & Fair Housing' + knowledgePoints: [] - id: fair-housing-act-1968 - name: "Fair Housing Act of 1968" + name: Fair Housing Act of 1968 difficulty: 4 estimatedMinutes: 30 - tags: [s09-fair-housing, federal-law, fair-housing] - sourceRef: "DOS Syllabus Subject 9: Human Rights & Fair Housing" + tags: + - s09-fair-housing + - federal-law + - fair-housing + sourceRef: 'DOS Syllabus Subject 9: Human Rights & Fair Housing' prerequisites: - civil-rights-act-1866 - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: fha-amendment-1988 - name: "Fair Housing Amendment Act of 1988" + name: Fair Housing Amendment Act of 1988 difficulty: 4 estimatedMinutes: 25 - tags: [s09-fair-housing, federal-law, fha-amendment] - sourceRef: "DOS Syllabus Subject 9: Human Rights & Fair Housing" + tags: + - s09-fair-housing + - federal-law + - fha-amendment + sourceRef: 'DOS Syllabus Subject 9: Human Rights & Fair Housing' prerequisites: - fair-housing-act-1968 - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: ny-human-rights-law - name: "New York Human Rights Law" + name: New York Human Rights Law difficulty: 5 estimatedMinutes: 30 - tags: [s09-fair-housing, ny-law, human-rights] - sourceRef: "DOS Syllabus Subject 9: Human Rights & Fair Housing" + tags: + - s09-fair-housing + - ny-law + - human-rights + sourceRef: 'DOS Syllabus Subject 9: Human Rights & Fair Housing' prerequisites: - fair-housing-act-1968 - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: protected-classes - name: "Federal and State Protected Classes" + name: Federal and State Protected Classes difficulty: 4 estimatedMinutes: 25 - tags: [s09-fair-housing, protected-classes] - sourceRef: "DOS Syllabus Subject 9: Human Rights & Fair Housing" + tags: + - s09-fair-housing + - protected-classes + sourceRef: 'DOS Syllabus Subject 9: Human Rights & Fair Housing' prerequisites: - fair-housing-act-1968 - ny-human-rights-law - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: steering - name: "Steering" + name: Steering difficulty: 4 estimatedMinutes: 20 - tags: [s09-fair-housing, discrimination, steering] - sourceRef: "DOS Syllabus Subject 9: Human Rights & Fair Housing" + tags: + - s09-fair-housing + - discrimination + - steering + sourceRef: 'DOS Syllabus Subject 9: Human Rights & Fair Housing' prerequisites: - protected-classes - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: blockbusting - name: "Blockbusting" + name: Blockbusting difficulty: 4 estimatedMinutes: 20 - tags: [s09-fair-housing, discrimination, blockbusting] - sourceRef: "DOS Syllabus Subject 9: Human Rights & Fair Housing" + tags: + - s09-fair-housing + - discrimination + - blockbusting + sourceRef: 'DOS Syllabus Subject 9: Human Rights & Fair Housing' prerequisites: - protected-classes - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: redlining - name: "Redlining" + name: Redlining difficulty: 4 estimatedMinutes: 20 - tags: [s09-fair-housing, discrimination, redlining] - sourceRef: "DOS Syllabus Subject 9: Human Rights & Fair Housing" + tags: + - s09-fair-housing + - discrimination + - redlining + sourceRef: 'DOS Syllabus Subject 9: Human Rights & Fair Housing' prerequisites: - protected-classes - knowledgePoints: [] # KPs to be authored - - # ───────────────────────────────────────────────────────────────────────────── - # Subject 10: Real Estate Math (1 hr) - # ───────────────────────────────────────────────────────────────────────────── - + knowledgePoints: [] - id: commission-calculations - name: "Commission Calculations" + name: Commission Calculations difficulty: 4 estimatedMinutes: 15 - tags: [s10-math, commissions] - sourceRef: "DOS Syllabus Subject 10: Real Estate Math" - knowledgePoints: [] # KPs to be authored - + tags: + - s10-math + - commissions + sourceRef: 'DOS Syllabus Subject 10: Real Estate Math' + knowledgePoints: [] - id: area-calculations - name: "Area and Volume Calculations" + name: Area and Volume Calculations difficulty: 4 estimatedMinutes: 15 - tags: [s10-math, area] - sourceRef: "DOS Syllabus Subject 10: Real Estate Math" - knowledgePoints: [] # KPs to be authored - + tags: + - s10-math + - area + sourceRef: 'DOS Syllabus Subject 10: Real Estate Math' + knowledgePoints: [] - id: tax-calculations - name: "Tax Calculations" + name: Tax Calculations difficulty: 5 estimatedMinutes: 15 - tags: [s10-math, taxes] - sourceRef: "DOS Syllabus Subject 10: Real Estate Math" - knowledgePoints: [] # KPs to be authored - + tags: + - s10-math + - taxes + sourceRef: 'DOS Syllabus Subject 10: Real Estate Math' + knowledgePoints: [] - id: mortgage-qualifying-math - name: "Mortgage Qualifying Ratios" + name: Mortgage Qualifying Ratios difficulty: 6 estimatedMinutes: 15 - tags: [s10-math, mortgage-qualifying] - sourceRef: "DOS Syllabus Subject 10: Real Estate Math" + tags: + - s10-math + - mortgage-qualifying + sourceRef: 'DOS Syllabus Subject 10: Real Estate Math' prerequisites: - mortgage-basics - knowledgePoints: [] # KPs to be authored - - # ───────────────────────────────────────────────────────────────────────────── - # Subject 11: Municipal Agencies (2 hr) - # ───────────────────────────────────────────────────────────────────────────── - + knowledgePoints: [] - id: municipal-planning-board - name: "Municipal Planning Board" + name: Municipal Planning Board difficulty: 3 estimatedMinutes: 20 - tags: [s11-municipal, planning-board] - sourceRef: "DOS Syllabus Subject 11: Municipal Agencies" + tags: + - s11-municipal + - planning-board + sourceRef: 'DOS Syllabus Subject 11: Municipal Agencies' prerequisites: - zoning-fundamentals - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: zoning-board-of-appeals - name: "Zoning Board of Appeals" + name: Zoning Board of Appeals difficulty: 4 estimatedMinutes: 25 - tags: [s11-municipal, zba] - sourceRef: "DOS Syllabus Subject 11: Municipal Agencies" + tags: + - s11-municipal + - zba + sourceRef: 'DOS Syllabus Subject 11: Municipal Agencies' prerequisites: - variances-use-and-area - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: building-department - name: "Building Department" + name: Building Department difficulty: 3 estimatedMinutes: 20 - tags: [s11-municipal, building-dept] - sourceRef: "DOS Syllabus Subject 11: Municipal Agencies" + tags: + - s11-municipal + - building-dept + sourceRef: 'DOS Syllabus Subject 11: Municipal Agencies' prerequisites: - building-construction-basics - knowledgePoints: [] # KPs to be authored - - # ───────────────────────────────────────────────────────────────────────────── - # Subject 12: Property Insurance (1 hr) - # ───────────────────────────────────────────────────────────────────────────── - + knowledgePoints: [] - id: homeowner-policy-types - name: "Homeowner Policy Types (HO-1 through HO-8)" + name: Homeowner Policy Types (HO-1 through HO-8) difficulty: 4 estimatedMinutes: 25 - tags: [s12-insurance, policy-types] - sourceRef: "DOS Syllabus Subject 12: Property Insurance" - knowledgePoints: [] # KPs to be authored - + tags: + - s12-insurance + - policy-types + sourceRef: 'DOS Syllabus Subject 12: Property Insurance' + knowledgePoints: [] - id: actual-cash-value-vs-replacement - name: "Actual Cash Value vs Replacement Cost" + name: Actual Cash Value vs Replacement Cost difficulty: 4 estimatedMinutes: 20 - tags: [s12-insurance, valuation] - sourceRef: "DOS Syllabus Subject 12: Property Insurance" + tags: + - s12-insurance + - valuation + sourceRef: 'DOS Syllabus Subject 12: Property Insurance' prerequisites: - homeowner-policy-types - knowledgePoints: [] # KPs to be authored - - # ───────────────────────────────────────────────────────────────────────────── - # Subject 13: Licensee Safety (1 hr) - # ───────────────────────────────────────────────────────────────────────────── - + knowledgePoints: [] - id: personal-safety - name: "Personal Safety for Licensees" + name: Personal Safety for Licensees difficulty: 2 estimatedMinutes: 20 - tags: [s13-safety, personal-safety] - sourceRef: "DOS Syllabus Subject 13: Licensee Safety" - knowledgePoints: [] # KPs to be authored - + tags: + - s13-safety + - personal-safety + sourceRef: 'DOS Syllabus Subject 13: Licensee Safety' + knowledgePoints: [] - id: cyber-security-identity-theft - name: "Cyber Security and Identity Theft" + name: Cyber Security and Identity Theft difficulty: 3 estimatedMinutes: 20 - tags: [s13-safety, cyber-security] - sourceRef: "DOS Syllabus Subject 13: Licensee Safety" - knowledgePoints: [] # KPs to be authored - - # ───────────────────────────────────────────────────────────────────────────── - # Subject 14: Taxes & Assessments (3 hr) - # ───────────────────────────────────────────────────────────────────────────── - + tags: + - s13-safety + - cyber-security + sourceRef: 'DOS Syllabus Subject 13: Licensee Safety' + knowledgePoints: [] - id: tax-calculation-process - name: "Property Tax Calculation Process" + name: Property Tax Calculation Process difficulty: 5 estimatedMinutes: 25 - tags: [s14-taxes, tax-calculation] - sourceRef: "DOS Syllabus Subject 14: Taxes & Assessments" - knowledgePoints: [] # KPs to be authored - + tags: + - s14-taxes + - tax-calculation + sourceRef: 'DOS Syllabus Subject 14: Taxes & Assessments' + knowledgePoints: [] - id: assessment-ratio - name: "Assessment Ratio and Equalization Rate" + name: Assessment Ratio and Equalization Rate difficulty: 6 estimatedMinutes: 25 - tags: [s14-taxes, assessment] - sourceRef: "DOS Syllabus Subject 14: Taxes & Assessments" + tags: + - s14-taxes + - assessment + sourceRef: 'DOS Syllabus Subject 14: Taxes & Assessments' prerequisites: - tax-calculation-process - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: star-program - name: "STAR Program (School Tax Relief)" + name: STAR Program (School Tax Relief) difficulty: 4 estimatedMinutes: 20 - tags: [s14-taxes, star, exemptions] - sourceRef: "DOS Syllabus Subject 14: Taxes & Assessments" + tags: + - s14-taxes + - star + - exemptions + sourceRef: 'DOS Syllabus Subject 14: Taxes & Assessments' prerequisites: - tax-calculation-process - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: tax-liens-priority - name: "Tax Liens and Priority" + name: Tax Liens and Priority difficulty: 5 estimatedMinutes: 20 - tags: [s14-taxes, tax-liens] - sourceRef: "DOS Syllabus Subject 14: Taxes & Assessments" + tags: + - s14-taxes + - tax-liens + sourceRef: 'DOS Syllabus Subject 14: Taxes & Assessments' prerequisites: - tax-liens - tax-calculation-process - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: protesting-assessments - name: "Protesting Assessments (Grievance Process)" + name: Protesting Assessments (Grievance Process) difficulty: 4 estimatedMinutes: 20 - tags: [s14-taxes, grievance] - sourceRef: "DOS Syllabus Subject 14: Taxes & Assessments" + tags: + - s14-taxes + - grievance + sourceRef: 'DOS Syllabus Subject 14: Taxes & Assessments' prerequisites: - assessment-ratio - knowledgePoints: [] # KPs to be authored - - # ───────────────────────────────────────────────────────────────────────────── - # Subject 15: Condos & Cooperatives (4 hr) - # ───────────────────────────────────────────────────────────────────────────── - + knowledgePoints: [] - id: condo-ownership - name: "Condominium Ownership (Real Property)" + name: Condominium Ownership (Real Property) difficulty: 4 estimatedMinutes: 30 - tags: [s15-condos-coops, condo] - sourceRef: "DOS Syllabus Subject 15: Condos & Cooperatives" + tags: + - s15-condos-coops + - condo + sourceRef: 'DOS Syllabus Subject 15: Condos & Cooperatives' prerequisites: - fee-simple-estates - contract-essentials encompassing: - concept: fee-simple-estates weight: 0.4 - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: coop-ownership - name: "Cooperative Ownership (Shares + Proprietary Lease)" + name: Cooperative Ownership (Shares + Proprietary Lease) difficulty: 5 estimatedMinutes: 30 - tags: [s15-condos-coops, coop] - sourceRef: "DOS Syllabus Subject 15: Condos & Cooperatives" + tags: + - s15-condos-coops + - coop + sourceRef: 'DOS Syllabus Subject 15: Condos & Cooperatives' prerequisites: - fee-simple-estates - lease-types @@ -1073,64 +1145,67 @@ concepts: encompassing: - concept: lease-types weight: 0.4 - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: offering-plans - name: "Offering Plans (Attorney General Filing)" + name: Offering Plans (Attorney General Filing) difficulty: 5 estimatedMinutes: 25 - tags: [s15-condos-coops, offering-plan] - sourceRef: "DOS Syllabus Subject 15: Condos & Cooperatives" + tags: + - s15-condos-coops + - offering-plan + sourceRef: 'DOS Syllabus Subject 15: Condos & Cooperatives' prerequisites: - condo-ownership - coop-ownership - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: board-applications - name: "Board Applications and Approval Process" + name: Board Applications and Approval Process difficulty: 4 estimatedMinutes: 20 - tags: [s15-condos-coops, board-approval] - sourceRef: "DOS Syllabus Subject 15: Condos & Cooperatives" + tags: + - s15-condos-coops + - board-approval + sourceRef: 'DOS Syllabus Subject 15: Condos & Cooperatives' prerequisites: - coop-ownership - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: condops - name: "Condops (Condo-Coop Hybrids)" + name: Condops (Condo-Coop Hybrids) difficulty: 5 estimatedMinutes: 15 - tags: [s15-condos-coops, condop] - sourceRef: "DOS Syllabus Subject 15: Condos & Cooperatives" + tags: + - s15-condos-coops + - condop + sourceRef: 'DOS Syllabus Subject 15: Condos & Cooperatives' prerequisites: - condo-ownership - coop-ownership - knowledgePoints: [] # KPs to be authored - - # ───────────────────────────────────────────────────────────────────────────── - # Subject 16: Commercial & Investment Properties (10 hr) - # ───────────────────────────────────────────────────────────────────────────── - + knowledgePoints: [] - id: net-operating-income - name: "Net Operating Income (NOI)" + name: Net Operating Income (NOI) difficulty: 6 estimatedMinutes: 35 - tags: [s16-commercial, noi, investment-analysis] - sourceRef: "DOS Syllabus Subject 16: Commercial & Investment Properties" + tags: + - s16-commercial + - noi + - investment-analysis + sourceRef: 'DOS Syllabus Subject 16: Commercial & Investment Properties' prerequisites: - income-approach - mortgage-basics encompassing: - concept: income-approach weight: 0.5 - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: cap-rate-and-noi - name: "Cap Rate and NOI Calculations" + name: Cap Rate and NOI Calculations difficulty: 7 estimatedMinutes: 45 - tags: [s16-commercial, cap-rate, investment-analysis] - sourceRef: "DOS Syllabus Subject 16: Commercial & Investment Properties" + tags: + - s16-commercial + - cap-rate + - investment-analysis + sourceRef: 'DOS Syllabus Subject 16: Commercial & Investment Properties' prerequisites: - net-operating-income - income-approach @@ -1141,88 +1216,92 @@ concepts: weight: 0.5 knowledgePoints: - id: cap-rate-formula - instruction: "content/ny-re/cap-rate-formula.md" - workedExample: "content/ny-re/cap-rate-formula-ex.md" + instruction: content/ny-re/cap-rate-formula.md + workedExample: content/ny-re/cap-rate-formula-ex.md problems: - id: cr-p1 type: multiple_choice - question: "A property generates $120,000 in NOI and is valued at $1,500,000. What is the capitalization rate?" + question: A property generates $120,000 in NOI and is valued at $1,500,000. What is the capitalization rate? options: - - "6%" - - "8%" - - "10%" - - "12.5%" + - 6% + - 8% + - 10% + - 12.5% correct: 1 - explanation: "Cap Rate = NOI / Value = $120,000 / $1,500,000 = 0.08 = 8%. The cap rate represents the expected rate of return on an investment property." + explanation: Cap Rate = NOI / Value = $120,000 / $1,500,000 = 0.08 = 8%. The cap rate represents the expected rate of return on an investment property. - id: cr-p2 type: multiple_choice - question: "A property has an NOI of $85,000 and comparable properties are selling at a 7% cap rate. What is the estimated value?" + question: A property has an NOI of $85,000 and comparable properties are selling at a 7% cap rate. What is the estimated value? options: - - "$595,000" - - "$1,000,000" - - "$1,214,286" - - "$850,000" + - $595,000 + - $1,000,000 + - $1,214,286 + - $850,000 correct: 2 - explanation: "Value = NOI / Cap Rate = $85,000 / 0.07 = $1,214,286 (rounded). When you know the NOI and the market cap rate, you can derive value by dividing NOI by the cap rate." + explanation: Value = NOI / Cap Rate = $85,000 / 0.07 = $1,214,286 (rounded). When you know the NOI and the market cap rate, you can derive value by dividing NOI by the cap rate. - id: cr-p3 type: fill_blank - question: "The formula for capitalization rate is Cap Rate = ___ / Property Value." - correct: "NOI" - explanation: "Cap Rate = NOI (Net Operating Income) / Property Value. This can be rearranged: Value = NOI / Cap Rate, or NOI = Value x Cap Rate." + question: The formula for capitalization rate is Cap Rate = ___ / Property Value. + correct: NOI + explanation: 'Cap Rate = NOI (Net Operating Income) / Property Value. This can be rearranged: Value = NOI / Cap Rate, or NOI = Value x Cap Rate.' - id: cap-rate-relationships - instruction: "content/ny-re/cap-rate-relationships.md" + instruction: content/ny-re/cap-rate-relationships.md problems: - id: crr-p1 type: multiple_choice - question: "All else being equal, if the cap rate for an area decreases from 8% to 6%, what happens to property values?" + question: All else being equal, if the cap rate for an area decreases from 8% to 6%, what happens to property values? options: - - "Values decrease by 25%" - - "Values increase by 33%" - - "Values remain the same" - - "Values increase by 25%" + - Values decrease by 25% + - Values increase by 33% + - Values remain the same + - Values increase by 25% correct: 1 - explanation: "Lower cap rates mean higher values. At 8% cap, a $100K NOI property = $1,250,000. At 6%, the same NOI yields $100K/0.06 = $1,666,667—a 33% increase. Cap rate and value have an inverse relationship." + explanation: Lower cap rates mean higher values. At 8% cap, a $100K NOI property = $1,250,000. At 6%, the same NOI yields $100K/0.06 = $1,666,667—a 33% increase. Cap rate and value have an inverse relationship. - id: crr-p2 type: multiple_choice - question: "An investor wants at least a 9% return. A property generates $72,000 NOI. What is the MAXIMUM price the investor should pay?" + question: An investor wants at least a 9% return. A property generates $72,000 NOI. What is the MAXIMUM price the investor should pay? options: - - "$648,000" - - "$720,000" - - "$800,000" - - "$900,000" + - $648,000 + - $720,000 + - $800,000 + - $900,000 correct: 2 - explanation: "Maximum price = NOI / Minimum Cap Rate = $72,000 / 0.09 = $800,000. If the investor pays more, their actual return falls below their 9% target." + explanation: Maximum price = NOI / Minimum Cap Rate = $72,000 / 0.09 = $800,000. If the investor pays more, their actual return falls below their 9% target. + keyPrerequisite: cap-rate-and-noi - id: noi-calculation-detail - instruction: "content/ny-re/noi-calculation-detail.md" - workedExample: "content/ny-re/noi-calculation-detail-ex.md" + instruction: content/ny-re/noi-calculation-detail.md + workedExample: content/ny-re/noi-calculation-detail-ex.md problems: - id: noi-p1 type: multiple_choice - question: "Which of the following is subtracted when calculating NOI?" + question: Which of the following is subtracted when calculating NOI? options: - - "Mortgage payments (debt service)" - - "Operating expenses (taxes, insurance, maintenance)" - - "Income taxes" - - "Depreciation" + - Mortgage payments (debt service) + - Operating expenses (taxes, insurance, maintenance) + - Income taxes + - Depreciation correct: 1 - explanation: "NOI = Effective Gross Income - Operating Expenses. Operating expenses include property taxes, insurance, maintenance, management fees, and utilities. Mortgage payments (debt service), income taxes, and depreciation are NOT subtracted when calculating NOI." + explanation: NOI = Effective Gross Income - Operating Expenses. Operating expenses include property taxes, insurance, maintenance, management fees, and utilities. Mortgage payments (debt service), income taxes, and depreciation are NOT subtracted when calculating NOI. - id: noi-p2 type: multiple_choice - question: "A building has potential gross income of $200,000, a 5% vacancy rate, and $80,000 in operating expenses. What is the NOI?" + question: A building has potential gross income of $200,000, a 5% vacancy rate, and $80,000 in operating expenses. What is the NOI? options: - - "$110,000" - - "$120,000" - - "$100,000" - - "$190,000" + - $110,000 + - $120,000 + - $100,000 + - $190,000 correct: 0 - explanation: "Effective Gross Income = $200,000 - ($200,000 x 0.05) = $200,000 - $10,000 = $190,000. NOI = $190,000 - $80,000 = $110,000." - + explanation: Effective Gross Income = $200,000 - ($200,000 x 0.05) = $200,000 - $10,000 = $190,000. NOI = $190,000 - $80,000 = $110,000. + keyPrerequisite: cap-rate-and-noi - id: cash-flow-analysis - name: "Cash Flow Analysis" + name: Cash Flow Analysis difficulty: 7 estimatedMinutes: 35 - tags: [s16-commercial, cash-flow, investment-analysis] - sourceRef: "DOS Syllabus Subject 16: Commercial & Investment Properties" + tags: + - s16-commercial + - cash-flow + - investment-analysis + sourceRef: 'DOS Syllabus Subject 16: Commercial & Investment Properties' prerequisites: - cap-rate-and-noi - mortgage-basics @@ -1231,65 +1310,68 @@ concepts: weight: 0.5 - concept: mortgage-basics weight: 0.4 - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: commercial-lease-types - name: "Commercial Lease Types (Net, Gross, Percentage)" + name: Commercial Lease Types (Net, Gross, Percentage) difficulty: 5 estimatedMinutes: 35 - tags: [s16-commercial, leases] - sourceRef: "DOS Syllabus Subject 16: Commercial & Investment Properties" + tags: + - s16-commercial + - leases + sourceRef: 'DOS Syllabus Subject 16: Commercial & Investment Properties' prerequisites: - lease-types encompassing: - concept: lease-types weight: 0.5 - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: escalation-clauses - name: "Escalation Clauses" + name: Escalation Clauses difficulty: 5 estimatedMinutes: 25 - tags: [s16-commercial, leases, escalation] - sourceRef: "DOS Syllabus Subject 16: Commercial & Investment Properties" + tags: + - s16-commercial + - leases + - escalation + sourceRef: 'DOS Syllabus Subject 16: Commercial & Investment Properties' prerequisites: - commercial-lease-types - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: commercial-square-footage - name: "Square Footage Calculations (Usable vs Rentable)" + name: Square Footage Calculations (Usable vs Rentable) difficulty: 6 estimatedMinutes: 30 - tags: [s16-commercial, square-footage, math] - sourceRef: "DOS Syllabus Subject 16: Commercial & Investment Properties" + tags: + - s16-commercial + - square-footage + - math + sourceRef: 'DOS Syllabus Subject 16: Commercial & Investment Properties' prerequisites: - commercial-lease-types - area-calculations encompassing: - concept: area-calculations weight: 0.5 - knowledgePoints: [] # KPs to be authored - - # ───────────────────────────────────────────────────────────────────────────── - # Subject 17: Income Tax Issues (3 hr) - # ───────────────────────────────────────────────────────────────────────────── - + knowledgePoints: [] - id: capital-gains-exclusion - name: "Capital Gains Exclusion ($250K/$500K)" + name: Capital Gains Exclusion ($250K/$500K) difficulty: 5 estimatedMinutes: 25 - tags: [s17-income-tax, capital-gains] - sourceRef: "DOS Syllabus Subject 17: Income Tax Issues" + tags: + - s17-income-tax + - capital-gains + sourceRef: 'DOS Syllabus Subject 17: Income Tax Issues' prerequisites: - mortgage-basics - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: 1031-exchange - name: "1031 Like-Kind Exchange" + name: 1031 Like-Kind Exchange difficulty: 7 estimatedMinutes: 35 - tags: [s17-income-tax, 1031-exchange] - sourceRef: "DOS Syllabus Subject 17: Income Tax Issues" + tags: + - s17-income-tax + - 1031-exchange + sourceRef: 'DOS Syllabus Subject 17: Income Tax Issues' prerequisites: - capital-gains-exclusion - net-operating-income @@ -1298,38 +1380,44 @@ concepts: weight: 0.4 - concept: net-operating-income weight: 0.3 - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: 1031-exchange-timelines - name: "1031 Exchange Timelines (45-Day/180-Day Rules)" + name: 1031 Exchange Timelines (45-Day/180-Day Rules) difficulty: 6 estimatedMinutes: 25 - tags: [s17-income-tax, 1031-exchange, timelines] - sourceRef: "DOS Syllabus Subject 17: Income Tax Issues" + tags: + - s17-income-tax + - 1031-exchange + - timelines + sourceRef: 'DOS Syllabus Subject 17: Income Tax Issues' prerequisites: - 1031-exchange - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: depreciation-residential - name: "Depreciation — Residential (27.5 Years)" + name: Depreciation — Residential (27.5 Years) difficulty: 6 estimatedMinutes: 25 - tags: [s17-income-tax, depreciation, residential] - sourceRef: "DOS Syllabus Subject 17: Income Tax Issues" + tags: + - s17-income-tax + - depreciation + - residential + sourceRef: 'DOS Syllabus Subject 17: Income Tax Issues' prerequisites: - mortgage-basics - net-operating-income encompassing: - concept: mortgage-basics weight: 0.3 - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: depreciation-nonresidential - name: "Depreciation — Non-Residential (39 Years)" + name: Depreciation — Non-Residential (39 Years) difficulty: 6 estimatedMinutes: 20 - tags: [s17-income-tax, depreciation, commercial] - sourceRef: "DOS Syllabus Subject 17: Income Tax Issues" + tags: + - s17-income-tax + - depreciation + - commercial + sourceRef: 'DOS Syllabus Subject 17: Income Tax Issues' prerequisites: - depreciation-residential - commercial-lease-types @@ -1338,74 +1426,71 @@ concepts: weight: 0.6 - concept: commercial-lease-types weight: 0.3 - knowledgePoints: [] # KPs to be authored - - # ───────────────────────────────────────────────────────────────────────────── - # Subject 18: Mortgage Brokerage (1 hr) - # ───────────────────────────────────────────────────────────────────────────── - + knowledgePoints: [] - id: mortgage-broker-vs-banker - name: "Mortgage Broker vs Mortgage Banker" + name: Mortgage Broker vs Mortgage Banker difficulty: 3 estimatedMinutes: 20 - tags: [s18-mortgage-brokerage, broker-banker] - sourceRef: "DOS Syllabus Subject 18: Mortgage Brokerage" + tags: + - s18-mortgage-brokerage + - broker-banker + sourceRef: 'DOS Syllabus Subject 18: Mortgage Brokerage' prerequisites: - mortgage-basics - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: mortgage-broker-disclosure - name: "Mortgage Broker Disclosure Requirements" + name: Mortgage Broker Disclosure Requirements difficulty: 4 estimatedMinutes: 20 - tags: [s18-mortgage-brokerage, disclosure] - sourceRef: "DOS Syllabus Subject 18: Mortgage Brokerage" + tags: + - s18-mortgage-brokerage + - disclosure + sourceRef: 'DOS Syllabus Subject 18: Mortgage Brokerage' prerequisites: - mortgage-broker-vs-banker - truth-in-lending-reg-z - knowledgePoints: [] # KPs to be authored - - # ───────────────────────────────────────────────────────────────────────────── - # Subject 19: Property Management (2 hr) - # ───────────────────────────────────────────────────────────────────────────── - + knowledgePoints: [] - id: management-agreements - name: "Property Management Agreements" + name: Property Management Agreements difficulty: 4 estimatedMinutes: 25 - tags: [s19-property-mgmt, management-agreement] - sourceRef: "DOS Syllabus Subject 19: Property Management" + tags: + - s19-property-mgmt + - management-agreement + sourceRef: 'DOS Syllabus Subject 19: Property Management' prerequisites: - fiduciary-duties - contract-essentials encompassing: - concept: fiduciary-duties weight: 0.3 - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: landlord-tenant-relations - name: "Landlord-Tenant Relations" + name: Landlord-Tenant Relations difficulty: 4 estimatedMinutes: 25 - tags: [s19-property-mgmt, landlord-tenant] - sourceRef: "DOS Syllabus Subject 19: Property Management" + tags: + - s19-property-mgmt + - landlord-tenant + sourceRef: 'DOS Syllabus Subject 19: Property Management' prerequisites: - lease-types encompassing: - concept: lease-types weight: 0.4 - knowledgePoints: [] # KPs to be authored - + knowledgePoints: [] - id: property-management-budgets - name: "Property Management Budgets" + name: Property Management Budgets difficulty: 5 estimatedMinutes: 25 - tags: [s19-property-mgmt, budgets] - sourceRef: "DOS Syllabus Subject 19: Property Management" + tags: + - s19-property-mgmt + - budgets + sourceRef: 'DOS Syllabus Subject 19: Property Management' prerequisites: - net-operating-income - management-agreements encompassing: - concept: net-operating-income weight: 0.4 - knowledgePoints: [] # KPs to be authored + knowledgePoints: [] diff --git a/content/courses/posthog-tam-onboarding.yaml b/content/courses/posthog-tam-onboarding.yaml index 778e828..4188f3f 100644 --- a/content/courses/posthog-tam-onboarding.yaml +++ b/content/courses/posthog-tam-onboarding.yaml @@ -1,9 +1,7 @@ course: id: posthog-tam-onboarding name: PostHog TAM Technical Onboarding - description: >- - Comprehensive technical onboarding for PostHog Technical Account Managers — from data modeling fundamentals through the PostHog data model, ingestion pipeline, identification, group analytics, - CDP, and querying. + description: Comprehensive technical onboarding for PostHog Technical Account Managers — from data modeling fundamentals through the PostHog data model, ingestion pipeline, identification, group analytics, CDP, and querying. estimatedHours: 12 version: '2026.1' sourceDocument: PostHog product documentation (analytics, persons, group analytics, CDP, and HogQL docs), reviewed March 2026 @@ -23,9 +21,7 @@ sections: minQuestions: 2 - conceptId: keys-and-identity minQuestions: 2 - instructions: >- - Work without step-by-step cues. Show that you can distinguish entities, attributes, and keys, - then apply those ideas to realistic PostHog-flavored examples. + instructions: Work without step-by-step cues. Show that you can distinguish entities, attributes, and keys, then apply those ideas to realistic PostHog-flavored examples. - id: data-modeling-design name: Data Modeling Design description: Relationships, cardinality, join tables, and the design process. @@ -54,9 +50,7 @@ sections: minQuestions: 1 - conceptId: ph-actions minQuestions: 1 - instructions: >- - This exam checks whether you can reason about the core PostHog entities and how they connect - in analysis, ingestion, and product usage. + instructions: This exam checks whether you can reason about the core PostHog entities and how they connect in analysis, ingestion, and product usage. - id: posthog-ingestion name: PostHog Ingestion Pipeline description: How events flow from capture through Kafka to ClickHouse storage. @@ -74,8 +68,7 @@ sections: minQuestions: 1 - conceptId: ph-person-processing minQuestions: 1 - instructions: >- - Show that you can trace what happens to an event after capture and explain where identity and storage fit. + instructions: Show that you can trace what happens to an event after capture and explain where identity and storage fit. - id: identification name: Identification description: Anonymous vs identified events, the identify call, person merging, and common pitfalls. @@ -93,8 +86,7 @@ sections: minQuestions: 1 - conceptId: identification-pitfalls minQuestions: 2 - instructions: >- - Work from behavior and system outcomes, not memorized definitions. The goal is to spot good and bad identification patterns. + instructions: Work from behavior and system outcomes, not memorized definitions. The goal is to spot good and bad identification patterns. - id: group-analytics name: Group Analytics description: Modeling organizations and B2B analytics with PostHog groups. @@ -112,8 +104,7 @@ sections: minQuestions: 1 - conceptId: group-gotchas minQuestions: 1 - instructions: >- - Demonstrate that you can model organizations cleanly and explain how groups change analysis in a B2B setting. + instructions: Demonstrate that you can model organizations cleanly and explain how groups change analysis in a B2B setting. - id: posthog-cdp name: PostHog CDP description: Data pipelines in PostHog — sources, transformations, and destinations. @@ -127,8 +118,7 @@ sections: minQuestions: 2 - conceptId: ph-destinations-exports minQuestions: 2 - instructions: >- - Show that you understand what PostHog CDP is for and where destinations and exports fit in a customer workflow. + instructions: Show that you understand what PostHog CDP is for and where destinations and exports fit in a customer workflow. - id: querying name: Querying Foundations description: Cohorts and HogQL for practical analysis. @@ -142,9 +132,7 @@ sections: minQuestions: 2 - conceptId: hogql-basics minQuestions: 2 - instructions: >- - This exam checks whether you can move from product questions to the right querying tool, - especially when HogQL is the right fit. + instructions: This exam checks whether you can move from product questions to the right querying tool, especially when HogQL is the right fit. concepts: - id: entities name: Entities — Things That Exist @@ -157,28 +145,22 @@ concepts: encompassing: [] knowledgePoints: - id: what-is-an-entity - instruction: >- + instruction: |- An **entity** is anything you need to store information about in a system. Entities are the nouns — the people, places, things, and concepts that matter to your business. - If you find yourself wanting to describe something with multiple facts (attributes), you are looking at an entity. A Customer is an entity because you want to track their name, email, and signup date. An Order is an entity because it has an order number, total, and status. A Product is an entity because it has a SKU, price, and description. - Entities are not actions or verbs — those become relationships later. - **The key test:** can you have more than one of this thing, and do you need to tell them apart? If yes, it is an entity. - In a hospital system, Patient, Doctor, Appointment, and Medication are all entities. In a music streaming app, User, Song, Playlist, and Artist are entities. - Recognizing entities is the first and most important step in data modeling because everything else — attributes, keys, relationships — hangs off of them. instructionContent: - type: callout title: Entity identification shortcut - body: >- - Ask three questions in order: can there be many of these, do we need to distinguish one from another, and do we track multiple facts about each one? + body: 'Ask three questions in order: can there be many of these, do we need to distinguish one from another, and do we track multiple facts about each one?' - type: link url: https://www.lucidchart.com/pages/er-diagrams title: Visual ER diagram primer @@ -193,16 +175,12 @@ concepts: - A single data value, like a name or email address - A rule that governs how data is validated correct: 1 - explanation: >- - An entity is a noun — a thing you need to store information about. Customer, Order, and Product are classic examples. Verbs become relationships, single values become attributes, and - rules become constraints. + explanation: An entity is a noun — a thing you need to store information about. Customer, Order, and Product are classic examples. Verbs become relationships, single values become attributes, and rules become constraints. - id: entities-p2 type: true_false question: In data modeling, an entity represents a single data value like a phone number or email address. correct: 'false' - explanation: >- - A single data value like a phone number is an attribute, not an entity. An entity is a thing (like a Customer) that has multiple attributes (name, phone number, email). Entities are the - nouns; attributes are the facts about those nouns. + explanation: A single data value like a phone number is an attribute, not an entity. An entity is a thing (like a Customer) that has multiple attributes (name, phone number, email). Entities are the nouns; attributes are the facts about those nouns. - id: entities-p3 type: scenario question: You are building a project management tool. Users create projects, add tasks to projects, and assign tasks to team members. Which of the following is NOT an entity in this system? @@ -212,26 +190,17 @@ concepts: - Assigns (the act of assigning a task) - Task correct: 2 - explanation: >- - 'Assigns' is a verb describing the relationship between a User and a Task — it is a relationship, not an entity. User, Project, and Task are all nouns that you would store information - about, making them entities. + explanation: '''Assigns'' is a verb describing the relationship between a User and a Task — it is a relationship, not an entity. User, Project, and Task are all nouns that you would store information about, making them entities.' - id: identifying-entities - instruction: >- + instruction: |- The first step in any data modeling exercise is identifying entities. A reliable technique: read or write a plain-English description of the system and **circle the nouns**. - In the sentence "Customers place orders for products," the nouns are Customer, Order, and Product — those are your candidate entities. Verbs like "place" and "for" hint at relationships you will define later. - Not every noun becomes an entity. A good entity has three qualities: it has **multiple instances** (there are many customers, not just one), it needs to be **uniquely identified** (Customer 42 vs Customer 43), and it has **its own attributes** worth tracking. - If a noun is really just a single attribute of another entity, it is not its own entity. For example, "color" is probably an attribute of Product, not a standalone entity — unless your system needs to track detailed information about each color (name, hex code, pantone number), in which case it might become one. - workedExample: >- - Consider an e-commerce system described as: 'Customers browse a catalog of products. They add items to a shopping cart and place orders. Each order contains one or more line items, and - payments are processed for each order.' Step 1: Circle the nouns — Customer, Catalog, Product, Shopping Cart, Order, Line Item, Payment. Step 2: Evaluate each. Catalog is probably just the - collection of products, not a separate entity. Shopping Cart might be an entity or might be a temporary state of an Order. The strong entities are: Customer, Product, Order, Line Item, and - Payment. Each has multiple instances, needs unique identification, and has its own attributes. + workedExample: 'Consider an e-commerce system described as: ''Customers browse a catalog of products. They add items to a shopping cart and place orders. Each order contains one or more line items, and payments are processed for each order.'' Step 1: Circle the nouns — Customer, Catalog, Product, Shopping Cart, Order, Line Item, Payment. Step 2: Evaluate each. Catalog is probably just the collection of products, not a separate entity. Shopping Cart might be an entity or might be a temporary state of an Order. The strong entities are: Customer, Product, Order, Line Item, and Payment. Each has multiple instances, needs unique identification, and has its own attributes.' problems: - id: identifying-entities-p1 type: multiple_choice @@ -255,18 +224,15 @@ concepts: explanation: Entities are the nouns in your system — the people, places, things, and concepts you need to store information about. Verbs become relationships. - id: identifying-entities-p3 type: scenario - question: >- - You read this product brief: 'Drivers deliver packages to customers. Each delivery has a timestamp and a signature.' A teammate says Delivery is not an entity because it started as a verb. - How do you respond? + question: 'You read this product brief: ''Drivers deliver packages to customers. Each delivery has a timestamp and a signature.'' A teammate says Delivery is not an entity because it started as a verb. How do you respond?' options: - They are correct — 'deliver' is a verb, so Delivery cannot be an entity - Delivery has its own attributes (timestamp, signature) and multiple instances, so it qualifies as an entity - Delivery should be stored as an attribute on Package instead - Delivery is only a relationship and can never become an entity correct: 1 - explanation: >- - The three-part test still applies. Delivery has multiple instances, needs unique identification, and has its own attributes (timestamp, signature). Some words that start as verbs evolve - into entities once they accumulate their own facts. If you agreed with the teammate, revisit the entity identification shortcut. + explanation: The three-part test still applies. Delivery has multiple instances, needs unique identification, and has its own attributes (timestamp, signature). Some words that start as verbs evolve into entities once they accumulate their own facts. If you agreed with the teammate, revisit the entity identification shortcut. + keyPrerequisite: entities section: data-modeling-basics - id: attributes name: Attributes — Properties of Entities @@ -280,15 +246,11 @@ concepts: encompassing: [] knowledgePoints: - id: what-are-attributes - instruction: >- - Attributes are the individual facts stored about one entity instance. A Customer might have first_name, email, and signup_date. An Order might have order_number, total_amount, and status. - The first quality bar is atomicity: each attribute should hold one fact, not a bundled sentence. A field like 'name_and_address' is really several attributes hiding inside one column. - Atomic attributes are easier to validate, filter, sort, and reuse in analysis. + instruction: 'Attributes are the individual facts stored about one entity instance. A Customer might have first_name, email, and signup_date. An Order might have order_number, total_amount, and status. The first quality bar is atomicity: each attribute should hold one fact, not a bundled sentence. A field like ''name_and_address'' is really several attributes hiding inside one column. Atomic attributes are easier to validate, filter, sort, and reuse in analysis.' instructionContent: - type: callout title: Atomic first - body: >- - If you cannot answer "what single fact does this field store?" without saying "and", the field is probably too wide. + body: If you cannot answer "what single fact does this field store?" without saying "and", the field is probably too wide. - type: link url: https://www.postgresql.org/docs/current/datatype.html title: PostgreSQL data types overview @@ -303,37 +265,26 @@ concepts: - product, details, misc_data - name, order_id, customer_email correct: 1 - explanation: >- - Good attributes are atomic (one fact each), descriptive, and belong to the entity. Option B has clear, atomic attributes that all describe a Product. Option A violates atomicity by - combining values. Option C is too vague. Option D mixes in attributes from other entities (order_id, customer_email). + explanation: Good attributes are atomic (one fact each), descriptive, and belong to the entity. Option B has clear, atomic attributes that all describe a Product. Option A violates atomicity by combining values. Option C is too vague. Option D mixes in attributes from other entities (order_id, customer_email). - id: attributes-p2 type: true_false question: An attribute called 'full_address' that stores '123 Main St, Springfield, IL 62704' follows good data modeling practice. correct: 'false' - explanation: >- - This violates the atomicity principle. A good data model would break this into separate attributes: street, city, state, and zip_code. Atomic attributes make it possible to query, - filter, and sort by individual components (e.g., find all customers in Illinois). + explanation: 'This violates the atomicity principle. A good data model would break this into separate attributes: street, city, state, and zip_code. Atomic attributes make it possible to query, filter, and sort by individual components (e.g., find all customers in Illinois).' - id: attributes-p5 type: scenario - question: >- - A teammate designs a Customer table with a field called 'contact_info' that stores 'jane@co.com | 555-1234 | San Francisco'. What feedback would you give? + question: A teammate designs a Customer table with a field called 'contact_info' that stores 'jane@co.com | 555-1234 | San Francisco'. What feedback would you give? options: - This is efficient because it saves columns - The field violates atomicity — it should be split into email, phone, and city - Contact info is not an attribute at all - This is fine as long as the application parses it correctly correct: 1 - explanation: >- - Bundling multiple facts into one field makes filtering, sorting, and validating each fact impossible at the database level. Split it into email, phone, and city so each attribute holds - one fact. If you thought application parsing is good enough, consider what happens when someone queries 'find all customers in San Francisco' — a bundled field makes that painful. + explanation: Bundling multiple facts into one field makes filtering, sorting, and validating each fact impossible at the database level. Split it into email, phone, and city so each attribute holds one fact. If you thought application parsing is good enough, consider what happens when someone queries 'find all customers in San Francisco' — a bundled field makes that painful. + keyPrerequisite: entities - id: attribute-boundaries - instruction: >- - After you list candidate attributes, ask two follow-up questions. First: does this field really belong to this entity? Second: is this still an attribute, or has it become its own entity or - relationship? Repeated structured data often signals a missing relationship. If Order and Invoice both store customer_name, that fact probably belongs on Customer instead. Attribute design is - really boundary design: one fact, owned by one entity, in the place where it can stay accurate over time. - workedExample: >- - Imagine a catalog where every Product row stores color_name, color_hex, and pantone_code. That works until the business wants one shared color catalog used across many products. At that - point, Color is no longer just a label on Product. It has its own reusable structure, so Product should reference Color instead of duplicating those fields everywhere. + instruction: 'After you list candidate attributes, ask two follow-up questions. First: does this field really belong to this entity? Second: is this still an attribute, or has it become its own entity or relationship? Repeated structured data often signals a missing relationship. If Order and Invoice both store customer_name, that fact probably belongs on Customer instead. Attribute design is really boundary design: one fact, owned by one entity, in the place where it can stay accurate over time.' + workedExample: Imagine a catalog where every Product row stores color_name, color_hex, and pantone_code. That works until the business wants one shared color catalog used across many products. At that point, Color is no longer just a label on Product. It has its own reusable structure, so Product should reference Color instead of duplicating those fields everywhere. instructionContent: - type: link url: https://www.postgresql.org/docs/current/tutorial-fk.html @@ -349,30 +300,23 @@ concepts: - The Order and Invoice entities should be combined into one - customer_name should be removed from both entities correct: 1 - explanation: >- - When the same attribute appears on multiple entities, it usually means there is a missing relationship. Both Order and Invoice should reference a Customer entity via a foreign key, - rather than duplicating the customer's name. + explanation: When the same attribute appears on multiple entities, it usually means there is a missing relationship. Both Order and Invoice should reference a Customer entity via a foreign key, rather than duplicating the customer's name. - id: attributes-p4 type: scenario - question: >- - A merch store keeps color_name, color_hex, and pantone_code directly on every Product row. The team now wants one reusable color catalog shared across many products. What is the best next - move? + question: A merch store keeps color_name, color_hex, and pantone_code directly on every Product row. The team now wants one reusable color catalog shared across many products. What is the best next move? options: - Keep the color fields on Product and add more color columns as needed - Create a Color entity and reference it from Product - Combine the three fields into one text blob so the row stays shorter - Remove color entirely because attributes should never repeat correct: 1 - explanation: >- - Once color has its own reusable structure, it has crossed the line from "simple attribute" into "reference entity." A Color entity keeps the shared facts in one place and lets Product - point to them cleanly. + explanation: Once color has its own reusable structure, it has crossed the line from "simple attribute" into "reference entity." A Color entity keeps the shared facts in one place and lets Product point to them cleanly. - id: attributes-p6 type: true_false question: If the same structured data (like color_name, color_hex) appears on multiple entities, it is always best to leave those fields duplicated on each entity. correct: 'false' - explanation: >- - Repeated structured data across entities usually signals a missing reference entity. When the same cluster of fields appears in multiple places, extract them into their own entity and - reference it via foreign key. This avoids duplication and keeps updates consistent. + explanation: Repeated structured data across entities usually signals a missing reference entity. When the same cluster of fields appears in multiple places, extract them into their own entity and reference it via foreign key. This avoids duplication and keeps updates consistent. + keyPrerequisite: attributes section: data-modeling-basics - id: keys-and-identity name: Keys — Uniquely Identifying Things @@ -387,22 +331,16 @@ concepts: encompassing: [] knowledgePoints: - id: primary-keys - instruction: >- - Every entity needs a primary key: the attribute, or combination of attributes, that uniquely identifies one instance. Customer 42 is different from Customer 43 because their keys are - different. The first job of a primary key is identity inside the entity itself. A good primary key is unique, stable over time, and never null. If any of those fail, the entity becomes hard - to trust because duplicates, broken references, or missing records start to appear. + instruction: 'Every entity needs a primary key: the attribute, or combination of attributes, that uniquely identifies one instance. Customer 42 is different from Customer 43 because their keys are different. The first job of a primary key is identity inside the entity itself. A good primary key is unique, stable over time, and never null. If any of those fail, the entity becomes hard to trust because duplicates, broken references, or missing records start to appear.' instructionContent: - type: callout title: Three tests for a primary key - body: >- - Ask three questions: can two rows share it, can it change later, and can it ever be missing? If the answer is yes to any of those, it is a weak primary key candidate. + body: 'Ask three questions: can two rows share it, can it change later, and can it ever be missing? If the answer is yes to any of those, it is a weak primary key candidate.' - type: link url: https://www.postgresql.org/docs/current/ddl-constraints.html#DDL-CONSTRAINTS-PRIMARY-KEYS title: PostgreSQL primary key reference description: A concrete reference for how databases enforce the uniqueness and non-null guarantees discussed here. - workedExample: >- - Imagine an Order table keyed by order_id. If order_id is unique, present on every row, and never reused, then each order stays distinguishable even when many orders have the same amount, - date, or customer. That is what makes order_id a real identity field instead of just another attribute. + workedExample: Imagine an Order table keyed by order_id. If order_id is unique, present on every row, and never reused, then each order stays distinguishable even when many orders have the same amount, date, or customer. That is what makes order_id a real identity field instead of just another attribute. problems: - id: keys-p1 type: multiple_choice @@ -413,9 +351,7 @@ concepts: - To encrypt sensitive data in the entity - To define the data type of each attribute correct: 1 - explanation: >- - A primary key uniquely identifies each instance of an entity. It ensures no two records are the same and allows other entities to reference it. It is not about importance, encryption, or - data types. + explanation: A primary key uniquely identifies each instance of an entity. It ensures no two records are the same and allows other entities to reference it. It is not about importance, encryption, or data types. - id: keys-p4 type: multiple_choice question: Which combination best describes a strong primary key? @@ -425,39 +361,29 @@ concepts: - Long text, frequently updated, and visible to users - Derived from several changing business rules correct: 1 - explanation: >- - If you were drawn to readability, you focused on convenience instead of identity quality. A strong primary key must stay unique, stable, and present even when business labels change. + explanation: If you were drawn to readability, you focused on convenience instead of identity quality. A strong primary key must stay unique, stable, and present even when business labels change. - id: keys-p7 type: scenario - question: >- - A developer proposes using 'order_date' as the primary key for an Orders table because each order has a different date. On a busy day the system creates two orders at the exact same - timestamp. What problem does this cause? + question: A developer proposes using 'order_date' as the primary key for an Orders table because each order has a different date. On a busy day the system creates two orders at the exact same timestamp. What problem does this cause? options: - No problem — timestamps are always unique - The primary key constraint fails because two rows share the same value - The database automatically adds a suffix to make them unique - The second order overwrites the first correct: 1 - explanation: >- - Timestamps are not guaranteed unique, especially under high throughput. A primary key must be unique for every row. If you assumed timestamps are always distinct, the mental model fix - is to separate 'usually unique' from 'guaranteed unique.' Use a surrogate key instead. + explanation: Timestamps are not guaranteed unique, especially under high throughput. A primary key must be unique for every row. If you assumed timestamps are always distinct, the mental model fix is to separate 'usually unique' from 'guaranteed unique.' Use a surrogate key instead. + keyPrerequisite: entities - id: foreign-keys-need-stable-targets - instruction: >- - Once an entity has a trustworthy primary key, other entities can point at it with foreign keys. That is how a model expresses connections such as "this Order belongs to Customer 42." This - only works if the referenced key stays stable. If the target key changes, every relationship that points to it becomes harder to maintain. That is why key choice is not just a local table - decision. It shapes whether the rest of the model can connect safely. + instruction: Once an entity has a trustworthy primary key, other entities can point at it with foreign keys. That is how a model expresses connections such as "this Order belongs to Customer 42." This only works if the referenced key stays stable. If the target key changes, every relationship that points to it becomes harder to maintain. That is why key choice is not just a local table decision. It shapes whether the rest of the model can connect safely. instructionContent: - type: callout title: Identity spreads outward - body: >- - A weak key does not stay a local problem. The moment another table references it, that weakness becomes a relationship problem too. + body: A weak key does not stay a local problem. The moment another table references it, that weakness becomes a relationship problem too. - type: link url: https://www.postgresql.org/docs/current/tutorial-fk.html title: PostgreSQL foreign key tutorial description: Useful reference for how foreign keys depend on stable primary keys. - workedExample: >- - Suppose Orders stores customer_id to show which customer placed each order. If customer_id is a stable surrogate key, every order can keep pointing to the right customer even if the - customer's email or company name changes later. + workedExample: Suppose Orders stores customer_id to show which customer placed each order. If customer_id is a stable surrogate key, every order can keep pointing to the right customer even if the customer's email or company name changes later. problems: - id: keys-p5 type: scenario @@ -468,8 +394,7 @@ concepts: - It is an optional display label - It is a session identifier correct: 1 - explanation: >- - Inside Order, customer_id points to a Customer record, so it is a foreign key. If you chose "primary key," you mixed up "identifies this row" with "references another row." + explanation: Inside Order, customer_id points to a Customer record, so it is a foreign key. If you chose "primary key," you mixed up "identifies this row" with "references another row." - id: keys-p6 type: multiple_choice question: Why does key stability matter beyond the table where the key lives? @@ -479,28 +404,20 @@ concepts: - Stable keys automatically improve query speed - Only unstable keys can be indexed correct: 1 - explanation: >- - Other entities depend on that key as a reference target. If you missed this, the misconception is treating key design as a local table concern instead of the backbone of relationships. + explanation: Other entities depend on that key as a reference target. If you missed this, the misconception is treating key design as a local table concern instead of the backbone of relationships. - id: keys-p8 type: true_false question: A foreign key can safely point to a primary key that is occasionally updated, as long as the updates are small. correct: 'false' - explanation: >- - Any change to a referenced primary key risks breaking every foreign key that points to it. Size of change does not matter — even a small edit creates a mismatch. Stability means no - changes, not small changes. + explanation: Any change to a referenced primary key risks breaking every foreign key that points to it. Size of change does not matter — even a small edit creates a mismatch. Stability means no changes, not small changes. + keyPrerequisite: keys-and-identity - id: choosing-key-types - instruction: >- - Once you know an entity needs a key, the next decision is what kind. Surrogate keys are system-generated IDs such as integers or UUIDs. Natural keys come from the business domain, like email - or SKU. Composite keys combine multiple fields. Surrogate keys are usually the safest default because they stay stable even when business data changes. Natural and composite keys can still be - useful, but only when their uniqueness and stability are truly dependable. - workedExample: >- - Suppose a User table uses email as its primary key. That feels convenient until someone changes their email address, or two employees share a team inbox. A surrogate user_id avoids that - instability, while email can remain a normal attribute with its own unique constraint if the business needs it. + instruction: Once you know an entity needs a key, the next decision is what kind. Surrogate keys are system-generated IDs such as integers or UUIDs. Natural keys come from the business domain, like email or SKU. Composite keys combine multiple fields. Surrogate keys are usually the safest default because they stay stable even when business data changes. Natural and composite keys can still be useful, but only when their uniqueness and stability are truly dependable. + workedExample: Suppose a User table uses email as its primary key. That feels convenient until someone changes their email address, or two employees share a team inbox. A surrogate user_id avoids that instability, while email can remain a normal attribute with its own unique constraint if the business needs it. instructionContent: - type: callout title: Safe default - body: >- - If the business field might change, let it be an attribute with a uniqueness rule and keep a surrogate ID as the true primary key. + body: If the business field might change, let it be an attribute with a uniqueness rule and keep a surrogate ID as the true primary key. problems: - id: keys-p2 type: multiple_choice @@ -511,29 +428,23 @@ concepts: - composite key - foreign key correct: 1 - explanation: >- - A surrogate key is a system-generated identifier with no inherent business meaning. It is preferred over natural keys (like email or SSN) because surrogate keys are guaranteed to be - stable and unique. + explanation: A surrogate key is a system-generated identifier with no inherent business meaning. It is preferred over natural keys (like email or SSN) because surrogate keys are guaranteed to be stable and unique. - id: keys-p3 type: true_false question: Using an email address as a primary key is always a good choice because every user has a unique email. correct: 'false' - explanation: >- - Email addresses can change and they are not guaranteed to map cleanly to one durable identity. If you answered true, the likely mistake is confusing "often unique right now" with - "safe primary key for the life of the record." Surrogate keys are safer because they stay stable even when business data changes. + explanation: Email addresses can change and they are not guaranteed to map cleanly to one durable identity. If you answered true, the likely mistake is confusing "often unique right now" with "safe primary key for the life of the record." Surrogate keys are safer because they stay stable even when business data changes. - id: keys-p9 type: scenario - question: >- - A Product table uses SKU as its primary key. The business decides to change the SKU format from '5-digit number' to 'prefix-5-digit' for all existing products. What risk does this create? + question: A Product table uses SKU as its primary key. The business decides to change the SKU format from '5-digit number' to 'prefix-5-digit' for all existing products. What risk does this create? options: - No risk — SKUs are just labels - Every table with a foreign key referencing Product.sku must also be updated, which is error-prone at scale - The database automatically cascades the change - Only new products are affected correct: 1 - explanation: >- - Changing a natural key that is referenced as a foreign key in other tables requires coordinated updates everywhere. This is exactly why surrogate keys are the safer default — they never - need to change when business labels evolve. Cascade rules can help but add complexity and risk. + explanation: Changing a natural key that is referenced as a foreign key in other tables requires coordinated updates everywhere. This is exactly why surrogate keys are the safer default — they never need to change when business labels evolve. Cascade rules can help but add complexity and risk. + keyPrerequisite: keys-and-identity section: data-modeling-basics - id: relationships name: Relationships — How Entities Connect @@ -548,22 +459,18 @@ concepts: encompassing: [] knowledgePoints: - id: what-are-relationships - instruction: >- + instruction: |- A **relationship** describes how two entities interact or connect. In the sentence "Customers place Orders," the verb "places" is the relationship between the Customer entity and the Order entity. - Relationships are the verbs and prepositions in your system description. They have a direction (Customer places Order, not the reverse) and a name that describes the interaction. - **Implementation:** relationships are implemented through foreign keys — an attribute on one entity that references the primary key of another. For example, the Order entity would have a customer_id attribute that points to the Customer entity's primary key. - Without relationships, your entities would be isolated silos of data with no way to answer questions like "which customer placed this order?" or "what orders does this customer have?" instructionContent: - type: callout title: Read the arrow carefully - body: >- - The foreign key usually lives on the side that has many records. In Customer -> Order, the relationship is implemented by customer_id on Order. + body: The foreign key usually lives on the side that has many records. In Customer -> Order, the relationship is implemented by customer_id on Order. - type: link url: https://www.lucidchart.com/pages/er-diagrams title: Relationship and foreign-key visual guide @@ -578,47 +485,35 @@ concepts: - By duplicating data across multiple entities - By creating a separate configuration file correct: 1 - explanation: >- - Relationships are implemented through foreign keys. A foreign key is an attribute on one entity (like customer_id on Order) that references the primary key of another entity (Customer). - This creates a link between the two without duplicating data. + explanation: Relationships are implemented through foreign keys. A foreign key is an attribute on one entity (like customer_id on Order) that references the primary key of another entity (Customer). This creates a link between the two without duplicating data. - id: relationships-p2 type: scenario - question: >- - You are designing a blog platform. Posts are written by Authors, and each Post can have many Comments. A junior developer suggests storing the author's name and email directly on every - Post record instead of using a foreign key to an Author entity. What is the main problem with this approach? + question: You are designing a blog platform. Posts are written by Authors, and each Post can have many Comments. A junior developer suggests storing the author's name and email directly on every Post record instead of using a foreign key to an Author entity. What is the main problem with this approach? options: - It makes the Post table too wide - It creates data duplication — if the author changes their email, you must update every Post - It violates naming conventions - It makes the database slower to read correct: 1 - explanation: >- - Duplicating author data on every Post creates an update anomaly — if the author changes their email, you must find and update every Post record. Using a foreign key (author_id on Post - referencing the Author entity) means the email is stored once and changes propagate automatically. + explanation: Duplicating author data on every Post creates an update anomaly — if the author changes their email, you must find and update every Post record. Using a foreign key (author_id on Post referencing the Author entity) means the email is stored once and changes propagate automatically. - id: relationships-p3 type: true_false question: Without relationships (foreign keys), you could still answer the question 'which customer placed this order?' using only the Order table. correct: 'false' - explanation: >- - Without a foreign key connecting Order to Customer, the Order table has no reference to the Customer entity. You could not determine which customer placed which order. Relationships are - what make cross-entity questions answerable. + explanation: Without a foreign key connecting Order to Customer, the Order table has no reference to the Customer entity. You could not determine which customer placed which order. Relationships are what make cross-entity questions answerable. + keyPrerequisite: keys-and-identity - id: optional-vs-mandatory - instruction: >- + instruction: |- Relationships can be **optional** or **mandatory**. - A **mandatory** relationship means every instance of one entity must be connected to the other. An Order must have a Customer — it makes no sense to have an order with no buyer. - An **optional** relationship means the connection may or may not exist. A Customer may have zero orders (they signed up but never purchased). - These participation rules reflect real business logic and prevent invalid data. - **In database terms:** mandatory relationships translate to NOT NULL foreign keys — the foreign key column cannot be empty. Optional relationships allow NULL foreign keys. - Getting this right matters for data quality. If your model says "every order must have a customer" but the database allows null customer_id, you will eventually get orphaned orders that break reports and analytics. problems: - id: optional-mandatory-p1 @@ -630,9 +525,7 @@ concepts: - Both sides of the relationship are optional - The Customer-to-Invoice side is mandatory; the Invoice-to-Customer side is optional correct: 1 - explanation: >- - Every Invoice must have a Customer (mandatory from Invoice side — the foreign key customer_id cannot be null). But a Customer can exist without any Invoices (optional from Customer - side). This asymmetry is very common in real data models. + explanation: Every Invoice must have a Customer (mandatory from Invoice side — the foreign key customer_id cannot be null). But a Customer can exist without any Invoices (optional from Customer side). This asymmetry is very common in real data models. - id: optional-mandatory-p2 type: true_false question: If a relationship is optional on one side, it must also be optional on the other side. @@ -640,17 +533,15 @@ concepts: explanation: Relationships can have different participation on each side. An Order must have a Customer (mandatory), but a Customer may have zero Orders (optional). The two sides are independent. - id: optional-mandatory-p3 type: scenario - question: >- - A User entity has a profile_photo_id foreign key pointing to a Photo entity. Some users have not uploaded a photo. Should this foreign key be NOT NULL or nullable? + question: A User entity has a profile_photo_id foreign key pointing to a Photo entity. Some users have not uploaded a photo. Should this foreign key be NOT NULL or nullable? options: - NOT NULL — every user must have a photo - Nullable — the relationship is optional because not every user has a photo - Remove the foreign key and store the photo data directly on User - Use a default placeholder photo_id that all users without photos share correct: 1 - explanation: >- - Since some users have no photo, the relationship is optional and the foreign key should be nullable. Making it NOT NULL would prevent creating users who have not uploaded a photo yet. - The placeholder option works but masks the optionality with a workaround rather than modeling it cleanly. + explanation: Since some users have no photo, the relationship is optional and the foreign key should be nullable. Making it NOT NULL would prevent creating users who have not uploaded a photo yet. The placeholder option works but masks the optionality with a workaround rather than modeling it cleanly. + keyPrerequisite: relationships section: data-modeling-design - id: cardinality name: Cardinality — How Many of Each? @@ -664,15 +555,11 @@ concepts: encompassing: [] knowledgePoints: - id: cardinality-types - instruction: >- - Cardinality answers the question "how many of A can connect to how many of B?" There are three patterns to recognize. One-to-one means each side matches one instance on the other side. - One-to-many means one record on the left can connect to many on the right, but each right-side record points back to only one left-side record. Many-to-many means both sides can have many - matches. Cardinality is the bridge between business rules and table design. + instruction: Cardinality answers the question "how many of A can connect to how many of B?" There are three patterns to recognize. One-to-one means each side matches one instance on the other side. One-to-many means one record on the left can connect to many on the right, but each right-side record points back to only one left-side record. Many-to-many means both sides can have many matches. Cardinality is the bridge between business rules and table design. instructionContent: - type: callout title: Read both directions - body: >- - Always say the relationship out loud both ways. "One customer has many orders" and "each order belongs to one customer" is how you confirm you are truly looking at one-to-many. + body: Always say the relationship out loud both ways. "One customer has many orders" and "each order belongs to one customer" is how you confirm you are truly looking at one-to-many. problems: - id: cardinality-p1 type: multiple_choice @@ -693,21 +580,15 @@ concepts: - Students and Courses|Many-to-many - Country and Capital City|One-to-one correct: 0,1,2,3 - explanation: >- - A Person has one SSN and vice versa (1:1). A Department has many Employees, each Employee in one Department (1:N). Students take many Courses and Courses have many Students (M:N). A - Country has one Capital and each Capital belongs to one Country (1:1). + explanation: A Person has one SSN and vice versa (1:1). A Department has many Employees, each Employee in one Department (1:N). Students take many Courses and Courses have many Students (M:N). A Country has one Capital and each Capital belongs to one Country (1:1). - id: cardinality-p5 type: true_false question: In a one-to-many relationship, records on the 'many' side can each point to a different record on the 'one' side. correct: 'true' - explanation: >- - In one-to-many, each record on the 'many' side points to exactly one record on the 'one' side — but different 'many' records can point to different 'one' records. For example, different - Orders can belong to different Customers. If you answered false, you may have confused this with one-to-one. + explanation: In one-to-many, each record on the 'many' side points to exactly one record on the 'one' side — but different 'many' records can point to different 'one' records. For example, different Orders can belong to different Customers. If you answered false, you may have confused this with one-to-one. + keyPrerequisite: relationships - id: implementing-cardinality - instruction: >- - Once you know the cardinality, you can decide the implementation pattern. One-to-many is usually implemented with a foreign key on the many side. One-to-one often uses a foreign key plus a - unique constraint, or it may signal that two entities should really be one. Many-to-many cannot be represented by a single foreign key, so it becomes a join table. The key move is to derive - the storage pattern from the business rule instead of memorizing table shapes. + instruction: Once you know the cardinality, you can decide the implementation pattern. One-to-many is usually implemented with a foreign key on the many side. One-to-one often uses a foreign key plus a unique constraint, or it may signal that two entities should really be one. Many-to-many cannot be represented by a single foreign key, so it becomes a join table. The key move is to derive the storage pattern from the business rule instead of memorizing table shapes. instructionContent: - type: link url: https://www.postgresql.org/docs/current/tutorial-fk.html @@ -716,18 +597,14 @@ concepts: problems: - id: cardinality-p3 type: scenario - question: >- - You are modeling a music streaming service. Users can create many Playlists, and each Playlist belongs to one User. However, each Playlist can contain many Songs, and each Song can - appear in many Playlists. Which relationship is many-to-many? + question: You are modeling a music streaming service. Users can create many Playlists, and each Playlist belongs to one User. However, each Playlist can contain many Songs, and each Song can appear in many Playlists. Which relationship is many-to-many? options: - User to Playlist - Playlist to Song - User to Song - Both User to Playlist and Playlist to Song correct: 1 - explanation: >- - Playlist to Song is many-to-many: a Playlist contains many Songs, and a Song can appear in many Playlists. User to Playlist is one-to-many: one User creates many Playlists, but each - Playlist has one creator. + explanation: 'Playlist to Song is many-to-many: a Playlist contains many Songs, and a Song can appear in many Playlists. User to Playlist is one-to-many: one User creates many Playlists, but each Playlist has one creator.' - id: cardinality-p4 type: multiple_choice question: In a one-to-many relationship, where does the foreign key go? @@ -740,17 +617,15 @@ concepts: explanation: The foreign key always goes on the 'many' side. In Customer (one) to Orders (many), the Order table gets a customer_id foreign key. Each Order points to its one Customer. - id: cardinality-p6 type: scenario - question: >- - You discover that a one-to-one relationship between Employee and ParkingPass is implemented with a foreign key on ParkingPass but no unique constraint. What could go wrong? + question: You discover that a one-to-one relationship between Employee and ParkingPass is implemented with a foreign key on ParkingPass but no unique constraint. What could go wrong? options: - Nothing — the foreign key is sufficient - Without a unique constraint, one employee could accidentally get multiple parking passes, violating the one-to-one rule - The database will enforce one-to-one automatically - ParkingPass should not have a foreign key at all correct: 1 - explanation: >- - A foreign key alone enforces referential integrity, not uniqueness. For one-to-one, you also need a unique constraint on the foreign key column so that no two ParkingPass rows point - to the same Employee. Without it, the relationship silently degrades to one-to-many. + explanation: A foreign key alone enforces referential integrity, not uniqueness. For one-to-one, you also need a unique constraint on the foreign key column so that no two ParkingPass rows point to the same Employee. Without it, the relationship silently degrades to one-to-many. + keyPrerequisite: cardinality section: data-modeling-design - id: associative-entities name: Associative Entities — Join Tables @@ -764,15 +639,11 @@ concepts: encompassing: [] knowledgePoints: - id: resolving-many-to-many - instruction: >- - Many-to-many relationships cannot be implemented with one foreign-key column. You need a third entity, usually called a join table or associative entity, that turns one many-to-many into two - one-to-many relationships. Students and Courses become Enrollment. Orders and Products become OrderLineItem. The join table is not a workaround; it is the real entity that represents each - pairing. + instruction: Many-to-many relationships cannot be implemented with one foreign-key column. You need a third entity, usually called a join table or associative entity, that turns one many-to-many into two one-to-many relationships. Students and Courses become Enrollment. Orders and Products become OrderLineItem. The join table is not a workaround; it is the real entity that represents each pairing. instructionContent: - type: callout title: Think in pairings - body: >- - A join-table row represents one specific pairing: this student in this course, this product in this order, this user in this role. + body: 'A join-table row represents one specific pairing: this student in this course, this product in this order, this user in this role.' problems: - id: assoc-p1 type: multiple_choice @@ -783,9 +654,7 @@ concepts: - Most databases do not support foreign keys - Many-to-many relationships are not allowed in data modeling correct: 1 - explanation: >- - A foreign key column holds one value pointing to one record. In a many-to-many, each Student relates to multiple Courses and vice versa — a single column cannot represent this. A join - table with rows for each pairing solves the problem. + explanation: A foreign key column holds one value pointing to one record. In a many-to-many, each Student relates to multiple Courses and vice versa — a single column cannot represent this. A join table with rows for each pairing solves the problem. - id: assoc-p2 type: multiple_choice question: An associative entity that resolves a many-to-many relationship between Order and Product is commonly called what? @@ -800,17 +669,11 @@ concepts: type: true_false question: A join table (associative entity) is just a workaround for a database limitation and does not represent a real concept in the data model. correct: 'false' - explanation: >- - A join table is a real entity that represents each specific pairing. Enrollment is a real thing (this student in this course), not just a technical workaround. It can have its own - attributes like enrollment_date and grade. If you answered true, revisit the idea that the pairing itself is a first-class concept. + explanation: A join table is a real entity that represents each specific pairing. Enrollment is a real thing (this student in this course), not just a technical workaround. It can have its own attributes like enrollment_date and grade. If you answered true, revisit the idea that the pairing itself is a first-class concept. + keyPrerequisite: cardinality - id: relationship-level-attributes - instruction: >- - The most important mental model is this: some facts belong to the relationship itself, not to either side of the relationship. Grade belongs to an Enrollment. Quantity belongs to an - OrderLineItem. Assigned_at belongs to a RoleAssignment. If you find yourself wondering where a fact goes, ask: "does this describe the left entity, the right entity, or this specific - pairing?" - workedExample: >- - In a hospital, Doctor and Patient are separate entities. But diagnosis_date and treatment_notes do not belong permanently to either Doctor or Patient. They describe one encounter between - them, so they belong on a Visit entity that links the two. + instruction: 'The most important mental model is this: some facts belong to the relationship itself, not to either side of the relationship. Grade belongs to an Enrollment. Quantity belongs to an OrderLineItem. Assigned_at belongs to a RoleAssignment. If you find yourself wondering where a fact goes, ask: "does this describe the left entity, the right entity, or this specific pairing?"' + workedExample: In a hospital, Doctor and Patient are separate entities. But diagnosis_date and treatment_notes do not belong permanently to either Doctor or Patient. They describe one encounter between them, so they belong on a Visit entity that links the two. instructionContent: - type: link url: https://www.postgresql.org/docs/current/tutorial-fk.html @@ -819,44 +682,35 @@ concepts: problems: - id: assoc-p3 type: scenario - question: >- - A hospital system has Doctors and Patients with a many-to-many relationship (a doctor treats many patients, a patient sees many doctors). You need to track the date of each visit and the - diagnosis. Where should these attributes live? + question: A hospital system has Doctors and Patients with a many-to-many relationship (a doctor treats many patients, a patient sees many doctors). You need to track the date of each visit and the diagnosis. Where should these attributes live? options: - On the Doctor entity - On the Patient entity - On an associative entity (e.g., Visit) between Doctor and Patient - In a separate configuration table correct: 2 - explanation: >- - Visit date and diagnosis describe the specific interaction between a Doctor and a Patient — they belong on the associative entity (Visit). They are not properties of the Doctor or - Patient alone, but of the relationship between them. + explanation: Visit date and diagnosis describe the specific interaction between a Doctor and a Patient — they belong on the associative entity (Visit). They are not properties of the Doctor or Patient alone, but of the relationship between them. - id: assoc-p4 type: scenario - question: >- - Users can have many Roles, and Roles can be granted to many Users. You also need to store assigned_by and assigned_at. Where should those two fields live? + question: Users can have many Roles, and Roles can be granted to many Users. You also need to store assigned_by and assigned_at. Where should those two fields live? options: - On User, because the grant affects the user - On Role, because the grant describes the role - On a RoleAssignment join table between User and Role - In a separate audit table only correct: 2 - explanation: >- - assigned_by and assigned_at describe one specific grant of one role to one user. That makes them attributes of the relationship row, not permanent attributes of User or Role alone. + explanation: assigned_by and assigned_at describe one specific grant of one role to one user. That makes them attributes of the relationship row, not permanent attributes of User or Role alone. - id: assoc-p6 type: multiple_choice - question: >- - An e-commerce system has Orders and Products linked through OrderLineItem. The attribute 'quantity' describes how many of a specific product are in a specific order. Where does 'quantity' - belong? + question: An e-commerce system has Orders and Products linked through OrderLineItem. The attribute 'quantity' describes how many of a specific product are in a specific order. Where does 'quantity' belong? options: - On the Order entity - On the Product entity - On the OrderLineItem (the join table) - In a separate configuration table correct: 2 - explanation: >- - Quantity describes one specific pairing of one product in one order — it is a relationship-level attribute. It does not belong on Order (which may have many products) or on Product - (which appears in many orders). It belongs on the join table that represents that specific pairing. + explanation: Quantity describes one specific pairing of one product in one order — it is a relationship-level attribute. It does not belong on Order (which may have many products) or on Product (which appears in many orders). It belongs on the join table that represents that specific pairing. + keyPrerequisite: associative-entities section: data-modeling-design - id: data-modeling-process name: The Data Modeling Design Process @@ -870,14 +724,11 @@ concepts: encompassing: [] knowledgePoints: - id: five-step-workflow - instruction: >- - Data modeling works best as a fixed sequence. First identify entities. Then list attributes. Then define relationships. Then decide the cardinality of those relationships. Finally, resolve - many-to-many relationships into join tables. The value of the workflow is not paperwork. It prevents you from jumping into tables too early and hiding structural mistakes inside SQL. + instruction: Data modeling works best as a fixed sequence. First identify entities. Then list attributes. Then define relationships. Then decide the cardinality of those relationships. Finally, resolve many-to-many relationships into join tables. The value of the workflow is not paperwork. It prevents you from jumping into tables too early and hiding structural mistakes inside SQL. instructionContent: - type: callout title: Sequence matters - body: >- - If you skip straight to table creation, you usually discover entity, relationship, and cardinality mistakes after code has already made them expensive. + body: If you skip straight to table creation, you usually discover entity, relationship, and cardinality mistakes after code has already made them expensive. problems: - id: process-p1 type: ordering @@ -889,9 +740,7 @@ concepts: - List attributes for each entity - Define relationships between entities correct: 1,3,4,0,2 - explanation: >- - The five steps in order: (1) Identify entities, (2) List attributes, (3) Define relationships, (4) Determine cardinality, (5) Resolve many-to-many. You must know your entities before - their attributes, and relationships before their cardinality. + explanation: 'The five steps in order: (1) Identify entities, (2) List attributes, (3) Define relationships, (4) Determine cardinality, (5) Resolve many-to-many. You must know your entities before their attributes, and relationships before their cardinality.' - id: process-p3 type: multiple_choice question: What is the main benefit of designing a data model before writing code or SQL? @@ -901,65 +750,48 @@ concepts: - It eliminates the need for a database entirely - It makes the system run faster at the hardware level correct: 1 - explanation: >- - Upfront data modeling produces a well-structured foundation. This leads to cleaner queries, fewer bugs, and a system that is easier to evolve as new features arrive. + explanation: Upfront data modeling produces a well-structured foundation. This leads to cleaner queries, fewer bugs, and a system that is easier to evolve as new features arrive. - id: process-p5 type: true_false question: It is fine to write SQL CREATE TABLE statements before identifying entities and their relationships, as long as you refactor later. correct: 'false' - explanation: >- - Jumping to tables before identifying entities, attributes, and relationships hides structural mistakes inside SQL that become expensive to fix. The five-step workflow exists to prevent - rework. If you answered true, the misconception is treating modeling as optional paperwork rather than a design step that prevents downstream bugs. + explanation: Jumping to tables before identifying entities, attributes, and relationships hides structural mistakes inside SQL that become expensive to fix. The five-step workflow exists to prevent rework. If you answered true, the misconception is treating modeling as optional paperwork rather than a design step that prevents downstream bugs. + keyPrerequisite: associative-entities - id: applying-the-workflow - instruction: >- - The five-step process becomes useful only when you can run it on a real system description. The goal is to move from vague product prose to concrete modeling choices. At each step, ask a - narrower question than the last: what things exist, what facts matter, how do they connect, how many of each connect, and which many-to-many pairings need their own entity? - workedExample: >- - Model a simple library system. Step 1 — Entities: Book, Member, Loan. Step 2 — Attributes: Book (isbn, title, author, published_year), Member (member_id, name, email, joined_date), Loan - (loan_id, borrowed_date, due_date, returned_date). Step 3 — Relationships: Members borrow Books via Loans. Step 4 — Cardinality: One Member has many Loans. One Book has many Loans over - time. Step 5 — Loan is the associative entity resolving the many-to-many between Member and Book. + instruction: 'The five-step process becomes useful only when you can run it on a real system description. The goal is to move from vague product prose to concrete modeling choices. At each step, ask a narrower question than the last: what things exist, what facts matter, how do they connect, how many of each connect, and which many-to-many pairings need their own entity?' + workedExample: 'Model a simple library system. Step 1 — Entities: Book, Member, Loan. Step 2 — Attributes: Book (isbn, title, author, published_year), Member (member_id, name, email, joined_date), Loan (loan_id, borrowed_date, due_date, returned_date). Step 3 — Relationships: Members borrow Books via Loans. Step 4 — Cardinality: One Member has many Loans. One Book has many Loans over time. Step 5 — Loan is the associative entity resolving the many-to-many between Member and Book.' problems: - id: process-p2 type: scenario - question: >- - A startup asks you to model their system: 'Users create Projects. Each Project has many Tasks. Users can be assigned to Tasks, and each Task can have multiple Users assigned.' You have - identified User, Project, and Task as entities. What is the next modeling decision you need to make? + question: 'A startup asks you to model their system: ''Users create Projects. Each Project has many Tasks. Users can be assigned to Tasks, and each Task can have multiple Users assigned.'' You have identified User, Project, and Task as entities. What is the next modeling decision you need to make?' options: - Choose a database vendor - Write SQL CREATE TABLE statements - Recognize that User-to-Task is many-to-many and create an associative entity (e.g., TaskAssignment) - Delete the Task entity since it is redundant with Project correct: 2 - explanation: >- - User-to-Task is many-to-many (one User has many Tasks, one Task has many Users). You need an associative entity like TaskAssignment with user_id, task_id, and potentially attributes like - assigned_date and role. This is step 5 of the data modeling process. + explanation: User-to-Task is many-to-many (one User has many Tasks, one Task has many Users). You need an associative entity like TaskAssignment with user_id, task_id, and potentially attributes like assigned_date and role. This is step 5 of the data modeling process. - id: process-p4 type: scenario - question: >- - You are modeling a subscription product. You have identified Customer and Plan. The business rule says one Customer can change Plans over time, and the team wants to keep started_at and - cancelled_at for each change. What is the next strong modeling move? + question: You are modeling a subscription product. You have identified Customer and Plan. The business rule says one Customer can change Plans over time, and the team wants to keep started_at and cancelled_at for each change. What is the next strong modeling move? options: - Put started_at and cancelled_at directly on Customer - Create a Subscription entity linking Customer and Plan - Delete Plan because the dates matter more than the plan itself - Skip the model and let the application code track history correct: 1 - explanation: >- - Once the relationship itself has history and dates, it deserves its own entity. Subscription captures the pairing between Customer and Plan over time, instead of forcing that history into - Customer. + explanation: Once the relationship itself has history and dates, it deserves its own entity. Subscription captures the pairing between Customer and Plan over time, instead of forcing that history into Customer. - id: process-p6 type: multiple_choice - question: >- - In the five-step modeling workflow, at which step do you decide that Student-to-Course needs a join table? + question: In the five-step modeling workflow, at which step do you decide that Student-to-Course needs a join table? options: - Step 1 — Identify entities - Step 3 — Define relationships - Step 4 — Determine cardinality - Step 5 — Resolve many-to-many into join tables correct: 3 - explanation: >- - The decision to create a join table happens at step 5, after you have already identified entities, listed attributes, defined relationships, and determined cardinality. You must know - the relationship is many-to-many (step 4) before resolving it (step 5). + explanation: The decision to create a join table happens at step 5, after you have already identified entities, listed attributes, defined relationships, and determined cardinality. You must know the relationship is many-to-many (step 4) before resolving it (step 5). + keyPrerequisite: data-modeling-process section: data-modeling-design - id: what-is-a-pipeline name: What Is a Data Pipeline? @@ -973,10 +805,7 @@ concepts: encompassing: [] knowledgePoints: - id: pipeline-definition-and-flow - instruction: >- - A data pipeline is a system that moves data from where it is produced to where it is needed, and often transforms it on the way. The usual stages are source, ingestion, storage, - transformation, and serving. Different tools may collapse or rename those stages, but the core idea stays the same: get data in, preserve it safely, shape it, and deliver it to someone who - can use it. + instruction: 'A data pipeline is a system that moves data from where it is produced to where it is needed, and often transforms it on the way. The usual stages are source, ingestion, storage, transformation, and serving. Different tools may collapse or rename those stages, but the core idea stays the same: get data in, preserve it safely, shape it, and deliver it to someone who can use it.' instructionContent: - type: image url: https://posthog.com/images/products/data-pipeline/data-pipeline.png @@ -993,9 +822,7 @@ concepts: - A programming language for writing SQL queries - A physical cable connecting two servers correct: 1 - explanation: >- - A data pipeline is a system that moves data from where it is produced (sources) to where it is needed (destinations), transforming it along the way. It is a logical system, not a - physical object or a language. + explanation: A data pipeline is a system that moves data from where it is produced (sources) to where it is needed (destinations), transforming it along the way. It is a logical system, not a physical object or a language. - id: pipeline-p2 type: ordering question: Place these data pipeline stages in the typical order. @@ -1005,26 +832,19 @@ concepts: - Serve/Analyze - Store correct: 1,3,0,2 - explanation: >- - The typical flow is: Ingest (collect from sources), Store (land somewhere durable), Transform (clean and process), Serve/Analyze (deliver to consumers). Data must be collected before - stored, stored before transformed, and transformed before served. + explanation: 'The typical flow is: Ingest (collect from sources), Store (land somewhere durable), Transform (clean and process), Serve/Analyze (deliver to consumers). Data must be collected before stored, stored before transformed, and transformed before served.' - id: pipeline-p5 type: true_false question: A data pipeline always includes all five stages (source, ingestion, storage, transformation, and serving) in every implementation. correct: 'false' - explanation: >- - Different tools may collapse, rename, or skip stages. A simple pipeline might go straight from ingestion to serving without a separate transformation step. The five stages are a mental - model, not a mandatory checklist for every pipeline. + explanation: Different tools may collapse, rename, or skip stages. A simple pipeline might go straight from ingestion to serving without a separate transformation step. The five stages are a mental model, not a mandatory checklist for every pipeline. + keyPrerequisite: data-modeling-process - id: pipeline-failure-points - instruction: >- - Once you know the stages, you can use them as a debugging map. Missing data often means the failure happened upstream. Stale data often means ingestion or transformation is delayed. Wrong - numbers often mean data arrived but the transformation or serving layer applied the wrong logic. A TAM does not need to memorize every vendor's internals to help. They need to ask which stage - first stopped behaving as expected. + instruction: Once you know the stages, you can use them as a debugging map. Missing data often means the failure happened upstream. Stale data often means ingestion or transformation is delayed. Wrong numbers often mean data arrived but the transformation or serving layer applied the wrong logic. A TAM does not need to memorize every vendor's internals to help. They need to ask which stage first stopped behaving as expected. instructionContent: - type: callout title: TAM lens - body: >- - When a customer says data is missing or stale, ask which stage failed first: source, ingestion, storage, transformation, or delivery. + body: 'When a customer says data is missing or stale, ask which stage failed first: source, ingestion, storage, transformation, or delivery.' problems: - id: pipeline-p3 type: true_false @@ -1033,29 +853,25 @@ concepts: explanation: Pipelines both move AND transform data. Transformation is a core stage — cleaning, filtering, aggregating, joining, and reshaping data as it flows from source to destination. - id: pipeline-p4 type: scenario - question: >- - Events are arriving at the platform, but the dashboard that depends on a daily aggregation has not updated since this morning. Which stage is the best first place to investigate? + question: Events are arriving at the platform, but the dashboard that depends on a daily aggregation has not updated since this morning. Which stage is the best first place to investigate? options: - The source system only - The transformation or serving step that builds the aggregate - The user's browser cache - The entity-relationship model correct: 1 - explanation: >- - If raw events are arriving but the derived dashboard is stale, the likely failure is downstream in transformation or serving, not in the original event source. + explanation: If raw events are arriving but the derived dashboard is stale, the likely failure is downstream in transformation or serving, not in the original event source. - id: pipeline-p6 type: multiple_choice - question: >- - A customer reports that their data appears in the warehouse but the numbers in their dashboard look wrong. Which pipeline stage should a TAM investigate first? + question: A customer reports that their data appears in the warehouse but the numbers in their dashboard look wrong. Which pipeline stage should a TAM investigate first? options: - The source system - The ingestion step - The transformation or serving layer - The network connection between systems correct: 2 - explanation: >- - If data arrived in the warehouse but the numbers are wrong, the issue is likely in transformation (bad logic) or serving (wrong query or aggregation). The source and ingestion steps - worked because the data did land. Start downstream and work backward. + explanation: If data arrived in the warehouse but the numbers are wrong, the issue is likely in transformation (bad logic) or serving (wrong query or aggregation). The source and ingestion steps worked because the data did land. Start downstream and work backward. + keyPrerequisite: what-is-a-pipeline section: pipeline-basics - id: sources-and-ingestion name: Sources & Ingestion Patterns @@ -1069,22 +885,18 @@ concepts: encompassing: [] knowledgePoints: - id: where-data-comes-from - instruction: >- + instruction: |- **Data sources** are any system that produces data your pipeline needs to consume. Common sources include: - **Application databases** (PostgreSQL, MySQL) — the operational databases your app writes to. **Event streams** (user clicks, pageviews, API calls) — real-time actions. **Third-party APIs** (Stripe for payments, Salesforce for CRM data). **Flat files** (CSVs, JSON exports). **Server logs** (access logs, error logs). - Sources differ in how they produce data. **Batch sources** produce data in chunks at intervals — a nightly database export, a weekly CSV from a vendor. **Streaming sources** produce data continuously in real-time — user clickstreams, IoT sensor readings, application event logs. - Batch is simpler to build and operate but introduces latency (data can be hours or days old). Streaming is faster (near real-time) but harder to build, debug, and operate. Most real-world pipelines use a mix of both. instructionContent: - type: callout title: Classification shortcut - body: >- - First ask what system emits the data. Then ask whether it arrives continuously or on a schedule. That gives you both the source type and the operating pattern. + body: First ask what system emits the data. Then ask whether it arrives continuously or on a schedule. That gives you both the source type and the operating pattern. problems: - id: sources-p1 type: multiple_choice @@ -1095,9 +907,7 @@ concepts: - Real-time user clickstream events from a web application - A monthly financial report correct: 2 - explanation: >- - User clickstream events are produced continuously in real-time as users interact with the application — this is a streaming source. The other options are all batch sources (periodic - exports at fixed intervals). + explanation: User clickstream events are produced continuously in real-time as users interact with the application — this is a streaming source. The other options are all batch sources (periodic exports at fixed intervals). - id: sources-p2 type: matching question: Match each data source to its category. @@ -1112,27 +922,20 @@ concepts: type: true_false question: Batch data sources always produce lower-quality data than streaming sources. correct: 'false' - explanation: >- - Data quality depends on the source system and pipeline design, not on whether it is batch or streaming. A well-designed nightly export can be higher quality than a poorly instrumented - real-time stream. The batch vs streaming distinction is about latency and operational complexity, not data quality. + explanation: Data quality depends on the source system and pipeline design, not on whether it is batch or streaming. A well-designed nightly export can be higher quality than a poorly instrumented real-time stream. The batch vs streaming distinction is about latency and operational complexity, not data quality. + keyPrerequisite: what-is-a-pipeline - id: ingestion-approaches - instruction: >- + instruction: |- **Ingestion** is the process of collecting data from sources into your pipeline. There are three main patterns. - **Pull-based ingestion:** the pipeline periodically requests data from the source. Example: a scheduled job that queries an API every hour. The pipeline controls the timing. - **Push-based ingestion:** the source sends data to the pipeline as it is produced. Example: a web application sends events to an analytics endpoint, or a webhook fires when a payment succeeds. The source controls the timing. - **Change Data Capture (CDC):** a specialized technique that watches a database's transaction log (WAL in PostgreSQL, binlog in MySQL) and captures every INSERT, UPDATE, and DELETE as it happens. CDC gives you streaming-like freshness from a batch source without querying the database directly — it reads the log instead. - Most product analytics tools (including PostHog) use push-based ingestion: your application sends events to their API. - workedExample: >- - Stripe sending a webhook when a payment succeeds is push-based ingestion. A cron job polling Salesforce every hour is pull-based ingestion. A connector reading PostgreSQL WAL records is CDC. - Same goal, different control point. + workedExample: Stripe sending a webhook when a payment succeeds is push-based ingestion. A cron job polling Salesforce every hour is pull-based ingestion. A connector reading PostgreSQL WAL records is CDC. Same goal, different control point. problems: - id: ingestion-p1 type: multiple_choice @@ -1146,25 +949,20 @@ concepts: explanation: In push-based ingestion, the source sends data to the pipeline. A web app posting events to an analytics API is a classic example. The source controls the timing, not the pipeline. - id: ingestion-p2 type: scenario - question: >- - Your company uses a third-party CRM (like Salesforce) that does not support webhooks. You need updated deal data in your warehouse every few hours. Which ingestion pattern is most - appropriate? + question: Your company uses a third-party CRM (like Salesforce) that does not support webhooks. You need updated deal data in your warehouse every few hours. Which ingestion pattern is most appropriate? options: - Push-based — have Salesforce send data to your pipeline - Pull-based — schedule your pipeline to query the Salesforce API periodically - Change Data Capture — read Salesforce's database logs - Manual — have someone export a CSV daily correct: 1 - explanation: >- - Without webhook support, you cannot use push-based ingestion. You do not have access to Salesforce's database logs for CDC. Pull-based is the right choice: schedule your pipeline to call - the Salesforce API every few hours to fetch updated records. + explanation: 'Without webhook support, you cannot use push-based ingestion. You do not have access to Salesforce''s database logs for CDC. Pull-based is the right choice: schedule your pipeline to call the Salesforce API every few hours to fetch updated records.' - id: ingestion-p3 type: true_false question: Change Data Capture (CDC) works by periodically querying a database for new rows. correct: 'false' - explanation: >- - CDC does NOT query the database. It reads the database's transaction log (WAL/binlog) to capture every INSERT, UPDATE, and DELETE as it happens. This avoids putting query load on the - production database and provides near real-time data. + explanation: CDC does NOT query the database. It reads the database's transaction log (WAL/binlog) to capture every INSERT, UPDATE, and DELETE as it happens. This avoids putting query load on the production database and provides near real-time data. + keyPrerequisite: sources-and-ingestion section: pipeline-basics - id: storage-layers name: Storage Layers — Where Data Lives @@ -1178,15 +976,11 @@ concepts: encompassing: [] knowledgePoints: - id: raw-lake-warehouse - instruction: >- - Data usually moves through layers as it becomes more useful. Raw storage or a landing zone is the first stop after ingestion. It keeps the original payload untouched so you can replay or - reprocess later. A data lake is cheap, flexible storage for large volumes of raw or semi-structured data. A data warehouse is optimized for analytical queries on structured tables. The same - data may move through all three layers, but each layer exists for a different reason. + instruction: Data usually moves through layers as it becomes more useful. Raw storage or a landing zone is the first stop after ingestion. It keeps the original payload untouched so you can replay or reprocess later. A data lake is cheap, flexible storage for large volumes of raw or semi-structured data. A data warehouse is optimized for analytical queries on structured tables. The same data may move through all three layers, but each layer exists for a different reason. instructionContent: - type: callout title: Same data, different jobs - body: >- - Raw storage protects recoverability, lakes protect cheap flexible retention, and warehouses protect query speed. + body: Raw storage protects recoverability, lakes protect cheap flexible retention, and warehouses protect query speed. problems: - id: storage-p1 type: multiple_choice @@ -1197,9 +991,7 @@ concepts: - It eliminates the need for a data warehouse - Raw storage automatically cleans and transforms data correct: 1 - explanation: >- - Raw storage is your safety net. By preserving the original data untouched, you can always go back and reprocess it if a transformation bug corrupts downstream data. Raw storage is not - fast to query — that is the warehouse's job. + explanation: Raw storage is your safety net. By preserving the original data untouched, you can always go back and reprocess it if a transformation bug corrupts downstream data. Raw storage is not fast to query — that is the warehouse's job. - id: storage-p2 type: matching question: Match each storage layer to its primary characteristic. @@ -1209,9 +1001,7 @@ concepts: - Data warehouse|Optimized for fast analytical queries - Landing zone|First place data lands after ingestion correct: 0,1,2,3 - explanation: >- - Raw storage and landing zone both describe the initial ingestion target (preserving original data). Data lakes prioritize cheap, flexible storage. Data warehouses prioritize fast - analytical queries with structured schemas. + explanation: Raw storage and landing zone both describe the initial ingestion target (preserving original data). Data lakes prioritize cheap, flexible storage. Data warehouses prioritize fast analytical queries with structured schemas. - id: storage-p5 type: multiple_choice question: Which storage layer is optimized for fast analytical queries on structured, schema-defined tables? @@ -1221,46 +1011,37 @@ concepts: - Data warehouse - Application database (OLTP) correct: 2 - explanation: >- - Data warehouses are built for analytical query speed on structured data. Raw storage preserves originals, lakes store cheap flexible data, and OLTP databases optimize for transactional - writes, not analytical reads. + explanation: Data warehouses are built for analytical query speed on structured data. Raw storage preserves originals, lakes store cheap flexible data, and OLTP databases optimize for transactional writes, not analytical reads. + keyPrerequisite: sources-and-ingestion - id: choosing-storage-layers - instruction: >- - Choosing the right layer depends on the job. Use raw storage when recoverability matters. Use a lake when you need cheap retention of varied file types. Use a warehouse when people need to - ask analytical questions quickly. The mistake is expecting one layer to optimize for every outcome at once. Cheap flexible storage is not automatically fast, and fast structured analytics is - not automatically the best place to keep every original payload forever. + instruction: Choosing the right layer depends on the job. Use raw storage when recoverability matters. Use a lake when you need cheap retention of varied file types. Use a warehouse when people need to ask analytical questions quickly. The mistake is expecting one layer to optimize for every outcome at once. Cheap flexible storage is not automatically fast, and fast structured analytics is not automatically the best place to keep every original payload forever. problems: - id: storage-p3 type: true_false question: A data warehouse is optimized for cheap storage of unstructured data like images and videos. correct: 'false' - explanation: >- - A data warehouse is optimized for fast analytical queries on structured data (tables with defined schemas). Cheap storage of unstructured data is the role of a data lake (like S3). - Warehouses trade storage cost for query speed. + explanation: A data warehouse is optimized for fast analytical queries on structured data (tables with defined schemas). Cheap storage of unstructured data is the role of a data lake (like S3). Warehouses trade storage cost for query speed. - id: storage-p4 type: scenario - question: >- - A transformation bug corrupted yesterday's aggregate tables. The team needs the original event payloads so they can rebuild the data correctly. Which storage layer is most important here? + question: A transformation bug corrupted yesterday's aggregate tables. The team needs the original event payloads so they can rebuild the data correctly. Which storage layer is most important here? options: - The BI dashboard cache - The raw landing zone - The semantic layer only - The metrics definition document correct: 1 - explanation: >- - The raw landing zone preserves the original data exactly as received. That is what lets the team rerun the downstream transformations after a bug. + explanation: The raw landing zone preserves the original data exactly as received. That is what lets the team rerun the downstream transformations after a bug. - id: storage-p6 type: scenario - question: >- - A team asks: 'Can we just put everything in our data warehouse and skip the raw layer and lake?' What is the strongest argument against this? + question: 'A team asks: ''Can we just put everything in our data warehouse and skip the raw layer and lake?'' What is the strongest argument against this?' options: - Warehouses cannot store JSON data - If a transformation bug corrupts warehouse data, you have no original copy to reprocess from - Warehouses are always more expensive than lakes - This approach violates database licensing rules correct: 1 - explanation: >- - Without a raw layer, you lose recoverability. If downstream transformation logic is wrong, you cannot replay the original data. The raw layer is your safety net, not redundant storage. + explanation: Without a raw layer, you lose recoverability. If downstream transformation logic is wrong, you cannot replay the original data. The raw layer is your safety net, not redundant storage. + keyPrerequisite: storage-layers section: pipeline-basics - id: transformation-etl-elt name: Transformation — ETL vs ELT @@ -1274,16 +1055,13 @@ concepts: encompassing: [] knowledgePoints: - id: what-transformation-does - instruction: >- + instruction: |- **Transformation** is the stage where raw data becomes usable data. It is where you clean, reshape, enrich, and aggregate. Common operations include: - **Cleaning** — removing duplicates, fixing null values, correcting data types. **Filtering** — dropping irrelevant records. **Joining** — combining data from multiple sources, such as enriching events with user attributes. **Aggregating** — summing, counting, averaging to turn raw events into metrics. **Normalizing** — standardizing formats like dates, currencies, or country codes. - For example, raw event data might look like individual "user_clicked_button" records with timestamps. After transformation, you might have an aggregated table of "daily_clicks_per_user" that is much easier to query. - Transformation is where **business logic** lives. The rules about what counts as an "active user" or how "revenue" is calculated are encoded in transformation steps. instructionContent: - type: image @@ -1293,8 +1071,7 @@ concepts: width: 960 - type: callout title: Important distinction - body: >- - Instrumentation creates raw facts. Transformation turns those facts into business definitions like active users, MRR, or qualified accounts. + body: Instrumentation creates raw facts. Transformation turns those facts into business definitions like active users, MRR, or qualified accounts. problems: - id: transform-p1 type: multiple_choice @@ -1305,9 +1082,7 @@ concepts: - Collecting data from a third-party API - Joining event data with user profile data correct: 2 - explanation: >- - Collecting data from an API is ingestion, not transformation. Transformation operates on data already in the pipeline — deduplication, aggregation, and joining are all transformation - operations. + explanation: Collecting data from an API is ingestion, not transformation. Transformation operates on data already in the pipeline — deduplication, aggregation, and joining are all transformation operations. - id: transform-p2 type: multiple_choice question: The transformation stage is where what kind of logic is encoded — rules like what counts as an active user or how revenue is calculated? @@ -1317,37 +1092,28 @@ concepts: - authentication logic - transport logic correct: 0 - explanation: >- - Business logic lives in the transformation layer. Definitions like 'active user = logged in within last 30 days' or 'MRR = sum of all active subscription amounts' are transformation - rules that turn raw data into meaningful metrics. + explanation: Business logic lives in the transformation layer. Definitions like 'active user = logged in within last 30 days' or 'MRR = sum of all active subscription amounts' are transformation rules that turn raw data into meaningful metrics. - id: transform-p3 type: scenario - question: >- - Two teams at the same company disagree on the definition of 'active user.' The marketing team counts anyone who logged in, while the product team counts anyone who performed a core action. - Where should this definition be codified? + question: Two teams at the same company disagree on the definition of 'active user.' The marketing team counts anyone who logged in, while the product team counts anyone who performed a core action. Where should this definition be codified? options: - In the application code - In the transformation layer as a documented business rule - In the BI dashboard configuration - In the source database schema correct: 1 - explanation: >- - Business definitions like 'active user' belong in the transformation layer where raw data becomes metrics. This is where business logic lives. Codifying it there ensures all downstream - consumers use the same definition instead of each team computing their own version. + explanation: Business definitions like 'active user' belong in the transformation layer where raw data becomes metrics. This is where business logic lives. Codifying it there ensures all downstream consumers use the same definition instead of each team computing their own version. + keyPrerequisite: storage-layers - id: etl-vs-elt - instruction: >- + instruction: |- There are two major approaches to when transformation happens. - **ETL (Extract, Transform, Load):** data is extracted from sources, transformed in a separate processing system, and then loaded into the destination warehouse. This was the traditional approach when storage was expensive — you only stored the clean, transformed data. - **ELT (Extract, Load, Transform):** data is extracted from sources, loaded raw into the destination, and then transformed inside the warehouse using SQL or the warehouse's own compute engine. This is the modern approach, enabled by cheap cloud storage (S3, GCS). - The advantage of ELT is **flexibility:** if your business logic changes, you can re-transform from the raw data without re-ingesting. You also preserve the original data for auditing. - Most modern analytics systems, including PostHog, use an ELT-like pattern: events are ingested raw, stored in ClickHouse, and then queried and transformed at read time using HogQL. problems: - id: etl-elt-p1 @@ -1359,16 +1125,12 @@ concepts: - ETL is for batch data; ELT is for streaming data - ETL is open source; ELT is proprietary correct: 1 - explanation: >- - The difference is when transformation happens. ETL transforms before loading (data enters the warehouse already clean). ELT loads raw data first and transforms inside the warehouse. ELT - is the modern approach enabled by cheap storage. + explanation: The difference is when transformation happens. ETL transforms before loading (data enters the warehouse already clean). ELT loads raw data first and transforms inside the warehouse. ELT is the modern approach enabled by cheap storage. - id: etl-elt-p2 type: true_false question: ELT became practical because cloud storage costs dropped, making it affordable to store raw data and transform later. correct: 'true' - explanation: >- - Cheap cloud storage (S3, GCS, Azure Blob) is the key enabler of ELT. When storage was expensive, you had to transform before loading to minimize what you stored (ETL). Now you can afford - to keep everything raw and transform on demand. + explanation: Cheap cloud storage (S3, GCS, Azure Blob) is the key enabler of ELT. When storage was expensive, you had to transform before loading to minimize what you stored (ETL). Now you can afford to keep everything raw and transform on demand. - id: etl-elt-p3 type: scenario question: Your company realizes their definition of 'active user' was wrong for the past 6 months. Under which approach can you fix the historical data without re-ingesting from the source? @@ -1378,9 +1140,8 @@ concepts: - Neither — you must always re-ingest from the source - Both — there is no difference for this scenario correct: 1 - explanation: >- - ELT preserves the raw data in the warehouse. When business logic changes, you can re-run transformations on the existing raw data. With ETL, raw data is discarded after transformation, - so you would need to re-ingest from the source (if it is even still available). + explanation: ELT preserves the raw data in the warehouse. When business logic changes, you can re-run transformations on the existing raw data. With ETL, raw data is discarded after transformation, so you would need to re-ingest from the source (if it is even still available). + keyPrerequisite: transformation-etl-elt section: pipeline-architecture - id: orchestration-and-serving name: Orchestration & Serving Data @@ -1394,38 +1155,31 @@ concepts: encompassing: [] knowledgePoints: - id: workflow-orchestration - instruction: >- + instruction: |- Pipelines have multiple steps that must run in a specific order with specific dependencies. **Orchestration** is the coordination of these steps. - An orchestrator schedules and manages execution: extract data from source A, then transform it, then load it, then refresh the dashboard. If the extract step fails, the transform step should not run. - Tasks are organized as a **DAG — a Directed Acyclic Graph**. "Directed" means edges have a direction (step A must complete before step B). "Acyclic" means there are no loops (step B cannot depend on step C which depends on step B). - The orchestrator handles four jobs: **scheduling** (run this pipeline every hour), **dependency management** (only run step B after step A succeeds), **retries** (if a step fails, retry it), and **alerting** (notify the team if a pipeline fails). - Common orchestration tools include Apache Airflow, Dagster, Prefect, and dbt for transformation-specific orchestration. instructionContent: - type: callout title: Orchestration is control flow - body: >- - The orchestrator is not the data itself. It is the system that decides what runs next, what retries, and what should stop when an upstream step fails. + body: The orchestrator is not the data itself. It is the system that decides what runs next, what retries, and what should stop when an upstream step fails. problems: - id: orch-p1 type: multiple_choice - question: >- - A data pipeline has four stages: Extract → Validate → Transform → Load. The Transform stage needs output from both Extract and Validate. Which property of a DAG makes this dependency structure possible? + question: 'A data pipeline has four stages: Extract → Validate → Transform → Load. The Transform stage needs output from both Extract and Validate. Which property of a DAG makes this dependency structure possible?' options: - DAGs allow circular dependencies so Transform can wait for both inputs - DAGs are directed and acyclic — each stage runs only after all its upstream dependencies complete, and no stage can depend on itself or create a loop - DAGs process all stages simultaneously in parallel - DAGs require each stage to have exactly one input and one output correct: 1 - explanation: >- - A Directed Acyclic Graph (DAG) models pipeline stages as nodes with directed edges showing dependencies. 'Directed' means edges have a direction (Extract → Transform, not the reverse). 'Acyclic' means no loops — you can't have Transform depend on Load which depends on Transform. This structure lets orchestrators like Airflow or Dagster determine execution order: run Extract and Validate first (no dependencies), then Transform (waits for both), then Load (waits for Transform). + explanation: 'A Directed Acyclic Graph (DAG) models pipeline stages as nodes with directed edges showing dependencies. ''Directed'' means edges have a direction (Extract → Transform, not the reverse). ''Acyclic'' means no loops — you can''t have Transform depend on Load which depends on Transform. This structure lets orchestrators like Airflow or Dagster determine execution order: run Extract and Validate first (no dependencies), then Transform (waits for both), then Load (waits for Transform).' difficulty: 3 - id: orch-p2 type: true_false @@ -1434,32 +1188,25 @@ concepts: explanation: A DAG is acyclic — no circular dependencies are allowed. If B depends on C and C depends on B, neither can ever start. This is a cycle, which the orchestrator would reject. - id: orch-p3 type: scenario - question: >- - A pipeline has three steps: Extract from API, Transform data, Load into warehouse. The Extract step fails due to an API timeout. What should a well-configured orchestrator do? + question: 'A pipeline has three steps: Extract from API, Transform data, Load into warehouse. The Extract step fails due to an API timeout. What should a well-configured orchestrator do?' options: - Run Transform and Load anyway with whatever data is available - Skip all remaining steps, retry Extract according to its retry policy, and alert the team if retries are exhausted - Delete the partially extracted data and start over tomorrow - Ignore the failure and mark the run as successful correct: 1 - explanation: >- - A good orchestrator respects dependencies: if Extract fails, Transform should not run because it has no input. The orchestrator retries the failed step and alerts the team if retries - are exhausted. Running downstream steps on incomplete data produces silently wrong results. + explanation: 'A good orchestrator respects dependencies: if Extract fails, Transform should not run because it has no input. The orchestrator retries the failed step and alerts the team if retries are exhausted. Running downstream steps on incomplete data produces silently wrong results.' + keyPrerequisite: transformation-etl-elt - id: serving-data - instruction: >- + instruction: |- Once data is processed, it must be delivered to the people and systems that need it. This is the **serving layer**. - **Common consumers:** BI dashboards (Looker, Metabase, Grafana) for business metrics and KPIs. Data scientists and ML engineers who need clean datasets for model training. Product analytics tools for understanding user behavior. Internal applications for reporting, billing, or customer-facing features. - **Common serving patterns:** direct warehouse access (users query the warehouse with SQL), semantic or metrics layers (a shared definition of metrics that dashboards and tools can reference), APIs (REST or GraphQL endpoints that serve processed data to applications), and cached materialized views (pre-computed query results for frequently accessed data). - The choice of serving layer depends on the consumer. Analysts want SQL access. Product managers want dashboards. Applications want APIs. - workedExample: >- - One warehouse can serve three audiences at once: analysts query it directly in SQL, executives see KPIs through a BI dashboard, and the product surface calls an API backed by curated - warehouse tables. The serving pattern changes with the consumer, not with the raw data itself. + workedExample: 'One warehouse can serve three audiences at once: analysts query it directly in SQL, executives see KPIs through a BI dashboard, and the product surface calls an API backed by curated warehouse tables. The serving pattern changes with the consumer, not with the raw data itself.' problems: - id: serving-p1 type: multiple_choice @@ -1470,9 +1217,7 @@ concepts: - A raw data dump to their email - An API endpoint returning JSON correct: 1 - explanation: >- - BI dashboards are designed for non-technical consumers who need visual, regularly updated KPI views. Direct SQL access suits analysts. APIs suit applications. Raw data dumps are not - user-friendly. + explanation: BI dashboards are designed for non-technical consumers who need visual, regularly updated KPI views. Direct SQL access suits analysts. APIs suit applications. Raw data dumps are not user-friendly. - id: serving-p2 type: matching question: Match each data consumer to their ideal serving pattern. @@ -1487,9 +1232,8 @@ concepts: type: true_false question: The best serving pattern is always direct SQL access to the warehouse because it is the most flexible. correct: 'false' - explanation: >- - The best serving pattern depends on the consumer. Analysts benefit from SQL access, but product managers need dashboards, and applications need APIs. Flexibility for one consumer does - not mean it is the best choice for all consumers. + explanation: The best serving pattern depends on the consumer. Analysts benefit from SQL access, but product managers need dashboards, and applications need APIs. Flexibility for one consumer does not mean it is the best choice for all consumers. + keyPrerequisite: orchestration-and-serving section: pipeline-architecture - id: pipeline-tradeoffs name: Pipeline Tradeoffs — Latency, Cost, Complexity @@ -1503,9 +1247,7 @@ concepts: encompassing: [] knowledgePoints: - id: three-tensions - instruction: >- - Every pipeline design pulls on three tensions at once: latency, cost, and complexity. Lower latency usually means more infrastructure and more operational burden. Simpler batch systems are - cheaper and easier to debug, but the data is less fresh. The right question is not "can we make this real time?" It is "what freshness does this use case actually need?" + instruction: 'Every pipeline design pulls on three tensions at once: latency, cost, and complexity. Lower latency usually means more infrastructure and more operational burden. Simpler batch systems are cheaper and easier to debug, but the data is less fresh. The right question is not "can we make this real time?" It is "what freshness does this use case actually need?"' problems: - id: tradeoffs-p1 type: multiple_choice @@ -1516,72 +1258,56 @@ concepts: - Streaming offers lower latency but higher cost and complexity compared to batch - There is no meaningful difference between batch and streaming correct: 2 - explanation: >- - Streaming delivers data faster (lower latency) but costs more to build and operate (higher cost and complexity). Batch is simpler and cheaper but data is less fresh. The right choice - depends on your requirements. + explanation: Streaming delivers data faster (lower latency) but costs more to build and operate (higher cost and complexity). Batch is simpler and cheaper but data is less fresh. The right choice depends on your requirements. - id: tradeoffs-p3 type: true_false question: For most analytics use cases, real-time data freshness (sub-second latency) is required. correct: 'false' - explanation: >- - Most analytics questions are fine with minutes-to-hours of latency. Real-time should be chosen for a demonstrated need, not as a default badge of sophistication. + explanation: Most analytics questions are fine with minutes-to-hours of latency. Real-time should be chosen for a demonstrated need, not as a default badge of sophistication. - id: tradeoffs-p5 type: scenario - question: >- - A team wants to build a real-time streaming pipeline for a weekly executive summary report. What is the main concern with this approach? + question: A team wants to build a real-time streaming pipeline for a weekly executive summary report. What is the main concern with this approach? options: - Streaming pipelines cannot produce summary reports - The added cost and complexity of streaming is not justified when the data only needs to be fresh once a week - Weekly reports require a data lake, not a stream - Real-time pipelines do not support aggregation correct: 1 - explanation: >- - The right question is 'what freshness does this use case actually need?' A weekly report needs weekly freshness, not sub-second latency. Building a streaming pipeline for this use - case adds unnecessary cost and complexity. Batch is the better fit. + explanation: The right question is 'what freshness does this use case actually need?' A weekly report needs weekly freshness, not sub-second latency. Building a streaming pipeline for this use case adds unnecessary cost and complexity. Batch is the better fit. + keyPrerequisite: orchestration-and-serving - id: operational-safety - instruction: >- - Once a pipeline is in production, two safety requirements matter constantly. Idempotency means the pipeline can be rerun without producing duplicate or conflicting results. Monitoring means - you notice failures, delays, null spikes, schema changes, and suspicious row counts before customers do. These are not optional polish items. They are what make a pipeline survivable in the - real world. + instruction: Once a pipeline is in production, two safety requirements matter constantly. Idempotency means the pipeline can be rerun without producing duplicate or conflicting results. Monitoring means you notice failures, delays, null spikes, schema changes, and suspicious row counts before customers do. These are not optional polish items. They are what make a pipeline survivable in the real world. instructionContent: - type: callout title: Production rule - body: >- - A pipeline that cannot be rerun safely and cannot alert on bad output will eventually fail in a way that is expensive to untangle. + body: A pipeline that cannot be rerun safely and cannot alert on bad output will eventually fail in a way that is expensive to untangle. problems: - id: tradeoffs-p2 type: scenario - question: >- - Your pipeline occasionally fails halfway through processing. When restarted, it creates duplicate rows in the warehouse. A colleague suggests making the pipeline idempotent. What does - this mean? + question: Your pipeline occasionally fails halfway through processing. When restarted, it creates duplicate rows in the warehouse. A colleague suggests making the pipeline idempotent. What does this mean? options: - The pipeline should run faster to avoid failures - The pipeline should be safe to rerun without creating duplicate data - The pipeline should skip failed records and continue - The pipeline should send an alert when it fails correct: 1 - explanation: >- - Idempotency means the pipeline produces the same result whether it runs once or multiple times. If restarted after a failure, it should not create duplicates. Techniques include upserts - (INSERT ... ON CONFLICT UPDATE) and deduplication checks. + explanation: Idempotency means the pipeline produces the same result whether it runs once or multiple times. If restarted after a failure, it should not create duplicates. Techniques include upserts (INSERT ... ON CONFLICT UPDATE) and deduplication checks. - id: tradeoffs-p4 type: scenario - question: >- - A daily pipeline still runs, but today's row count is 90% lower than normal because an upstream schema change dropped a key field. Which capability would have caught this fastest? + question: A daily pipeline still runs, but today's row count is 90% lower than normal because an upstream schema change dropped a key field. Which capability would have caught this fastest? options: - Lower latency infrastructure - Monitoring on row counts and schema expectations - A different primary key design - Moving the data to a lake instead of a warehouse correct: 1 - explanation: >- - This is exactly what monitoring is for. Healthy production pipelines watch both failures and suspicious outputs so teams can catch silent bad data before users trust it. + explanation: This is exactly what monitoring is for. Healthy production pipelines watch both failures and suspicious outputs so teams can catch silent bad data before users trust it. - id: tradeoffs-p6 type: true_false question: An idempotent pipeline produces different results when rerun multiple times on the same input data. correct: 'false' - explanation: >- - Idempotent means the pipeline produces the same result whether it runs once or many times on the same input. If rerunning creates duplicates or different outputs, the pipeline is not - idempotent, which makes recovery from failures risky. + explanation: Idempotent means the pipeline produces the same result whether it runs once or many times on the same input. If rerunning creates duplicates or different outputs, the pipeline is not idempotent, which makes recovery from failures risky. + keyPrerequisite: pipeline-tradeoffs section: pipeline-architecture - id: ph-events name: PostHog Events — The Atomic Unit @@ -1598,13 +1324,11 @@ concepts: weight: 0.35 knowledgePoints: - id: what-is-a-posthog-event - instruction: >- + instruction: |- An **event** is the atomic unit of data in PostHog: one record of something that happened at a specific moment. Every event answers four questions: - **What happened:** the event name. **When did it happen:** the timestamp. **Who or which device did it:** the distinct_id. **What extra context came with it:** the properties object. - If one of those pieces is wrong or missing, PostHog can still ingest the record, but the downstream analysis gets weaker because the fact is harder to group, filter, or attribute correctly. instructionContent: - type: link @@ -1616,16 +1340,11 @@ concepts: alt: PostHog product analytics interface built on event data caption: The UI is downstream of the event model. Every chart here starts from captured events. width: 960 - workedExample: >- - A user visits your pricing page. PostHog's JS SDK automatically captures a '$pageview' event. The event looks like this internally: event name = '$pageview', timestamp = - '2025-01-15T14:32:00Z', distinct_id = '018d4f2a-random-uuid', properties = { '$current_url': '/pricing', '$browser': 'Chrome', '$os': 'Mac OS X', '$device_type': - 'Desktop', '$referrer': 'google', '$referring_domain': 'google.com' }. Every one of these properties was set automatically by the SDK — the developer did not write any code - beyond initializing PostHog. + workedExample: 'A user visits your pricing page. PostHog''s JS SDK automatically captures a ''$pageview'' event. The event looks like this internally: event name = ''$pageview'', timestamp = ''2025-01-15T14:32:00Z'', distinct_id = ''018d4f2a-random-uuid'', properties = { ''$current_url'': ''/pricing'', ''$browser'': ''Chrome'', ''$os'': ''Mac OS X'', ''$device_type'': ''Desktop'', ''$referrer'': ''google'', ''$referring_domain'': ''google.com'' }. Every one of these properties was set automatically by the SDK — the developer did not write any code beyond initializing PostHog.' workedExampleContent: - type: callout title: Coaching angle - body: >- - When a customer says 'PostHog missed the user,' inspect the event first. Event name, timestamp, distinct_id, and properties usually reveal the real issue. + body: When a customer says 'PostHog missed the user,' inspect the event first. Event name, timestamp, distinct_id, and properties usually reveal the real issue. problems: - id: ph-events-p1 type: multiple_choice @@ -1636,9 +1355,7 @@ concepts: - Source, destination, payload, and status code - User ID, session ID, page URL, and browser correct: 1 - explanation: >- - The mistake to avoid is swapping in examples like browser, URL, or session ID for the real event shape. Those may appear as properties, but the core event record is name, timestamp, - distinct_id, and properties. + explanation: The mistake to avoid is swapping in examples like browser, URL, or session ID for the real event shape. Those may appear as properties, but the core event record is name, timestamp, distinct_id, and properties. - id: ph-events-p4 type: multiple_choice question: In PostHog's data model, which entity is the central building block that all other entities relate to? @@ -1648,30 +1365,24 @@ concepts: - Event - Action correct: 2 - explanation: >- - If you picked Person or Session, you are treating a derived layer as the raw fact. Event is the base record. Persons, sessions, actions, and groups are all built on top of event data. + explanation: If you picked Person or Session, you are treating a derived layer as the raw fact. Event is the base record. Persons, sessions, actions, and groups are all built on top of event data. - id: ph-events-p5 type: scenario - question: >- - A customer reports that some events in PostHog are missing the distinct_id field. They captured the events using a custom script that sends raw JSON to the capture API. What is the most - likely cause of the problem? + question: A customer reports that some events in PostHog are missing the distinct_id field. They captured the events using a custom script that sends raw JSON to the capture API. What is the most likely cause of the problem? options: - PostHog silently drops events without distinct_id - The capture API requires distinct_id but the script is not including it in the payload - distinct_id is optional and only needed for identified events - The events are stored but hidden in the UI correct: 1 - explanation: >- - Every PostHog event needs a distinct_id to answer 'who or which device did this.' The capture API expects it in the payload. If the custom script omits it, the event either fails - validation or gets assigned a default that makes downstream analysis unreliable. Always check the four required components: event name, timestamp, distinct_id, and properties. + explanation: 'Every PostHog event needs a distinct_id to answer ''who or which device did this.'' The capture API expects it in the payload. If the custom script omits it, the event either fails validation or gets assigned a default that makes downstream analysis unreliable. Always check the four required components: event name, timestamp, distinct_id, and properties.' + keyPrerequisite: entities - id: immutable-facts-and-default-events - instruction: >- + instruction: |- Events are **immutable facts** in PostHog. Once captured, they are records of what the system believed happened at that moment, so you do not edit them later the way you would update a person or company profile. - PostHog also ships with **default events**, usually prefixed with `$`, such as `$pageview`, `$pageleave`, `$autocapture`, `$identify`, and `$set`. - The useful distinction: default events tell you what the SDK already records for you, while immutability tells you how to react when the instrumentation was wrong. instructionContent: - type: link @@ -1683,40 +1394,30 @@ concepts: type: true_false question: PostHog events can be updated after they are captured to correct mistakes. correct: 'false' - explanation: >- - The common misconception is treating events like mutable profile rows. When event tracking is wrong, the fix is to correct the instrumentation going forward or adjust analysis logic, not - to rewrite yesterday's event payloads. + explanation: The common misconception is treating events like mutable profile rows. When event tracking is wrong, the fix is to correct the instrumentation going forward or adjust analysis logic, not to rewrite yesterday's event payloads. - id: ph-events-p3 type: multiple_choice question: Events with names prefixed by which symbol are PostHog defaults, automatically captured by the SDKs? options: - - "$" - - "#" - - "@" - - "_" + - $ + - '#' + - '@' + - _ correct: 0 - explanation: >- - The `$` prefix marks PostHog-defined default events. If you chose another symbol, you likely remembered a naming style rather than the actual SDK convention. Custom business events - normally do not use the `$` prefix. + explanation: The `$` prefix marks PostHog-defined default events. If you chose another symbol, you likely remembered a naming style rather than the actual SDK convention. Custom business events normally do not use the `$` prefix. - id: ph-events-p6 type: scenario - question: >- - A customer realizes they misspelled a custom event name as 'singup_completed' instead of 'signup_completed' for the past two weeks. They ask you to fix the historical events. What do you - tell them? + question: A customer realizes they misspelled a custom event name as 'singup_completed' instead of 'signup_completed' for the past two weeks. They ask you to fix the historical events. What do you tell them? options: - You can bulk-edit event names in the PostHog UI - Events are immutable — fix the instrumentation going forward and use an action to group both spellings for analysis - Delete the misspelled events and re-ingest them with the correct name - PostHog automatically corrects common typos correct: 1 - explanation: >- - PostHog events are immutable facts. Once captured, they cannot be edited. The practical fix is to correct the instrumentation code so future events have the right name, then create - an action that matches both spellings so historical analysis is not disrupted. + explanation: PostHog events are immutable facts. Once captured, they cannot be edited. The practical fix is to correct the instrumentation code so future events have the right name, then create an action that matches both spellings so historical analysis is not disrupted. + keyPrerequisite: ph-events - id: custom-vs-autocapture - instruction: >- - PostHog gives you two capture patterns. Autocapture records UI interactions automatically, which is useful for fast discovery and exploratory analysis. Custom events are emitted explicitly in - your code and describe business actions in stable terms such as `signup_completed` or `subscription_upgraded`. The key judgment is knowing when to promote a behavior from convenient - autocapture into intentional instrumentation. If the metric matters to the business, tie it to the business fact rather than to the text, selector, or layout of a button. + instruction: PostHog gives you two capture patterns. Autocapture records UI interactions automatically, which is useful for fast discovery and exploratory analysis. Custom events are emitted explicitly in your code and describe business actions in stable terms such as `signup_completed` or `subscription_upgraded`. The key judgment is knowing when to promote a behavior from convenient autocapture into intentional instrumentation. If the metric matters to the business, tie it to the business fact rather than to the text, selector, or layout of a button. instructionContent: - type: link url: https://posthog.com/docs/product-analytics/capture-events @@ -1732,30 +1433,23 @@ concepts: - Autocapture is too expensive to use - Autocapture only works on mobile apps correct: 1 - explanation: >- - Autocapture identifies elements by their text, CSS classes, and position. When a button changes from 'Sign Up' to 'Get Started,' the autocapture event properties change too, breaking any - analysis that relied on the old text. Custom events avoid this because you control the event name. + explanation: Autocapture identifies elements by their text, CSS classes, and position. When a button changes from 'Sign Up' to 'Get Started,' the autocapture event properties change too, breaking any analysis that relied on the old text. Custom events avoid this because you control the event name. - id: ph-autocapture-p2 type: scenario - question: >- - A customer wants to track how many users complete their checkout flow. They currently rely on autocapture to detect clicks on the 'Place Order' button. Their frontend team is about to - redesign the checkout page. What do you recommend? + question: A customer wants to track how many users complete their checkout flow. They currently rely on autocapture to detect clicks on the 'Place Order' button. Their frontend team is about to redesign the checkout page. What do you recommend? options: - Keep using autocapture — it will adapt to the new design automatically - Add a custom event like posthog.capture('order_completed') that fires on successful checkout, independent of UI elements - Disable autocapture entirely to save costs - Ask the frontend team not to change the button text correct: 1 - explanation: >- - A custom event like 'order_completed' is tied to the business action (a successful checkout), not the UI element (a button with specific text). It will survive any redesign. Autocapture - is fragile for critical metrics because it depends on element properties that change with UI updates. + explanation: A custom event like 'order_completed' is tied to the business action (a successful checkout), not the UI element (a button with specific text). It will survive any redesign. Autocapture is fragile for critical metrics because it depends on element properties that change with UI updates. - id: ph-autocapture-p3 type: true_false question: Autocapture and custom events are mutually exclusive — you must choose one or the other. correct: 'false' - explanation: >- - You can (and should) use both. Autocapture gives you broad coverage for exploration and discovery. Custom events give you reliable, stable tracking for critical business actions. They - complement each other. + explanation: You can (and should) use both. Autocapture gives you broad coverage for exploration and discovery. Custom events give you reliable, stable tracking for critical business actions. They complement each other. + keyPrerequisite: ph-events section: posthog-data-model - id: ph-event-properties name: Event Properties — Metadata on Events @@ -1770,16 +1464,13 @@ concepts: encompassing: [] knowledgePoints: - id: default-vs-custom-properties - instruction: >- + instruction: |- Every PostHog event carries **properties** — a JSON object of key-value pairs that provide context about the event. Properties come in two flavors. - **Default properties** are set automatically by the SDK with no code from you. These include: `$browser` (Chrome, Firefox, Safari), `$os` (Mac OS X, Windows, iOS), `$current_url` (the page URL when the event fired), `$referrer` (the referring page), `$device_type` (Desktop, Mobile, Tablet), `$screen_height` and `$screen_width`, `$timestamp`, and `$lib` (which SDK sent it). - **Custom properties** are ones you define when capturing events, for example passing plan, amount, and currency alongside a purchase event. Custom properties let you attach business context that the SDK cannot infer. - Properties are the backbone of analysis — you use them to filter events ("show me purchases where plan = pro"), break down metrics ("pageviews by browser"), and segment users. Without properties, events would be bare "something happened" records with no useful context. instructionContent: - type: link @@ -1796,9 +1487,7 @@ concepts: - $browser - signup_source correct: 2 - explanation: >- - $browser is automatically set by the SDK based on the user's browser. 'plan', 'amount', and 'signup_source' are custom properties that a developer would need to explicitly include when - capturing events. + explanation: $browser is automatically set by the SDK based on the user's browser. 'plan', 'amount', and 'signup_source' are custom properties that a developer would need to explicitly include when capturing events. - id: ph-props-p2 type: multiple_choice question: To filter insights by the page where an event occurred, which default property should you use? @@ -1813,45 +1502,36 @@ concepts: type: true_false question: Custom event properties must be defined in the PostHog UI before they can be used in code. correct: 'false' - explanation: >- - Custom properties are schemaless — you can send any key-value pair in your capture call and PostHog will accept it. No pre-registration or UI configuration is needed. Properties appear - in the UI automatically after the first event containing them is captured. + explanation: Custom properties are schemaless — you can send any key-value pair in your capture call and PostHog will accept it. No pre-registration or UI configuration is needed. Properties appear in the UI automatically after the first event containing them is captured. - id: ph-props-p4 type: scenario - question: >- - A customer wants to track which pricing plan a user is on when they perform any action in the app. They're debating two approaches: (A) send `plan: 'pro'` as an event property on every capture() call, or (B) set it once as a person property using $set. Which approach is better and why? + question: 'A customer wants to track which pricing plan a user is on when they perform any action in the app. They''re debating two approaches: (A) send `plan: ''pro''` as an event property on every capture() call, or (B) set it once as a person property using $set. Which approach is better and why?' options: - Approach A — event properties are more reliable than person properties - Approach B — the plan is an attribute of the user, not the event. Setting it as a person property with $set means it's always available on every event via person property filters without needing to send it repeatedly - Both are equally valid — it's a matter of preference - Neither — plan should be tracked as a group property on the company correct: 1 - explanation: >- - Properties that describe the user (plan, role, company) belong as person properties. Properties that describe the specific action (button clicked, page URL, amount) belong as event properties. Using $set for `plan` means: (1) you set it once on login/plan change, (2) it's automatically available for filtering on all past and future events via person property filters, (3) you don't bloat every event payload. Approach A would work but creates redundant data and risks inconsistency if a capture() call forgets to include it. + explanation: 'Properties that describe the user (plan, role, company) belong as person properties. Properties that describe the specific action (button clicked, page URL, amount) belong as event properties. Using $set for `plan` means: (1) you set it once on login/plan change, (2) it''s automatically available for filtering on all past and future events via person property filters, (3) you don''t bloat every event payload. Approach A would work but creates redundant data and risks inconsistency if a capture() call forgets to include it.' difficulty: 4 + keyPrerequisite: ph-events - id: event-vs-person-properties - instruction: >- + instruction: |- PostHog has two types of properties that are often confused: **event properties** and **person properties**. - **Event properties** are attached to a specific event and describe the context of that action at that moment. They are per-event — each event carries its own snapshot. Example: `$current_url`, `button_text`, `cart_value`. If a user visits page A, the event has $current_url = /page-a. If they visit page B, that event has $current_url = /page-b. - **Person properties** are stored on the person profile and describe the user across all their events. They persist and apply globally. Example: `email`, `plan`, `company_name`. A user on the "pro" plan has that property on their profile regardless of which event you are looking at. - **The rule of thumb:** "Is this fact about the user generally, across all events?" Use a person property. "Is this fact about this specific action, right now?" Use an event property. - Event properties do not retroactively change — each event is an immutable snapshot. Person properties are mutable — when you change someone's plan from "free" to "pro," the person property updates immediately. instructionContent: - type: link url: https://posthog.com/docs/product-analytics/person-properties title: Person properties docs description: Use this when a learner needs the official rule set for persistent user attributes. - workedExample: >- - A user clicks "Upgrade" on `/pricing` while still on the free plan. The page URL belongs on the event because it describes that click. The plan belongs on the person because it describes the - user across many events. Mixing them up either loses history or stores duplicate user facts on every event. + workedExample: A user clicks "Upgrade" on `/pricing` while still on the free plan. The page URL belongs on the event because it describes that click. The plan belongs on the person because it describes the user across many events. Mixing them up either loses history or stores duplicate user facts on every event. problems: - id: ph-evperson-p1 type: multiple_choice @@ -1862,24 +1542,17 @@ concepts: - Session property — it describes the visit - Group property — it describes the company correct: 1 - explanation: >- - A subscription plan describes the user generally, not a specific action. It should be a person property so it persists on the user's profile. If stored as an event property, you would - need to attach it to every single event. + explanation: A subscription plan describes the user generally, not a specific action. It should be a person property so it persists on the user's profile. If stored as an event property, you would need to attach it to every single event. - id: ph-evperson-p2 type: scenario - question: >- - A customer tracks the page URL where a button was clicked. They store this as a person property ($set: { last_clicked_page: '/pricing' }). Every time the user clicks a different button - on a different page, the person property updates. When they build a funnel analysis, they see unexpected results because the person property reflects the latest click, not the click at - each funnel step. What went wrong? + question: 'A customer tracks the page URL where a button was clicked. They store this as a person property ($set: { last_clicked_page: ''/pricing'' }). Every time the user clicks a different button on a different page, the person property updates. When they build a funnel analysis, they see unexpected results because the person property reflects the latest click, not the click at each funnel step. What went wrong?' options: - They should have used a group property instead - Page URL at click time is per-event context and should be an event property, not a person property - They need to use $set_once instead of $set - Funnel analysis does not support properties correct: 1 - explanation: >- - Page URL at click time is event-specific context — it varies per event. Storing it as a person property overwrites on every click, losing the history. It should be an event property so - each event preserves the URL at the time of that specific click. + explanation: Page URL at click time is event-specific context — it varies per event. Storing it as a person property overwrites on every click, losing the history. It should be an event property so each event preserves the URL at the time of that specific click. - id: ph-evperson-p3 type: matching question: Classify each property as event property or person property. @@ -1890,6 +1563,7 @@ concepts: - plan (user's subscription tier)|Person property correct: 0,1,2,3 explanation: $current_url and cart_value are snapshots of context at event time (event properties). Email and plan describe the user generally and persist across events (person properties). + keyPrerequisite: ph-event-properties section: posthog-data-model - id: ph-persons name: Persons & Person Profiles @@ -1910,10 +1584,7 @@ concepts: weight: 0.45 knowledgePoints: - id: what-is-a-person - instruction: >- - A person in PostHog represents one user identity whose events, sessions, and properties can be tied together in one profile. In graph terms, Person is a one-to-many parent of Events: one - person can have many events, but events can also exist without a person profile when the user is still anonymous. That distinction matters because new learners often assume every event must - belong to a person. In PostHog, that is not true. + instruction: 'A person in PostHog represents one user identity whose events, sessions, and properties can be tied together in one profile. In graph terms, Person is a one-to-many parent of Events: one person can have many events, but events can also exist without a person profile when the user is still anonymous. That distinction matters because new learners often assume every event must belong to a person. In PostHog, that is not true.' instructionContent: - type: link url: https://posthog.com/docs/data/persons @@ -1929,16 +1600,12 @@ concepts: - Capturing an event with posthog.capture() without any identification - Calling posthog.group() correct: 2 - explanation: >- - A plain posthog.capture() call without identification only creates an event with a distinct_id. It does not create a person profile (when using identified_only mode). identify(), $set, - and group() all trigger person profile creation. + explanation: A plain posthog.capture() call without identification only creates an event with a distinct_id. It does not create a person profile (when using identified_only mode). identify(), $set, and group() all trigger person profile creation. - id: ph-persons-p2 type: true_false question: Every event in PostHog must have an associated person profile. correct: 'false' - explanation: >- - Events can exist without a person profile. Anonymous events have a distinct_id but no person record. This is especially true in 'identified_only' mode where person profiles are only - created when explicit identification occurs. + explanation: Events can exist without a person profile. Anonymous events have a distinct_id but no person record. This is especially true in 'identified_only' mode where person profiles are only created when explicit identification occurs. - id: ph-persons-p3 type: multiple_choice question: Which PostHog features require a person profile to function? @@ -1948,60 +1615,44 @@ concepts: - Counting total pageviews - Viewing the project settings page correct: 1 - explanation: >- - Feature flags need to know who the user is to decide which flag variant to serve. Experiments need person profiles for consistent bucketing. Cohorts group users by properties. All of - these require person profiles. Raw event counting works without them. + explanation: Feature flags need to know who the user is to decide which flag variant to serve. Experiments need person profiles for consistent bucketing. Cohorts group users by properties. All of these require person profiles. Raw event counting works without them. + keyPrerequisite: ph-events - id: what-person-profiles-enable - instruction: >- - Person profiles matter because several higher-level PostHog capabilities depend on stable user identity. Person properties power segmentation. Feature flags and experiments need a known user - identity for consistent evaluation and bucketing. Cohorts use person state to build reusable groups. Without person profiles, you can still count events, but you lose person-level targeting, - longitudinal user context, and many debugging workflows. + instruction: Person profiles matter because several higher-level PostHog capabilities depend on stable user identity. Person properties power segmentation. Feature flags and experiments need a known user identity for consistent evaluation and bucketing. Cohorts use person state to build reusable groups. Without person profiles, you can still count events, but you lose person-level targeting, longitudinal user context, and many debugging workflows. problems: - id: ph-persons-p3a type: multiple_choice - question: >- - A customer has Product Analytics dashboards working but reports that their feature flag targeting rules are not matching any users. They confirm events are flowing. What is the most likely cause? + question: A customer has Product Analytics dashboards working but reports that their feature flag targeting rules are not matching any users. They confirm events are flowing. What is the most likely cause? options: - The feature flag has a syntax error in the targeting rule - Events are being captured without person profiles — feature flags require identified users with person profiles - The CDN is caching the old flag value - PostHog's feature flag service is experiencing downtime correct: 1 - explanation: >- - Feature flags evaluate targeting rules against person profiles. If events are captured anonymously (no identify() call, or person processing is off), no person profiles exist, and flag targeting has nothing to match against. The fix is to ensure identify() is called so person profiles are created. + explanation: Feature flags evaluate targeting rules against person profiles. If events are captured anonymously (no identify() call, or person processing is off), no person profiles exist, and flag targeting has nothing to match against. The fix is to ensure identify() is called so person profiles are created. - id: ph-persons-p4 type: scenario - question: >- - A customer can count pageviews and signups, but they cannot target a feature to users on the `pro` plan or inspect one user's full journey. What missing layer should you look for first? + question: A customer can count pageviews and signups, but they cannot target a feature to users on the `pro` plan or inspect one user's full journey. What missing layer should you look for first? options: - Session properties only - Person profiles with stable identity and person properties - Actions built from autocapture - Batch exports to a warehouse correct: 1 - explanation: >- - Aggregate events alone are not enough for person-level tooling. Feature targeting and user-level debugging need person profiles plus person properties such as `plan`. + explanation: Aggregate events alone are not enough for person-level tooling. Feature targeting and user-level debugging need person profiles plus person properties such as `plan`. - id: ph-persons-p5 type: true_false question: Person properties in PostHog can be used to segment users in insights (e.g., 'show me pageviews broken down by plan tier') even without feature flags or experiments. correct: 'true' - explanation: >- - Person properties power segmentation in insights, not just feature flags. You can break down any event by person properties like plan, role, or signup_source. If you answered false, - you may have thought person properties are only for targeting features — they are also the backbone of user-level analysis. + explanation: Person properties power segmentation in insights, not just feature flags. You can break down any event by person properties like plan, role, or signup_source. If you answered false, you may have thought person properties are only for targeting features — they are also the backbone of user-level analysis. + keyPrerequisite: ph-persons - id: viewing-person-profiles - instruction: >- - In the PostHog UI, the person profile is the operational debugging surface. It brings together the user's distinct_ids, person properties, event history, session recordings, feature flag - evaluations, and group memberships. When a customer asks 'what did user X do?' or 'why is user X seeing this feature?', the person profile is usually the fastest way to inspect the full - identity state in one place. + instruction: In the PostHog UI, the person profile is the operational debugging surface. It brings together the user's distinct_ids, person properties, event history, session recordings, feature flag evaluations, and group memberships. When a customer asks 'what did user X do?' or 'why is user X seeing this feature?', the person profile is usually the fastest way to inspect the full identity state in one place. instructionContent: - type: callout title: Debugging shortcut - body: >- - If the question mentions one specific user, start at the person profile before diving into insights. It is the best place to catch duplicate IDs, stale person properties, or unexpected - flag evaluations. - workedExample: >- - A TAM investigates why one customer claims a beta feature never appeared. The person profile shows the user's distinct_ids, recent events, current person properties, and feature flag - evaluations in one place. That is usually faster than jumping between raw event tables and flag settings separately. + body: If the question mentions one specific user, start at the person profile before diving into insights. It is the best place to catch duplicate IDs, stale person properties, or unexpected flag evaluations. + workedExample: A TAM investigates why one customer claims a beta feature never appeared. The person profile shows the user's distinct_ids, recent events, current person properties, and feature flag evaluations in one place. That is usually faster than jumping between raw event tables and flag settings separately. problems: - id: ph-viewing-p1 type: multiple_choice @@ -2012,9 +1663,7 @@ concepts: - The Dashboard settings - The Project settings page correct: 1 - explanation: >- - The Person profile page is the central view for an individual user. It shows all distinct_ids, person properties, event history, session recordings, and feature flag evaluations in one - place. + explanation: The Person profile page is the central view for an individual user. It shows all distinct_ids, person properties, event history, session recordings, and feature flag evaluations in one place. - id: ph-viewing-p2 type: true_false question: If two person profiles in PostHog represent the same real human, they can be manually merged in the UI. @@ -2022,17 +1671,15 @@ concepts: explanation: PostHog supports manual merging of person profiles. This is useful for fixing identification mistakes where the same user accidentally created two separate profiles. - id: ph-viewing-p3 type: scenario - question: >- - A customer says 'User X should be seeing the beta feature, but they report it is not showing up.' As a TAM, what is the fastest first debugging step in PostHog? + question: A customer says 'User X should be seeing the beta feature, but they report it is not showing up.' As a TAM, what is the fastest first debugging step in PostHog? options: - Re-deploy the feature flag configuration - Open User X's person profile to inspect their distinct_ids, person properties, and feature flag evaluations - Ask the customer to clear their browser cache - Check the ClickHouse query logs correct: 1 - explanation: >- - The person profile is the debugging surface that brings together identity, properties, and flag evaluations in one place. It is the fastest way to see why a specific user is or is not - seeing a feature. Start there before diving into infrastructure or asking the customer to troubleshoot. + explanation: The person profile is the debugging surface that brings together identity, properties, and flag evaluations in one place. It is the fastest way to see why a specific user is or is not seeing a feature. Start there before diving into infrastructure or asking the customer to troubleshoot. + keyPrerequisite: ph-persons section: posthog-data-model - id: ph-person-properties name: Person Properties — $set and $set_once @@ -2047,10 +1694,7 @@ concepts: encompassing: [] knowledgePoints: - id: setting-person-properties - instruction: >- - Person properties live on the person profile rather than on one event. They are meant to describe the user over time. The two main write modes are `$set` and `$set_once`. `$set` overwrites - the current value. `$set_once` writes only if the property does not already exist. That means changing facts like plan or subscription_status usually use `$set`, while first-touch facts like - signup_source usually use `$set_once`. + instruction: Person properties live on the person profile rather than on one event. They are meant to describe the user over time. The two main write modes are `$set` and `$set_once`. `$set` overwrites the current value. `$set_once` writes only if the property does not already exist. That means changing facts like plan or subscription_status usually use `$set`, while first-touch facts like signup_source usually use `$set_once`. instructionContent: - type: link url: https://posthog.com/docs/product-analytics/person-properties @@ -2066,56 +1710,42 @@ concepts: - $set works on events and $set_once works on persons - $set is synchronous and $set_once is asynchronous correct: 1 - explanation: >- - $set always overwrites the current value, regardless of what was there before. $set_once only writes the value if the property does not already exist on the person profile. + explanation: $set always overwrites the current value, regardless of what was there before. $set_once only writes the value if the property does not already exist on the person profile. - id: ph-personprops-p5 type: scenario - question: >- - A customer calls $set_once({ signup_source: 'google_ads' }) for a user, then later calls $set_once({ signup_source: 'organic' }) for the same user after they visit again through a - different channel. What value does signup_source have on the person profile? + question: 'A customer calls $set_once({ signup_source: ''google_ads'' }) for a user, then later calls $set_once({ signup_source: ''organic'' }) for the same user after they visit again through a different channel. What value does signup_source have on the person profile?' options: - The value is 'organic' because the latest call wins - The value is 'google_ads' because $set_once preserves the first value and ignores subsequent writes - Both values are stored as an array - The property is deleted because of the conflict correct: 1 - explanation: >- - $set_once writes only if the property does not already exist. Since signup_source was already set to 'google_ads', the second call with 'organic' is silently ignored. This is exactly - the intended behavior for first-touch attribution data. + explanation: $set_once writes only if the property does not already exist. Since signup_source was already set to 'google_ads', the second call with 'organic' is silently ignored. This is exactly the intended behavior for first-touch attribution data. + keyPrerequisite: ph-persons - id: choosing-person-property-updates - instruction: >- - The real skill is deciding which facts should stay historically fixed and which should reflect the latest truth. Attribution, original referrer, or first signup date are first-touch facts. - Plan tier, lifecycle stage, or last_seen_at are current-state facts. If you use `$set` where you needed `$set_once`, you erase history. If you use `$set_once` where you needed `$set`, the - profile gets stuck with stale data. - workedExample: >- - A user signs up through Google Ads. Your code sets plan with `$set` and signup_source with `$set_once`. Months later they upgrade and arrive through a different campaign. Plan should update - to reflect the user's current state, but signup_source should stay tied to the original acquisition channel. + instruction: The real skill is deciding which facts should stay historically fixed and which should reflect the latest truth. Attribution, original referrer, or first signup date are first-touch facts. Plan tier, lifecycle stage, or last_seen_at are current-state facts. If you use `$set` where you needed `$set_once`, you erase history. If you use `$set_once` where you needed `$set`, the profile gets stuck with stale data. + workedExample: A user signs up through Google Ads. Your code sets plan with `$set` and signup_source with `$set_once`. Months later they upgrade and arrive through a different campaign. Plan should update to reflect the user's current state, but signup_source should stay tied to the original acquisition channel. problems: - id: ph-personprops-p2 type: scenario - question: >- - A customer wants to track each user's original marketing channel (the first channel that brought them) and their current subscription plan. The marketing channel should never change once - set, but the plan updates on upgrade/downgrade. Which approach is correct? + question: A customer wants to track each user's original marketing channel (the first channel that brought them) and their current subscription plan. The marketing channel should never change once set, but the plan updates on upgrade/downgrade. Which approach is correct? options: - Use $set for both properties - Use $set_once for both properties - Use $set_once for marketing channel and $set for plan - Use event properties for both instead of person properties correct: 2 - explanation: >- - $set_once for marketing channel preserves the original acquisition source. $set for plan ensures it always reflects the current subscription tier. + explanation: $set_once for marketing channel preserves the original acquisition source. $set for plan ensures it always reflects the current subscription tier. - id: ph-personprops-p4 type: multiple_choice - question: >- - A customer tracks both `current_plan` (changes on upgrade/downgrade) and `original_signup_source` (should never change). They're using `$set` for both. What problem will this cause and how should they fix it? + question: A customer tracks both `current_plan` (changes on upgrade/downgrade) and `original_signup_source` (should never change). They're using `$set` for both. What problem will this cause and how should they fix it? options: - No problem — $set is correct for both since it always keeps the latest value - '`original_signup_source` will be overwritten if the customer re-visits from a different source — use `$set_once` for it instead' - Both properties should use `$set_once` to prevent any changes - '`current_plan` will stop updating — they need to use `$set_once` for it' correct: 1 - explanation: >- - `$set` always overwrites with the latest value, which is correct for `current_plan` (you want it to reflect the current state). But `original_signup_source` should be immutable — `$set_once` writes only if the property has no existing value, preserving the first-touch attribution. The fix: use `$set` for mutable properties and `$set_once` for immutable ones. + explanation: '`$set` always overwrites with the latest value, which is correct for `current_plan` (you want it to reflect the current state). But `original_signup_source` should be immutable — `$set_once` writes only if the property has no existing value, preserving the first-touch attribution. The fix: use `$set` for mutable properties and `$set_once` for immutable ones.' - id: ph-personprops-p6 type: multiple_choice question: A customer wants to track both a user's current plan and their original signup date. Which combination of operators is correct? @@ -2125,9 +1755,8 @@ concepts: - $set for plan (changes on upgrade) and $set_once for signup_date (never changes) - $set_once for plan and $set for signup_date correct: 2 - explanation: >- - Plan changes when users upgrade or downgrade, so it needs $set to reflect the current state. Signup date is a historical fact that should never be overwritten, so it needs $set_once. - The pattern is: current-state facts use $set, first-touch facts use $set_once. + explanation: 'Plan changes when users upgrade or downgrade, so it needs $set to reflect the current state. Signup date is a historical fact that should never be overwritten, so it needs $set_once. The pattern is: current-state facts use $set, first-touch facts use $set_once.' + keyPrerequisite: ph-person-properties section: posthog-data-model - id: ph-distinct-id name: distinct_id — Linking Events to Persons @@ -2145,14 +1774,11 @@ concepts: weight: 0.8 knowledgePoints: - id: what-is-distinct-id - instruction: >- - The `distinct_id` is the identity key on every PostHog event. It answers the question 'who or which device did this?' and acts like the foreign key from Event to Person. If two events have - different distinct_ids and nothing links them, PostHog treats them as different identities. That is why distinct_id mistakes create duplicate users so quickly. + instruction: The `distinct_id` is the identity key on every PostHog event. It answers the question 'who or which device did this?' and acts like the foreign key from Event to Person. If two events have different distinct_ids and nothing links them, PostHog treats them as different identities. That is why distinct_id mistakes create duplicate users so quickly. instructionContent: - type: callout title: Identity question - body: >- - When you inspect an event and ask "who is this?", `distinct_id` is the first field doing that work. + body: When you inspect an event and ask "who is this?", `distinct_id` is the first field doing that work. - type: link url: https://posthog.com/docs/data/persons title: PostHog identity and persons docs @@ -2162,23 +1788,17 @@ concepts: type: true_false question: The distinct_id on PostHog events serves as a foreign key linking each event to a person. correct: 'true' - explanation: >- - If you answered false, the likely confusion is treating `distinct_id` as just another property. It is the identity key on the event. Other properties add context, but `distinct_id` - determines which user or device the event belongs to. + explanation: If you answered false, the likely confusion is treating `distinct_id` as just another property. It is the identity key on the event. Other properties add context, but `distinct_id` determines which user or device the event belongs to. - id: ph-did-p4 type: scenario - question: >- - A customer sees two otherwise similar signup events, but one has `distinct_id = anon-123` and the other has `distinct_id = user_42`. No identify or alias link exists between them. How - will PostHog interpret those events? + question: A customer sees two otherwise similar signup events, but one has `distinct_id = anon-123` and the other has `distinct_id = user_42`. No identify or alias link exists between them. How will PostHog interpret those events? options: - As the same person because the event names match - As two separate identities until something links the IDs - As invalid events that will be rejected - As one person if they came from the same IP address correct: 1 - explanation: >- - The event name does not define identity. `distinct_id` does. If the IDs differ and no linkage exists, PostHog keeps them separate. The thing to inspect is the identifier flow, not the - event label. + explanation: The event name does not define identity. `distinct_id` does. If the IDs differ and no linkage exists, PostHog keeps them separate. The thing to inspect is the identifier flow, not the event label. - id: ph-did-p5 type: multiple_choice question: If two PostHog events share the same distinct_id, what can you conclude? @@ -2188,17 +1808,11 @@ concepts: - PostHog attributes both events to the same identity - They have identical properties correct: 2 - explanation: >- - The distinct_id is the identity key. Events with the same distinct_id are attributed to the same user or device. They can have different timestamps, different SDKs, and completely - different properties. The only thing distinct_id guarantees is identity linkage. + explanation: The distinct_id is the identity key. Events with the same distinct_id are attributed to the same user or device. They can have different timestamps, different SDKs, and completely different properties. The only thing distinct_id guarantees is identity linkage. + keyPrerequisite: keys-and-identity - id: frontend-vs-backend-distinct-id - instruction: >- - Frontend and backend SDKs behave differently. Frontend SDKs generate and persist an anonymous distinct_id automatically on first use, which lets PostHog track pre-login behavior. Backend SDKs - do not do that. On the server, you must pass a distinct_id yourself on every capture call. That difference is easy to miss, and it explains many 'why did my backend event create a new user?' - support threads. - workedExample: >- - On the web, a visitor lands on `/pricing` and the JS SDK creates `anon-abc`. Later, after login, the app identifies them as `user_42`. On the backend, an API event for that same user must - also use `user_42`, because the backend will not infer it automatically. + instruction: Frontend and backend SDKs behave differently. Frontend SDKs generate and persist an anonymous distinct_id automatically on first use, which lets PostHog track pre-login behavior. Backend SDKs do not do that. On the server, you must pass a distinct_id yourself on every capture call. That difference is easy to miss, and it explains many 'why did my backend event create a new user?' support threads. + workedExample: On the web, a visitor lands on `/pricing` and the JS SDK creates `anon-abc`. Later, after login, the app identifies them as `user_42`. On the backend, an API event for that same user must also use `user_42`, because the backend will not infer it automatically. problems: - id: ph-did-p1 type: multiple_choice @@ -2209,8 +1823,7 @@ concepts: - It uses the user's IP address as the distinct_id - It sends events without any distinct_id correct: 1 - explanation: >- - The frontend SDK creates the anonymous identity for you. If you chose 'waits for login', you are thinking in backend terms, where the application usually has to provide the known user ID. + explanation: The frontend SDK creates the anonymous identity for you. If you chose 'waits for login', you are thinking in backend terms, where the application usually has to provide the known user ID. - id: ph-did-p2 type: multiple_choice question: Backend PostHog SDKs do not auto-generate a distinct_id. What must you do on every capture call? @@ -2220,37 +1833,28 @@ concepts: - Enable autocapture - Attach a $session_id correct: 0 - explanation: >- - The server has no browser state to fall back on. If you omit `distinct_id`, PostHog cannot attach the event to the intended user, so the recovery step is to pass the same canonical ID - your other systems use. + explanation: The server has no browser state to fall back on. If you omit `distinct_id`, PostHog cannot attach the event to the intended user, so the recovery step is to pass the same canonical ID your other systems use. - id: ph-did-p6 type: scenario - question: >- - A customer's backend Python SDK sends a 'payment_processed' event but does not include a distinct_id in the capture call. What is the most likely outcome? + question: A customer's backend Python SDK sends a 'payment_processed' event but does not include a distinct_id in the capture call. What is the most likely outcome? options: - PostHog auto-generates an anonymous distinct_id like the frontend SDK does - The event is rejected or attributed incorrectly because backend SDKs require an explicit distinct_id - PostHog infers the user from the IP address - The event is stored without any identity and cannot be queried correct: 1 - explanation: >- - Backend SDKs do not auto-generate distinct_ids. If you omit it, the SDK may raise an error or the event may be attributed to a meaningless default. The fix is to always pass the - known user ID explicitly on every backend capture call. + explanation: Backend SDKs do not auto-generate distinct_ids. If you omit it, the SDK may raise an error or the event may be attributed to a meaningless default. The fix is to always pass the known user ID explicitly on every backend capture call. + keyPrerequisite: ph-distinct-id - id: multiple-distinct-ids - instruction: >- + instruction: |- A single person in PostHog can have **multiple distinct_ids**. This is not a bug — it is by design and essential for linking anonymous and identified behavior. - **The most common scenario:** a user visits your site and the SDK generates a random distinct_id (say "abc-random-uuid"). They browse several pages. Then they log in, and you call posthog.identify("user_42"). Now this person has two distinct_ids: "abc-random-uuid" and "user_42". All events from both IDs belong to the same person. - **Other scenarios that create multiple distinct_ids:** a user visits from a second device (generates another random ID), then logs in on that device too — both random IDs plus the known ID are now linked. Or you use posthog.alias to explicitly link two IDs. - In data modeling terms, this is a **one-to-many relationship:** one Person has many distinct_ids. The person profile page in PostHog shows all distinct_ids associated with a person, which is useful for debugging identification issues. - workedExample: >- - Pre-login web browsing might create `anon-web-123`, the mobile app might create `anon-mobile-456`, and login might attach both to `user_42`. One person, several identifiers, one combined - history. + workedExample: Pre-login web browsing might create `anon-web-123`, the mobile app might create `anon-mobile-456`, and login might attach both to `user_42`. One person, several identifiers, one combined history. problems: - id: ph-multi-did-p1 type: multiple_choice @@ -2261,28 +1865,23 @@ concepts: - Because PostHog randomly reassigns distinct_ids every session - Because each event must have a unique distinct_id correct: 1 - explanation: >- - Multiple distinct_ids per person is by design. The anonymous ID from before login and the known ID from after login both belong to the same person. PostHog links them via identify() so - the full user journey is captured. + explanation: Multiple distinct_ids per person is by design. The anonymous ID from before login and the known ID from after login both belong to the same person. PostHog links them via identify() so the full user journey is captured. - id: ph-multi-did-p2 type: scenario - question: >- - A user browses your site on their laptop (distinct_id: laptop-uuid) and their phone (distinct_id: phone-uuid). They log in on the laptop and you call identify('user_42'). Later they log - in on the phone and you call identify('user_42') again. How many distinct_ids does this person have? + question: 'A user browses your site on their laptop (distinct_id: laptop-uuid) and their phone (distinct_id: phone-uuid). They log in on the laptop and you call identify(''user_42''). Later they log in on the phone and you call identify(''user_42'') again. How many distinct_ids does this person have?' options: - 1 — only user_42 - 2 — laptop-uuid and phone-uuid - 3 — laptop-uuid, phone-uuid, and user_42 - 4 — two per device correct: 2 - explanation: >- - The person has three distinct_ids: laptop-uuid (from laptop's first visit), phone-uuid (from phone's first visit), and user_42 (the known ID from both identify calls). All three are - linked to one person profile. + explanation: 'The person has three distinct_ids: laptop-uuid (from laptop''s first visit), phone-uuid (from phone''s first visit), and user_42 (the known ID from both identify calls). All three are linked to one person profile.' - id: ph-multi-did-p3 type: true_false question: In PostHog, the relationship between a Person and their distinct_ids is one-to-one. correct: 'false' explanation: 'It is one-to-many: one Person can have many distinct_ids. This happens through anonymous browsing on multiple devices, identify() calls, and alias() calls that link IDs together.' + keyPrerequisite: ph-distinct-id section: posthog-data-model - id: ph-sessions name: Sessions — Grouping Events by Visit @@ -2298,16 +1897,13 @@ concepts: encompassing: [] knowledgePoints: - id: how-sessions-work - instruction: >- + instruction: |- A **session** in PostHog represents a single visit — a contiguous period of user activity. The JS web SDK and mobile SDKs automatically generate a `$session_id` and attach it to every event. Events with the same `$session_id` belong to the same session. - **Two rules control session boundaries:** a new session starts after **30 minutes of inactivity** (no events for 30 minutes means the old session ends and the next event starts a new one), and sessions have a **maximum duration of 24 hours** (even with continuous activity, a new session starts after 24 hours). - **Server-side SDKs** do NOT automatically generate or attach `$session_id` — you must set it manually if you want server events to belong to a session. This means server-side events are typically not associated with sessions unless you explicitly pass the session ID from your frontend. - Session Replay and Web Analytics both depend on `$session_id` to group events into recordings and visits. Without it, these features cannot function. instructionContent: - type: link @@ -2324,9 +1920,7 @@ concepts: - The user closes and reopens their browser - The user navigates to a different domain correct: 1 - explanation: >- - PostHog starts a new session after 30 minutes of inactivity (no events) or after 24 hours of continuous activity. Browser close/open does not necessarily end a session if it happens - within the 30-minute window. + explanation: PostHog starts a new session after 30 minutes of inactivity (no events) or after 24 hours of continuous activity. Browser close/open does not necessarily end a session if it happens within the 30-minute window. - id: ph-sessions-p2 type: multiple_choice question: What is the maximum duration of a single PostHog session, even with continuous activity? @@ -2341,37 +1935,29 @@ concepts: type: true_false question: Server-side PostHog SDKs automatically attach a $session_id to every captured event. correct: 'false' - explanation: >- - Server-side SDKs do NOT auto-generate or attach $session_id. You must manually pass it if you want server events associated with a session. Only the JS web SDK and mobile SDKs handle - this automatically. + explanation: Server-side SDKs do NOT auto-generate or attach $session_id. You must manually pass it if you want server events associated with a session. Only the JS web SDK and mobile SDKs handle this automatically. - id: ph-sessions-p4 type: scenario - question: >- - A customer reports that their Session Replay recordings all appear as short 1-2 minute fragments instead of full user sessions. Users are navigating a single-page app (SPA) and sessions should be 10-15 minutes long. What is the most likely cause? + question: A customer reports that their Session Replay recordings all appear as short 1-2 minute fragments instead of full user sessions. Users are navigating a single-page app (SPA) and sessions should be 10-15 minutes long. What is the most likely cause? options: - The Session Replay sampling rate is set too low - The SPA is re-initializing the PostHog SDK on each route change, generating new session IDs - PostHog's 30-minute inactivity timeout is too aggressive for their use case - ClickHouse is splitting sessions during ingestion due to high event volume correct: 1 - explanation: >- - In a single-page app, if the PostHog SDK is re-initialized on each route change (e.g., calling posthog.init() inside a component that remounts), each initialization generates a new $session_id. This fragments what should be one continuous session into many short ones. The fix: initialize the SDK once at the app root level, not inside route-level components. The 30-minute timeout and 24-hour max duration are unlikely culprits since users are actively navigating. + explanation: 'In a single-page app, if the PostHog SDK is re-initialized on each route change (e.g., calling posthog.init() inside a component that remounts), each initialization generates a new $session_id. This fragments what should be one continuous session into many short ones. The fix: initialize the SDK once at the app root level, not inside route-level components. The 30-minute timeout and 24-hour max duration are unlikely culprits since users are actively navigating.' difficulty: 4 + keyPrerequisite: ph-distinct-id - id: session-properties - instruction: >- + instruction: |- PostHog computes **session-level properties** automatically from the events within a session. These are distinct from event properties and person properties — they describe the visit as a whole. - **Key session properties:** `$session_duration` (total time from first to last event), `$entry_current_url` (the URL of the first pageview), `$exit_pathname` (the path of the last pageview), `$pageview_count` (how many pageviews in the session), `$autocapture_count` (how many autocapture events), and `$is_bounce` (whether the session had only one pageview). - These properties are **computed by PostHog** — you do not set them yourself. - You can use session properties to filter insights (for example, "show me sessions with duration greater than 5 minutes") and to filter session recordings (for example, "show me bounce sessions on the pricing page"). Session properties are useful for understanding visit quality and user engagement at the session level. - workedExample: >- - If a visitor lands on `/pricing`, views three pages, and leaves after six minutes, PostHog can compute entry URL, pageview count, bounce status, and total session duration from that bundle - of events without you setting those fields manually. + workedExample: If a visitor lands on `/pricing`, views three pages, and leaves after six minutes, PostHog can compute entry URL, pageview count, bounce status, and total session duration from that bundle of events without you setting those fields manually. problems: - id: ph-sessprops-p1 type: multiple_choice @@ -2382,29 +1968,23 @@ concepts: - plan (the user's subscription tier) - $current_url (the page URL at event time) correct: 1 - explanation: >- - $session_duration is a session property computed from the events within a session. $browser is an event property (set per event). 'plan' is a person property. $current_url is an event - property that varies per event. + explanation: $session_duration is a session property computed from the events within a session. $browser is an event property (set per event). 'plan' is a person property. $current_url is an event property that varies per event. - id: ph-sessprops-p2 type: true_false question: Session properties like $session_duration and $is_bounce must be manually set by the developer. correct: 'false' - explanation: >- - Session properties are computed automatically by PostHog from the events within a session. You do not set them — PostHog calculates duration, bounce status, pageview counts, entry/exit - URLs, and other session-level metrics. + explanation: Session properties are computed automatically by PostHog from the events within a session. You do not set them — PostHog calculates duration, bounce status, pageview counts, entry/exit URLs, and other session-level metrics. - id: ph-sessprops-p3 type: scenario - question: >- - A customer wants to find session recordings of users who bounced on the pricing page. Which combination of session properties would help filter for this? + question: A customer wants to find session recordings of users who bounced on the pricing page. Which combination of session properties would help filter for this? options: - $session_duration > 30 minutes and $pageview_count > 10 - $is_bounce = true and $entry_current_url contains '/pricing' - $browser = 'Chrome' and $os = 'Mac OS X' - $autocapture_count = 0 and $exit_pathname = '/home' correct: 1 - explanation: >- - $is_bounce identifies single-pageview sessions, and $entry_current_url tells you where the session started. Together they filter for users who landed on /pricing and left without - viewing another page. These are session properties computed automatically by PostHog. + explanation: $is_bounce identifies single-pageview sessions, and $entry_current_url tells you where the session started. Together they filter for users who landed on /pricing and left without viewing another page. These are session properties computed automatically by PostHog. + keyPrerequisite: ph-sessions section: posthog-data-model - id: ph-actions name: Actions — Grouping Events for Analysis @@ -2420,9 +2000,7 @@ concepts: encompassing: [] knowledgePoints: - id: what-are-actions - instruction: >- - An action in PostHog is a saved grouping of one or more events that you want to treat as one analytical unit. Instead of rebuilding the same filters in every insight, you define the match - once in the UI and reuse it. Actions do not create new raw event data. They sit on top of existing events as reusable saved filters, and they apply retroactively to historical matches. + instruction: An action in PostHog is a saved grouping of one or more events that you want to treat as one analytical unit. Instead of rebuilding the same filters in every insight, you define the match once in the UI and reuse it. Actions do not create new raw event data. They sit on top of existing events as reusable saved filters, and they apply retroactively to historical matches. instructionContent: - type: link url: https://posthog.com/docs/data/actions#what-is-an-action @@ -2438,9 +2016,7 @@ concepts: - A webhook that triggers when a specific event occurs - A person property that tracks user behavior correct: 1 - explanation: >- - An action is a saved grouping of events defined in PostHog's UI. It lets you combine multiple related events into one analytical unit. Actions are not custom events and are not defined - in code. + explanation: An action is a saved grouping of events defined in PostHog's UI. It lets you combine multiple related events into one analytical unit. Actions are not custom events and are not defined in code. - id: ph-actions-p5 type: multiple_choice question: When you create a new action in PostHog, does it generate new event data or work with existing events? @@ -2450,50 +2026,37 @@ concepts: - It only matches events captured after the action is created - It creates a copy of matching events in a separate table correct: 1 - explanation: >- - Actions are saved filters that sit on top of existing events. They do not create new data. When you define an action, it immediately matches all historical events that fit the - criteria. This is why actions apply retroactively. + explanation: Actions are saved filters that sit on top of existing events. They do not create new data. When you define an action, it immediately matches all historical events that fit the criteria. This is why actions apply retroactively. + keyPrerequisite: ph-event-properties - id: actions-vs-custom-events - instruction: >- - Actions are best when you already have events and want a reusable analysis layer on top of them, especially for grouping several autocapture patterns without redeploying code. But actions are - not a substitute for good instrumentation. If a metric is mission-critical and tied to a real business event, a custom event is usually the stronger foundation because it survives UI changes - better than selector-based matching. + instruction: Actions are best when you already have events and want a reusable analysis layer on top of them, especially for grouping several autocapture patterns without redeploying code. But actions are not a substitute for good instrumentation. If a metric is mission-critical and tied to a real business event, a custom event is usually the stronger foundation because it survives UI changes better than selector-based matching. problems: - id: ph-actions-p3 type: scenario - question: >- - A customer has three 'Sign Up' buttons on their site — one in the navbar, one in the hero section, and one in the footer. Each generates a slightly different autocapture event. They want - to track total signup button clicks as a single metric. What do you recommend? + question: A customer has three 'Sign Up' buttons on their site — one in the navbar, one in the hero section, and one in the footer. Each generates a slightly different autocapture event. They want to track total signup button clicks as a single metric. What do you recommend? options: - Rewrite the frontend to use the same CSS class on all three buttons - Create an action in PostHog that matches all three autocapture events - Use a custom event for each button and add them manually in every insight - Ignore two of the buttons and only track one correct: 1 - explanation: >- - An action can group multiple autocapture events into one unit. The customer defines the action once in PostHog's UI, and then uses it anywhere they would use an event — in trends, - funnels, paths, and other analyses. + explanation: An action can group multiple autocapture events into one unit. The customer defines the action once in PostHog's UI, and then uses it anywhere they would use an event — in trends, funnels, paths, and other analyses. - id: ph-actions-p4 type: scenario - question: >- - A team relies on a "subscription_started" KPI for revenue reporting. Today they approximate it with an action built from checkout-button selectors. What is the stronger long-term - recommendation? + question: A team relies on a "subscription_started" KPI for revenue reporting. Today they approximate it with an action built from checkout-button selectors. What is the stronger long-term recommendation? options: - Keep the action only, because actions are always more reliable than custom events - Instrument a custom "subscription_started" event in code and use actions only as a convenience layer when needed - Replace the action with a person property - Stop tracking the KPI in PostHog correct: 1 - explanation: >- - Actions are useful for grouping existing events, especially UI interactions. But a revenue-critical business event should usually be instrumented explicitly as a custom event so the metric - survives UI changes and selector drift. + explanation: Actions are useful for grouping existing events, especially UI interactions. But a revenue-critical business event should usually be instrumented explicitly as a custom event so the metric survives UI changes and selector drift. - id: ph-actions-p6 type: true_false question: For a mission-critical business metric like revenue, relying solely on an action built from autocapture selectors is a strong long-term strategy. correct: 'false' - explanation: >- - Autocapture-based actions depend on UI element properties (text, selectors, position) that change with redesigns. For mission-critical metrics, a custom event fired explicitly in - code is the stronger foundation because it survives UI changes. Actions are great as a convenience layer, not as the sole source of truth for revenue. + explanation: Autocapture-based actions depend on UI element properties (text, selectors, position) that change with redesigns. For mission-critical metrics, a custom event fired explicitly in code is the stronger foundation because it survives UI changes. Actions are great as a convenience layer, not as the sole source of truth for revenue. + keyPrerequisite: ph-actions section: posthog-data-model - id: ph-event-capture name: Event Capture — SDKs, API, and Autocapture @@ -2509,10 +2072,7 @@ concepts: encompassing: [] knowledgePoints: - id: how-events-enter-posthog - instruction: >- - Events reach PostHog through three surfaces: client-side SDKs, server-side SDKs, and the raw HTTP API. Client SDKs run in the browser or app, auto-generate anonymous IDs, and can observe UI - behavior like pageviews or autocapture. Server SDKs run on your backend, require an explicit distinct_id, and are better for backend actions such as API calls or jobs. The HTTP API is the - lowest-level option when you need to send capture requests without an official SDK. + instruction: 'Events reach PostHog through three surfaces: client-side SDKs, server-side SDKs, and the raw HTTP API. Client SDKs run in the browser or app, auto-generate anonymous IDs, and can observe UI behavior like pageviews or autocapture. Server SDKs run on your backend, require an explicit distinct_id, and are better for backend actions such as API calls or jobs. The HTTP API is the lowest-level option when you need to send capture requests without an official SDK.' instructionContent: - type: image url: https://posthog.com/images/products/product-os/event-pipelines.png @@ -2533,8 +2093,7 @@ concepts: - Both client-side and server-side SDKs equally - Neither — autocapture requires a separate tool correct: 1 - explanation: >- - Only client-side SDKs support autocapture and session recording because they run in the user's browser or app and can observe UI interactions directly. + explanation: Only client-side SDKs support autocapture and session recording because they run in the user's browser or app and can observe UI interactions directly. - id: ph-capture-p2 type: matching question: Match each SDK type to its characteristic. @@ -2544,13 +2103,10 @@ concepts: - HTTP API|Direct POST to /capture endpoint without SDK - JS web SDK|Supports session recording and the toolbar correct: 0,1,2,3 - explanation: >- - Client-side SDKs handle identity and autocapture automatically. Server-side SDKs need manual distinct_id and lack UI features. The HTTP API is the raw endpoint. + explanation: Client-side SDKs handle identity and autocapture automatically. Server-side SDKs need manual distinct_id and lack UI features. The HTTP API is the raw endpoint. + keyPrerequisite: ph-events - id: choosing-a-capture-surface - instruction: >- - All three capture surfaces use a push model: your systems send events to PostHog. The important design choice is which surface owns the event. Use a client SDK when the event depends on UI - context like page URL or session behavior. Use a server SDK when the event is a backend fact such as a webhook, billing job, or API outcome. Use the HTTP API when you need raw transport - without an official SDK or when building a custom integration layer. + instruction: 'All three capture surfaces use a push model: your systems send events to PostHog. The important design choice is which surface owns the event. Use a client SDK when the event depends on UI context like page URL or session behavior. Use a server SDK when the event is a backend fact such as a webhook, billing job, or API outcome. Use the HTTP API when you need raw transport without an official SDK or when building a custom integration layer.' instructionContent: - type: link url: https://posthog.com/docs/how-posthog-works @@ -2564,29 +2120,25 @@ concepts: explanation: PostHog uses push-based ingestion. Your application sends events to PostHog's capture endpoint via SDKs or the HTTP API. - id: ph-capture-p4 type: scenario - question: >- - A backend worker written in an unsupported language needs to send billing events into PostHog with an explicit user ID. Which capture path is the best fit? + question: A backend worker written in an unsupported language needs to send billing events into PostHog with an explicit user ID. Which capture path is the best fit? options: - The JS web SDK - A session replay integration - The raw HTTP capture API - Autocapture only correct: 2 - explanation: >- - If there is no official SDK, the raw HTTP capture API is the fallback surface. It still lets the worker push events into PostHog with an explicit distinct_id. + explanation: If there is no official SDK, the raw HTTP capture API is the fallback surface. It still lets the worker push events into PostHog with an explicit distinct_id. - id: ph-capture-p6 type: scenario - question: >- - A customer needs to track when a webhook from Stripe confirms a successful payment. The event happens entirely on the server with no UI involved. Which capture surface should they use? + question: A customer needs to track when a webhook from Stripe confirms a successful payment. The event happens entirely on the server with no UI involved. Which capture surface should they use? options: - The JS web SDK with autocapture - A server-side SDK (e.g., Node.js, Python) with an explicit distinct_id - Session recording - The PostHog toolbar correct: 1 - explanation: >- - Backend events like webhook confirmations have no UI context. A server-side SDK is the right choice because it runs on the backend and lets you explicitly set the distinct_id to the - customer who made the payment. + explanation: Backend events like webhook confirmations have no UI context. A server-side SDK is the right choice because it runs on the backend and lets you explicitly set the distinct_id to the customer who made the payment. + keyPrerequisite: ph-event-capture section: posthog-ingestion - id: ph-ingestion-pipeline name: The Ingestion Pipeline — Kafka to ClickHouse @@ -2602,28 +2154,22 @@ concepts: encompassing: [] knowledgePoints: - id: why-not-straight-to-db - instruction: >- + instruction: |- PostHog does not write events directly into ClickHouse (its analytics database). Instead, events land in **Apache Kafka** first — a distributed message queue designed for high-throughput, durable message streaming. - Why the indirection? Three reasons: - **Resilience:** if ClickHouse is temporarily slow, overloaded, or undergoing maintenance, events queue up safely in Kafka rather than being lost or causing backpressure on the capture API. - **Throughput:** Kafka can absorb massive bursts of events and smooth them out for ClickHouse to consume at a steady rate. - **Decoupling:** the capture API and ClickHouse do not need to know about each other — Kafka sits between them as a buffer. - This is the same pattern described in pipeline fundamentals: a message queue between ingestion and storage makes the pipeline more resilient and scalable. The capture API's only job is to validate the event and write it to Kafka. Everything else — person processing, property enrichment, storage — happens downstream. instructionContent: - type: callout title: Mental model - body: >- - Capture API -> Kafka buffer -> downstream consumers -> ClickHouse. Kafka buys resilience by absorbing bursts and outages between ingestion and storage. + body: Capture API -> Kafka buffer -> downstream consumers -> ClickHouse. Kafka buys resilience by absorbing bursts and outages between ingestion and storage. - type: link url: https://posthog.com/docs/how-posthog-works/ingestion-pipeline title: Ingestion pipeline diagram @@ -2638,53 +2184,39 @@ concepts: - Kafka transforms events into the correct format for ClickHouse - It is a legacy design that PostHog plans to remove correct: 1 - explanation: >- - Kafka acts as a durable buffer between ingestion and storage. If ClickHouse is slow or undergoing maintenance, events queue in Kafka safely. Without this buffer, events could be lost - during ClickHouse downtime. + explanation: Kafka acts as a durable buffer between ingestion and storage. If ClickHouse is slow or undergoing maintenance, events queue in Kafka safely. Without this buffer, events could be lost during ClickHouse downtime. - id: ph-pipeline-p2 type: true_false question: PostHog's capture API writes events directly into ClickHouse tables. correct: 'false' - explanation: >- - The capture API writes events to Kafka, not directly to ClickHouse. Kafka then feeds events into ClickHouse through a table engine and materialized view. This decoupling provides - resilience and throughput benefits. + explanation: The capture API writes events to Kafka, not directly to ClickHouse. Kafka then feeds events into ClickHouse through a table engine and materialized view. This decoupling provides resilience and throughput benefits. - id: ph-pipeline-p3 type: scenario - question: >- - A PostHog Cloud customer reports that their ClickHouse cluster had a brief maintenance window, but they did not lose any events during that period. What component of the architecture - prevented data loss? + question: A PostHog Cloud customer reports that their ClickHouse cluster had a brief maintenance window, but they did not lose any events during that period. What component of the architecture prevented data loss? options: - The client-side SDK cached events in local storage - Kafka queued the events durably until ClickHouse was ready to consume them again - PostgreSQL stored the events as a backup - The capture API retried failed writes automatically correct: 1 - explanation: >- - Kafka is a durable message queue. When ClickHouse is unavailable, events queue in Kafka and are consumed once ClickHouse recovers. This is the primary reason for the Kafka buffer in - PostHog's architecture. + explanation: Kafka is a durable message queue. When ClickHouse is unavailable, events queue in Kafka and are consumed once ClickHouse recovers. This is the primary reason for the Kafka buffer in PostHog's architecture. + keyPrerequisite: storage-layers - id: the-full-flow - instruction: >- + instruction: |- The complete ingestion flow from your app to queryable data: - **Step 1:** Your app sends an event via SDK or API. - **Step 2:** PostHog's capture endpoint validates the event and writes it to a Kafka topic. - **Step 3:** ClickHouse has a Kafka table engine (`kafka_events`) that acts as a consumer, reading events from Kafka and advancing offsets. - **Step 4:** A materialized view (`events_mv`) reads from `kafka_events` and inserts into the storage tables. - **Step 5:** Writes go through `writable_events` — a ClickHouse Distributed table that routes each event to the correct shard by hashing distinct_id using sipHash64. This means all events for the same user land on the same shard, making person-level queries efficient. - **Step 6:** Data lands in `sharded_events` — a ReplicatedReplacingMergeTree table that provides actual durable, replicated storage. - For reads, queries go through the `events` Distributed table, which fans out to all shards and aggregates results. instructionContent: - type: link @@ -2702,9 +2234,7 @@ concepts: - Capture endpoint writes event to Kafka - kafka_events table engine reads from Kafka correct: 1,3,4,0,2 - explanation: >- - The flow is: App sends event, capture endpoint writes to Kafka, kafka_events reads from Kafka, events_mv materialized view inserts into storage, data lands in sharded_events for durable - storage. + explanation: 'The flow is: App sends event, capture endpoint writes to Kafka, kafka_events reads from Kafka, events_mv materialized view inserts into storage, data lands in sharded_events for durable storage.' - id: ph-flow-p2 type: multiple_choice question: How does PostHog decide which ClickHouse shard to store an event on? @@ -2714,9 +2244,7 @@ concepts: - By hashing the distinct_id using sipHash64 - Based on the event timestamp correct: 2 - explanation: >- - PostHog shards events by sipHash64(distinct_id). This ensures all events for the same user land on the same shard, making person-level queries (like 'all events for user X') efficient - because they only need to hit one shard. + explanation: PostHog shards events by sipHash64(distinct_id). This ensures all events for the same user land on the same shard, making person-level queries (like 'all events for user X') efficient because they only need to hit one shard. - id: ph-flow-p3 type: multiple_choice question: In PostHog's ClickHouse architecture, which Distributed table handles writes, while reads go through the events Distributed table? @@ -2726,9 +2254,8 @@ concepts: - sharded_events - person_distinct_id_overrides correct: 1 - explanation: >- - writable_events is the Distributed table used for writes — it routes events to the correct shard. The events table is a separate Distributed table used for reads — it fans out queries to - all shards and aggregates results. + explanation: writable_events is the Distributed table used for writes — it routes events to the correct shard. The events table is a separate Distributed table used for reads — it fans out queries to all shards and aggregates results. + keyPrerequisite: ph-ingestion-pipeline section: posthog-ingestion - id: ph-clickhouse-storage name: ClickHouse Storage — Tables and Sharding @@ -2743,10 +2270,7 @@ concepts: encompassing: [] knowledgePoints: - id: table-roles - instruction: >- - PostHog's ClickHouse setup uses several tables with different jobs. `kafka_events` consumes from Kafka. `events_mv` is the materialized view that pushes records downstream. `sharded_events` - is the real durable storage table. `writable_events` and `events` are distributed access layers that sit in front of that storage. The point of learning these names is not memorization for - its own sake. It is being able to ask which layer is responsible when writes succeed, reads lag, or duplicates appear. + instruction: PostHog's ClickHouse setup uses several tables with different jobs. `kafka_events` consumes from Kafka. `events_mv` is the materialized view that pushes records downstream. `sharded_events` is the real durable storage table. `writable_events` and `events` are distributed access layers that sit in front of that storage. The point of learning these names is not memorization for its own sake. It is being able to ask which layer is responsible when writes succeed, reads lag, or duplicates appear. instructionContent: - type: link url: https://posthog.com/docs/how-posthog-works/clickhouse @@ -2772,33 +2296,26 @@ concepts: - ReplicatedReplacingMergeTree - Distributed correct: 2 - explanation: >- - ReplicatedReplacingMergeTree combines replication for durability, replacing behavior for eventual deduplication, and the MergeTree storage engine used for analytical workloads. + explanation: ReplicatedReplacingMergeTree combines replication for durability, replacing behavior for eventual deduplication, and the MergeTree storage engine used for analytical workloads. - id: ph-ch-p5 type: true_false question: In PostHog's ClickHouse architecture, kafka_events is where events are durably stored for long-term queries. correct: 'false' - explanation: >- - kafka_events is a Kafka consumer bridge — it reads events from Kafka and passes them downstream. Durable long-term storage is handled by sharded_events - (ReplicatedReplacingMergeTree). If you confused the two, the fix is to think of kafka_events as a pipeline stage, not a final destination. + explanation: kafka_events is a Kafka consumer bridge — it reads events from Kafka and passes them downstream. Durable long-term storage is handled by sharded_events (ReplicatedReplacingMergeTree). If you confused the two, the fix is to think of kafka_events as a pipeline stage, not a final destination. - id: ph-ch-p7 type: scenario - question: >- - A self-hosted PostHog customer reports that events captured in the last 5 minutes appear in the Activity log but do not show up in Trends or other insights. The Kafka consumer is running. Where in the ClickHouse table chain is the most likely bottleneck? + question: A self-hosted PostHog customer reports that events captured in the last 5 minutes appear in the Activity log but do not show up in Trends or other insights. The Kafka consumer is running. Where in the ClickHouse table chain is the most likely bottleneck? options: - The events table is full and rejecting new writes - Events are stuck in kafka_events and the materialized view (events_mv) that moves data to writable_events is likely failing or lagging - The sharded_events distributed table has lost connection to replica nodes - ClickHouse is performing a background merge and all reads are blocked correct: 1 - explanation: >- - The ClickHouse ingestion chain flows: kafka_events → events_mv (materialized view) → writable_events → sharded_events → events (distributed). If events appear in the Activity log (which may read from kafka_events or a fast path) but not in insights (which query the events distributed table), the bottleneck is most likely in the materialized view step. The events_mv transforms and inserts data from the Kafka table into writable_events. If this view is failing (e.g., due to schema mismatch, disk space, or a ClickHouse error), data accumulates in kafka_events but never reaches the queryable tables. + explanation: 'The ClickHouse ingestion chain flows: kafka_events → events_mv (materialized view) → writable_events → sharded_events → events (distributed). If events appear in the Activity log (which may read from kafka_events or a fast path) but not in insights (which query the events distributed table), the bottleneck is most likely in the materialized view step. The events_mv transforms and inserts data from the Kafka table into writable_events. If this view is failing (e.g., due to schema mismatch, disk space, or a ClickHouse error), data accumulates in kafka_events but never reaches the queryable tables.' difficulty: 5 + keyPrerequisite: ph-ingestion-pipeline - id: reads-writes-and-sharding - instruction: >- - The second key idea is separation of read and write paths. Writes go through `writable_events`, which chooses a shard by hashing `distinct_id`. Reads go through the `events` distributed - table, which fans queries out across shards and aggregates the results. That split matters because ingestion and querying have different optimization goals. Sharding by `distinct_id` also - keeps one user's events together, which helps person-level queries. + instruction: The second key idea is separation of read and write paths. Writes go through `writable_events`, which chooses a shard by hashing `distinct_id`. Reads go through the `events` distributed table, which fans queries out across shards and aggregates the results. That split matters because ingestion and querying have different optimization goals. Sharding by `distinct_id` also keeps one user's events together, which helps person-level queries. problems: - id: ph-ch-p2 type: multiple_choice @@ -2809,27 +2326,23 @@ concepts: - sharded_events directly - The events Distributed table correct: 3 - explanation: >- - If you chose `writable_events`, you mixed up the write path with the read path. Insights read through `events`, which fans queries across shards and assembles the result. + explanation: If you chose `writable_events`, you mixed up the write path with the read path. Insights read through `events`, which fans queries across shards and assembles the result. - id: ph-ch-p3 type: true_false question: In PostHog's ClickHouse setup, the same Distributed table is used for both reads and writes. correct: 'false' - explanation: >- - PostHog uses separate Distributed tables: `writable_events` for writes and `events` for reads. This allows different routing and optimization strategies for ingestion versus querying. + explanation: 'PostHog uses separate Distributed tables: `writable_events` for writes and `events` for reads. This allows different routing and optimization strategies for ingestion versus querying.' - id: ph-ch-p6 type: scenario - question: >- - A PostHog engineer mentions that querying all events for a single user is fast because of how data is sharded. Why is this the case? + question: A PostHog engineer mentions that querying all events for a single user is fast because of how data is sharded. Why is this the case? options: - PostHog caches all user queries in memory - Events are sharded by sipHash64(distinct_id), so all events for one user live on the same shard - ClickHouse reads all shards in parallel regardless of the query - User events are stored in a separate high-speed table correct: 1 - explanation: >- - Sharding by distinct_id ensures all events for the same user land on the same shard. A person-level query only needs to hit one shard instead of scanning all of them. This is a - deliberate design choice that optimizes the most common PostHog query pattern. + explanation: Sharding by distinct_id ensures all events for the same user land on the same shard. A person-level query only needs to hit one shard instead of scanning all of them. This is a deliberate design choice that optimizes the most common PostHog query pattern. + keyPrerequisite: ph-clickhouse-storage section: posthog-ingestion - id: ph-person-processing name: Person Processing — Resolving Events to Profiles @@ -2850,9 +2363,7 @@ concepts: weight: 0.65 knowledgePoints: - id: how-person-processing-works - instruction: >- - Person processing is the ingestion step where PostHog decides whether an event should link to an existing person, create a new one, or trigger a merge. That requires identity lookups, - possible writes, and sometimes profile reconciliation. Person data lives in PostgreSQL as the source of truth and is replicated into ClickHouse for query performance. + instruction: Person processing is the ingestion step where PostHog decides whether an event should link to an existing person, create a new one, or trigger a merge. That requires identity lookups, possible writes, and sometimes profile reconciliation. Person data lives in PostgreSQL as the source of truth and is replicated into ClickHouse for query performance. instructionContent: - type: link url: https://posthog.com/docs/how-posthog-works/ingestion-pipeline @@ -2868,14 +2379,12 @@ concepts: - It encrypts all person data with military-grade encryption - It runs machine learning models on every event correct: 1 - explanation: >- - Person processing is expensive because it may need to look up existing identity state, create or update person records, and merge profiles when IDs connect. + explanation: Person processing is expensive because it may need to look up existing identity state, create or update person records, and merge profiles when IDs connect. - id: ph-pp-p3 type: true_false question: Person data in PostHog is stored only in ClickHouse. correct: 'false' - explanation: >- - The misconception here is assuming all analytics state lives only in ClickHouse. Person data is authored in PostgreSQL, then replicated into ClickHouse so queries stay fast. + explanation: The misconception here is assuming all analytics state lives only in ClickHouse. Person data is authored in PostgreSQL, then replicated into ClickHouse so queries stay fast. - id: ph-pp-p5 type: multiple_choice question: Where does PostHog store person data as the source of truth before replicating it to ClickHouse? @@ -2885,28 +2394,21 @@ concepts: - PostgreSQL - Amazon S3 correct: 2 - explanation: >- - Person data is authored in PostgreSQL (the source of truth) and then replicated into ClickHouse for fast query performance. If you chose Kafka, that is the event buffer, not the - person store. The dual-storage design separates identity management (PostgreSQL) from analytical queries (ClickHouse). + explanation: Person data is authored in PostgreSQL (the source of truth) and then replicated into ClickHouse for fast query performance. If you chose Kafka, that is the event buffer, not the person store. The dual-storage design separates identity management (PostgreSQL) from analytical queries (ClickHouse). + keyPrerequisite: ph-ingestion-pipeline - id: cost-control-and-skip-rules - instruction: >- - Because person processing is expensive, PostHog can skip it when the event does not need person-level behavior. In `identified_only` mode, anonymous events with no identify, no `$set`, and - no group linkage skip person processing entirely. That makes this mode a good fit for high-volume anonymous traffic where the team still wants aggregate analytics but does not need person - profiles for every visitor. + instruction: Because person processing is expensive, PostHog can skip it when the event does not need person-level behavior. In `identified_only` mode, anonymous events with no identify, no `$set`, and no group linkage skip person processing entirely. That makes this mode a good fit for high-volume anonymous traffic where the team still wants aggregate analytics but does not need person profiles for every visitor. problems: - id: ph-pp-p2 type: scenario - question: >- - A customer is on PostHog Cloud and notices their bill is higher than expected. They have millions of anonymous pageview events from marketing landing pages where users never log in. What - configuration change could reduce their costs? + question: A customer is on PostHog Cloud and notices their bill is higher than expected. They have millions of anonymous pageview events from marketing landing pages where users never log in. What configuration change could reduce their costs? options: - 'Switch to person_profiles: ''always'' to create profiles for every visitor' - 'Switch to person_profiles: ''identified_only'' so anonymous events skip person processing' - Disable event capture entirely on landing pages - Move to self-hosted PostHog correct: 1 - explanation: >- - With `identified_only` mode, anonymous events skip person processing entirely. Since the landing page visitors never log in, their events do not need person profiles. + explanation: With `identified_only` mode, anonymous events skip person processing entirely. Since the landing page visitors never log in, their events do not need person profiles. - id: ph-pp-p4 type: multiple_choice question: Which event would skip person processing in identified_only mode? @@ -2916,15 +2418,13 @@ concepts: - A capture call that includes $set person properties - A group() call that links the session to a company correct: 0 - explanation: >- - In `identified_only` mode, plain anonymous events skip person processing. Events that identify, set person properties, or link groups need person-level handling and therefore do not skip it. + explanation: In `identified_only` mode, plain anonymous events skip person processing. Events that identify, set person properties, or link groups need person-level handling and therefore do not skip it. - id: ph-pp-p6 type: true_false question: In identified_only mode, a capture call that includes $set person properties will skip person processing just like a plain anonymous event. correct: 'false' - explanation: >- - Events with $set, identify, alias, or group linkage trigger person processing even in identified_only mode. Only plain anonymous events with no identification signals skip it. The - mode is about skipping processing for truly anonymous traffic, not for any event that lacks an identify() call. + explanation: Events with $set, identify, alias, or group linkage trigger person processing even in identified_only mode. Only plain anonymous events with no identification signals skip it. The mode is about skipping processing for truly anonymous traffic, not for any event that lacks an identify() call. + keyPrerequisite: ph-person-processing section: posthog-ingestion - id: anonymous-vs-identified name: Anonymous vs Identified Events @@ -2940,14 +2440,11 @@ concepts: encompassing: [] knowledgePoints: - id: two-modes-of-events - instruction: >- - Anonymous events have a distinct_id but no person profile. Identified events are linked to a person profile. Both can be captured and analyzed, but they unlock different capabilities. - Anonymous events are good for aggregate analytics. Identified events unlock person-scoped features such as feature flags, cohorts, experiments, and richer support workflows. + instruction: Anonymous events have a distinct_id but no person profile. Identified events are linked to a person profile. Both can be captured and analyzed, but they unlock different capabilities. Anonymous events are good for aggregate analytics. Identified events unlock person-scoped features such as feature flags, cohorts, experiments, and richer support workflows. instructionContent: - type: callout title: Shortcut - body: >- - Anonymous gets you aggregate analytics. Identified unlocks person-scoped features like feature flags, cohorts, and experiments. + body: Anonymous gets you aggregate analytics. Identified unlocks person-scoped features like feature flags, cohorts, and experiments. problems: - id: anon-id-p1 type: multiple_choice @@ -2958,14 +2455,12 @@ concepts: - Anonymous events are not stored; identified events are stored - Anonymous events are free; identified events cost extra per event correct: 1 - explanation: >- - Both anonymous and identified events have a distinct_id. The difference is whether a person profile exists behind that identity. + explanation: Both anonymous and identified events have a distinct_id. The difference is whether a person profile exists behind that identity. - id: anon-id-p2 type: true_false question: Anonymous events in PostHog cannot be used for any analysis at all. correct: 'false' - explanation: >- - Anonymous events are fully queryable for aggregate analysis. They simply do not support person-level features that require a person profile. + explanation: Anonymous events are fully queryable for aggregate analysis. They simply do not support person-level features that require a person profile. - id: anon-id-p5 type: matching question: Match each PostHog capability to whether it works with anonymous events or requires identified events. @@ -2975,13 +2470,10 @@ concepts: - Aggregate funnel conversion rates|Works with anonymous events - Cohort targeting by person properties|Requires identified events correct: 0,1,2,3 - explanation: >- - Aggregate analytics (pageview counts, funnel conversion rates) work with anonymous events because they do not need to know who each user is. Feature flags and cohort targeting require - person profiles, which means identified events. + explanation: Aggregate analytics (pageview counts, funnel conversion rates) work with anonymous events because they do not need to know who each user is. Feature flags and cohort targeting require person profiles, which means identified events. + keyPrerequisite: ph-person-processing - id: choosing-when-to-identify - instruction: >- - Most teams should use a hybrid pattern: capture anonymous browsing before login, then call identify after authentication. That preserves cheap pre-login analytics while still unlocking - person-level capabilities for known users. The right moment to identify is when you can reliably say which human is behind the session. + instruction: 'Most teams should use a hybrid pattern: capture anonymous browsing before login, then call identify after authentication. That preserves cheap pre-login analytics while still unlocking person-level capabilities for known users. The right moment to identify is when you can reliably say which human is behind the session.' instructionContent: - type: link url: https://posthog.com/docs/getting-started/identify-users @@ -2997,15 +2489,13 @@ concepts: - Switch to a different analytics tool - Create a custom event called 'feature_flag_check' correct: 1 - explanation: >- - Feature flags require person profiles to decide which variant to serve. The company must identify users after login so those profiles exist. + explanation: Feature flags require person profiles to decide which variant to serve. The company must identify users after login so those profiles exist. - id: anon-id-p6 type: true_false question: The best practice is to identify users as early as possible, even before they authenticate, to capture the most data. correct: 'false' - explanation: >- - Identifying before authentication risks linking anonymous browsing to the wrong person. The best practice is to call identify() after successful authentication, when you can reliably - confirm which human is behind the session. Pre-login events are still captured with the anonymous distinct_id and get linked once identify runs. + explanation: Identifying before authentication risks linking anonymous browsing to the wrong person. The best practice is to call identify() after successful authentication, when you can reliably confirm which human is behind the session. Pre-login events are still captured with the anonymous distinct_id and get linked once identify runs. + keyPrerequisite: anonymous-vs-identified section: identification - id: identify-call name: The Identify Call @@ -3022,28 +2512,22 @@ concepts: weight: 0.6 knowledgePoints: - id: how-identify-works - instruction: >- - The identify() call is the bridge between anonymous and identified tracking. It links the current anonymous distinct_id to a known ID, creates or reuses the person profile, and applies - person-property updates from the arguments you pass. After identify runs on the client, subsequent events from that device use the identified distinct_id instead of the anonymous one. + instruction: The identify() call is the bridge between anonymous and identified tracking. It links the current anonymous distinct_id to a known ID, creates or reuses the person profile, and applies person-property updates from the arguments you pass. After identify runs on the client, subsequent events from that device use the identified distinct_id instead of the anonymous one. instructionContent: - type: callout title: Three things happen at once - body: >- - identify links the anonymous browser id to a known id, creates or reuses the person, and updates person properties. + body: identify links the anonymous browser id to a known id, creates or reuses the person, and updates person properties. - type: link url: https://posthog.com/docs/product-analytics/identify title: Identify docs with SDK examples description: Useful for comparing frontend and backend identify behavior side by side. - workedExample: >- - User visits your site. The JS SDK generates distinct_id 'abc-random'. They browse several pages. Then they sign up and your code runs posthog.identify('user_42', { email: 'jane@co.com', - plan: 'free' }). PostHog links the anonymous browsing to user_42, stores both IDs on the same person, and updates the profile properties. + workedExample: 'User visits your site. The JS SDK generates distinct_id ''abc-random''. They browse several pages. Then they sign up and your code runs posthog.identify(''user_42'', { email: ''jane@co.com'', plan: ''free'' }). PostHog links the anonymous browsing to user_42, stores both IDs on the same person, and updates the profile properties.' problems: - id: identify-p3 type: true_false question: After calling posthog.identify(), the SDK continues using the original anonymous distinct_id for subsequent events. correct: 'false' - explanation: >- - After identify(), the SDK switches its internal distinct_id to the one you provided. Subsequent events use the known ID, not the original anonymous one. + explanation: After identify(), the SDK switches its internal distinct_id to the one you provided. Subsequent events use the known ID, not the original anonymous one. - id: identify-p4 type: multiple_choice question: The second argument to posthog.identify('user_id', { ... }) sets person properties using which semantics? @@ -3053,8 +2537,7 @@ concepts: - $set - It does not set person properties correct: 2 - explanation: >- - Properties passed in the second argument of identify() use `$set` semantics, meaning they overwrite the current value on the person profile. + explanation: Properties passed in the second argument of identify() use `$set` semantics, meaning they overwrite the current value on the person profile. - id: identify-p5 type: multiple_choice question: What happens to the anonymous distinct_id after posthog.identify('user_42') is called on the frontend? @@ -3064,14 +2547,10 @@ concepts: - The anonymous ID continues to be used for all future events - A new random anonymous ID is generated correct: 1 - explanation: >- - identify() links the anonymous ID and the known ID on the same person profile. After the call, the SDK switches to using the known ID for subsequent events. The anonymous ID is - preserved as an additional distinct_id on the person, not deleted. + explanation: identify() links the anonymous ID and the known ID on the same person profile. After the call, the SDK switches to using the known ID for subsequent events. The anonymous ID is preserved as an additional distinct_id on the person, not deleted. + keyPrerequisite: anonymous-vs-identified - id: identify-best-practices - instruction: >- - The main risks with identify are timing and identifier quality. Call identify after successful authentication and on each authenticated app load so the client re-establishes the correct - person context. Use a stable ID that uniquely represents one human being, usually your database user ID. Shared emails or generic account IDs create "frankenstein" profiles by merging - unrelated people together. + instruction: The main risks with identify are timing and identifier quality. Call identify after successful authentication and on each authenticated app load so the client re-establishes the correct person context. Use a stable ID that uniquely represents one human being, usually your database user ID. Shared emails or generic account IDs create "frankenstein" profiles by merging unrelated people together. problems: - id: identify-p1 type: multiple_choice @@ -3082,28 +2561,23 @@ concepts: - Only on the very first visit ever - Never — PostHog identifies users automatically correct: 1 - explanation: >- - Call identify() every time your app initializes for an authenticated user and directly after login or signup. The SDK deduplicates redundant calls, so this is safe. + explanation: Call identify() every time your app initializes for an authenticated user and directly after login or signup. The SDK deduplicates redundant calls, so this is safe. - id: identify-p2 type: scenario - question: >- - A customer calls posthog.identify() with the user's email address as the distinct_id. Two users at the same company share a team email (team@acme.com) and both call identify with it. - What happens? + question: A customer calls posthog.identify() with the user's email address as the distinct_id. Two users at the same company share a team email (team@acme.com) and both call identify with it. What happens? options: - PostHog creates two separate person profiles with the same email - PostHog merges both users into one person profile, combining all their events — creating a single 'frankenstein' profile - PostHog rejects the second identify call - Nothing unusual — email is a safe identifier correct: 1 - explanation: >- - If two different anonymous users both identify as the same shared email, PostHog merges them into one person. Use stable unique user IDs instead of shared identifiers. + explanation: If two different anonymous users both identify as the same shared email, PostHog merges them into one person. Use stable unique user IDs instead of shared identifiers. - id: identify-p6 type: true_false question: Calling posthog.identify() on every authenticated page load is wasteful and should be avoided. correct: 'false' - explanation: >- - Calling identify() on every authenticated app load is the recommended practice. The SDK deduplicates redundant calls, so there is no meaningful overhead. This ensures the correct - person context is always re-established, even if the user returns after their session state was cleared. + explanation: Calling identify() on every authenticated app load is the recommended practice. The SDK deduplicates redundant calls, so there is no meaningful overhead. This ensures the correct person context is always re-established, even if the user returns after their session state was cleared. + keyPrerequisite: identify-call section: identification - id: person-merging name: Person Merging — Linking Identities @@ -3123,22 +2597,18 @@ concepts: weight: 0.45 knowledgePoints: - id: how-merging-works - instruction: >- + instruction: |- When you call identify("known-id"), PostHog checks if the current anonymous distinct_id and the known-id already have separate person profiles. If they do, PostHog **merges them into one profile** — combining all events, person properties, and distinct_ids from both profiles. - **Merge rules:** the most recent value wins for each person property. All distinct_ids from both profiles are linked to the surviving profile. Historical events are re-attributed. - You can also use **alias("id-a", "id-b")** to explicitly link two IDs without changing the current session's distinct_id. This is useful for connecting IDs across systems, like linking a Stripe customer ID to a PostHog user ID. - **Reversibility:** merges can be partially reversed using the "Split IDs" feature on person profiles, which splits distinct_ids so future events go to separate profiles. However, historical events are not re-attributed — so it is still critical to use correct, unique identifiers from the start. instructionContent: - type: callout title: Merge effect - body: >- - Merging is not just "link these IDs." It can change which profile survives, which properties win, and how history appears on the final person record. + body: Merging is not just "link these IDs." It can change which profile survives, which properties win, and how history appears on the final person record. - type: link url: https://posthog.com/docs/data/persons title: Persons merge behavior docs @@ -3156,9 +2626,7 @@ concepts: explanation: Merging combines all events from both profiles into one. No events are deleted or lost. The merged profile has the complete event history from both original profiles. - id: merge-p2 type: scenario - question: >- - User browses anonymously (distinct_id: anon-123, person profile A with 10 events). Then logs in and you call identify('user_42'). User_42 already has a person profile B from a previous - session with 5 events. What is the final state? + question: 'User browses anonymously (distinct_id: anon-123, person profile A with 10 events). Then logs in and you call identify(''user_42''). User_42 already has a person profile B from a previous session with 5 events. What is the final state?' options: - Two separate profiles remain - 'One merged profile with 15 events and distinct_ids: anon-123 and user_42' @@ -3170,23 +2638,18 @@ concepts: type: true_false question: Once two person profiles are merged in PostHog, they can be unmerged if the merge was a mistake. correct: 'true' - explanation: >- - PostHog provides a 'Split IDs' button on person profiles that lets you split previously merged distinct_ids back into separate users. While historical events are not re-attributed, future - events will go to separate profiles. That said, merges are still risky — use unique, stable identifiers in identify() calls to avoid bad merges in the first place. + explanation: PostHog provides a 'Split IDs' button on person profiles that lets you split previously merged distinct_ids back into separate users. While historical events are not re-attributed, future events will go to separate profiles. That said, merges are still risky — use unique, stable identifiers in identify() calls to avoid bad merges in the first place. + keyPrerequisite: identify-call - id: when-merging-goes-wrong - instruction: >- + instruction: |- Person merging is powerful but dangerous when misused. Three common mistakes cause bad merges: - **(1) Identifying with a shared or generic ID:** calling identify("support@company.com") for multiple users merges all of them into one profile. Always use an ID that uniquely identifies one human being — typically a database user ID. - **(2) Identifying before authentication:** if you call identify() based on a form input before the user actually logs in, you might associate anonymous browsing with the wrong person. Only call identify() after successful authentication. - **(3) Mismatched IDs across client and server:** if your frontend uses "user_42" but your backend uses "u-42" for the same person, PostHog sees them as different users and creates separate profiles. Use the same canonical ID everywhere. - **The golden rule:** the distinct_id you pass to identify() must uniquely and permanently identify exactly one human being. When in doubt, use database primary keys. instructionContent: - type: link @@ -3203,36 +2666,29 @@ concepts: - The user's company name - The user's IP address correct: 1 - explanation: >- - Database primary keys are unique per user, stable over time, and not shared. Emails can be shared (team accounts), company names are definitely shared, and IP addresses change and are - shared across users on the same network. + explanation: Database primary keys are unique per user, stable over time, and not shared. Emails can be shared (team accounts), company names are definitely shared, and IP addresses change and are shared across users on the same network. - id: merge-wrong-p2 type: scenario - question: >- - A customer's support team all log into PostHog-tracked admin panel using a shared 'admin@company.com' account. They call posthog.identify('admin@company.com') on login. After a month, - they notice all support agents' actions appear under a single person profile. Why? + question: A customer's support team all log into PostHog-tracked admin panel using a shared 'admin@company.com' account. They call posthog.identify('admin@company.com') on login. After a month, they notice all support agents' actions appear under a single person profile. Why? options: - PostHog has a bug with email-based identification - All agents identified with the same ID, so PostHog merged all their anonymous profiles into one person - The admin panel is not compatible with PostHog - PostHog only supports one user per email domain correct: 1 - explanation: >- - Every agent's anonymous distinct_id was linked to 'admin@company.com' via identify(). PostHog dutifully merged them all into one person profile. The fix: each agent should identify with - their own unique ID, not a shared account. + explanation: 'Every agent''s anonymous distinct_id was linked to ''admin@company.com'' via identify(). PostHog dutifully merged them all into one person profile. The fix: each agent should identify with their own unique ID, not a shared account.' - id: merge-wrong-p3 type: scenario - question: >- - A customer's React app calls posthog.identify(user.id) in a useEffect hook that runs on every page load, using the user object from their auth context. On the login page, before authentication completes, user.id is undefined. Users report seeing other people's feature flag values briefly after logging in. What is happening? + question: A customer's React app calls posthog.identify(user.id) in a useEffect hook that runs on every page load, using the user object from their auth context. On the login page, before authentication completes, user.id is undefined. Users report seeing other people's feature flag values briefly after logging in. What is happening? options: - PostHog's feature flag cache is stale and needs to be refreshed - Calling identify(undefined) before auth completes links all pre-auth anonymous users to a single 'undefined' profile, causing cross-user contamination - The useEffect hook is running twice due to React strict mode - Feature flags are being evaluated server-side with the wrong API key correct: 1 - explanation: >- - When identify() is called with undefined or null, PostHog treats it as a literal identifier. All users who hit the login page before authenticating get identified as the same 'undefined' person, merging their anonymous profiles together. This causes feature flag values, person properties, and analytics to bleed across users. The fix: only call identify() after authentication succeeds and you have a valid, unique user ID. Guard the call: `if (user?.id) posthog.identify(user.id)`. + explanation: 'When identify() is called with undefined or null, PostHog treats it as a literal identifier. All users who hit the login page before authenticating get identified as the same ''undefined'' person, merging their anonymous profiles together. This causes feature flag values, person properties, and analytics to bleed across users. The fix: only call identify() after authentication succeeds and you have a valid, unique user ID. Guard the call: `if (user?.id) posthog.identify(user.id)`.' difficulty: 5 + keyPrerequisite: person-merging section: identification - id: person-modes name: Person Modes — identified_only vs Always @@ -3247,9 +2703,7 @@ concepts: encompassing: [] knowledgePoints: - id: choosing-a-mode - instruction: >- - The `person_profiles` mode controls when person profiles are created. `identified_only` creates them only after explicit identification and is the recommended default for most setups. - `always` creates a person profile for every distinct_id, including anonymous visitors. The choice is a tradeoff between lower cost and broader anonymous-user capabilities. + instruction: The `person_profiles` mode controls when person profiles are created. `identified_only` creates them only after explicit identification and is the recommended default for most setups. `always` creates a person profile for every distinct_id, including anonymous visitors. The choice is a tradeoff between lower cost and broader anonymous-user capabilities. instructionContent: - type: link url: https://posthog.com/docs/data/persons @@ -3265,61 +2719,48 @@ concepts: - '''never'' — to avoid creating any person profiles' - '''auto'' — to let PostHog decide automatically' correct: 1 - explanation: >- - `identified_only` is recommended for most use cases because it creates person profiles only when you explicitly identify users. + explanation: '`identified_only` is recommended for most use cases because it creates person profiles only when you explicitly identify users.' - id: modes-p3 type: scenario - question: >- - A high-traffic news website has millions of anonymous visitors per day but only 50,000 registered users. They want to use feature flags for registered users only. Which person_profiles - mode should they use? + question: A high-traffic news website has millions of anonymous visitors per day but only 50,000 registered users. They want to use feature flags for registered users only. Which person_profiles mode should they use? options: - '''always'' — to create profiles for all visitors' - '''identified_only'' — to create profiles only for the 50,000 registered users who identify' - Disable PostHog on pages without login - Use both modes simultaneously correct: 1 - explanation: >- - `identified_only` is ideal here. The anonymous visitors get cheap event tracking without person processing, while identified users still get full person-level features. + explanation: '`identified_only` is ideal here. The anonymous visitors get cheap event tracking without person processing, while identified users still get full person-level features.' - id: modes-p5 type: true_false question: In 'always' mode, PostHog creates a person profile for every distinct_id, including completely anonymous visitors who never log in. correct: 'true' - explanation: >- - 'always' mode creates a person profile for every distinct_id, regardless of whether the user is identified. This enables person-level features for anonymous users but increases cost. - If you answered false, you may have been thinking of identified_only mode, which is the opposite behavior. + explanation: '''always'' mode creates a person profile for every distinct_id, regardless of whether the user is identified. This enables person-level features for anonymous users but increases cost. If you answered false, you may have been thinking of identified_only mode, which is the opposite behavior.' + keyPrerequisite: anonymous-vs-identified - id: mode-gotchas - instruction: >- - The biggest gotcha is assuming inline `$set` on a capture call will create a profile in `identified_only` mode. It will not. You still need an identification trigger such as identify, alias, - group, or the dedicated person-property helper. Use `always` only when you truly need person-level features for anonymous users before login. - workedExample: >- - A team sends anonymous `$pageview` events with inline `$set` for `email` and expects feature flags to work before login in `identified_only` mode. They still have no person profile because - they never triggered identification. The write looked person-shaped, but the identity step never happened. + instruction: The biggest gotcha is assuming inline `$set` on a capture call will create a profile in `identified_only` mode. It will not. You still need an identification trigger such as identify, alias, group, or the dedicated person-property helper. Use `always` only when you truly need person-level features for anonymous users before login. + workedExample: A team sends anonymous `$pageview` events with inline `$set` for `email` and expects feature flags to work before login in `identified_only` mode. They still have no person profile because they never triggered identification. The write looked person-shaped, but the identity step never happened. problems: - id: modes-p4 type: scenario - question: >- - A consumer app needs to evaluate feature flags for anonymous visitors before signup. Which person_profiles mode is the better fit? + question: A consumer app needs to evaluate feature flags for anonymous visitors before signup. Which person_profiles mode is the better fit? options: - identified_only - always - neither, because feature flags never work for anonymous users - a mix of both in the same project correct: 1 - explanation: >- - If you need person-level capabilities for anonymous visitors before signup, `always` is the better fit because it creates person profiles for every distinct_id. + explanation: If you need person-level capabilities for anonymous visitors before signup, `always` is the better fit because it creates person profiles for every distinct_id. - id: modes-p6 type: scenario - question: >- - A team sends anonymous $pageview events with $set: { email: 'test@example.com' } but they are in identified_only mode. They expect the email to appear on a person profile. Why does it not? + question: 'A team sends anonymous $pageview events with $set: { email: ''test@example.com'' } but they are in identified_only mode. They expect the email to appear on a person profile. Why does it not?' options: - $set does not work with email properties - In identified_only mode, inline $set on a capture call does not create a person profile without an identification trigger - The email format is invalid - Person properties only work on mobile SDKs correct: 1 - explanation: >- - This is the biggest gotcha of identified_only mode. Inline $set on a capture call does not trigger person profile creation. The team needs an identification trigger (identify, alias, - group, or the dedicated person-property helper) to create the profile first. + explanation: This is the biggest gotcha of identified_only mode. Inline $set on a capture call does not trigger person profile creation. The team needs an identification trigger (identify, alias, group, or the dedicated person-property helper) to create the profile first. + keyPrerequisite: person-modes section: identification - id: identification-pitfalls name: Common Identification Pitfalls @@ -3335,41 +2776,32 @@ concepts: encompassing: [] knowledgePoints: - id: duplicate-profiles-across-devices - instruction: >- + instruction: |- **Duplicate person profiles** — two or more profiles representing the same real human — are the most common identification problem. - The first version of this problem is **missed identification across devices or platforms**. A user logs in on desktop and gets identified there, but uses the mobile app or another browser without an identify call. That second surface keeps generating anonymous activity under a different distinct_id, so PostHog sees two separate people. - **The operational rule:** if the same real user can authenticate on multiple surfaces, identify them on every one of those surfaces after authentication. instructionContent: - type: callout title: Same human, different surface - body: >- - If one device identifies and another never does, the data model has no reason to treat them as the same person. + body: If one device identifies and another never does, the data model has no reason to treat them as the same person. problems: - id: pitfall-dup-p1 type: scenario - question: >- - A SaaS customer has both a web app and a mobile app. Users log in on the web app (posthog.identify('user_42') is called), but the mobile app only captures events with the auto-generated - anonymous distinct_id. What problem will they see in PostHog? + question: A SaaS customer has both a web app and a mobile app. Users log in on the web app (posthog.identify('user_42') is called), but the mobile app only captures events with the auto-generated anonymous distinct_id. What problem will they see in PostHog? options: - Missing events from the mobile app - Duplicate person profiles — one identified from web, one anonymous from mobile, for the same user - Events from both platforms merged correctly - Error messages in the PostHog UI correct: 1 - explanation: >- - Without identify() on mobile, the mobile events create a separate anonymous profile. The same user now has two profiles: one identified from web and one anonymous from mobile. Fix: call - identify() on the mobile app after authentication. + explanation: 'Without identify() on mobile, the mobile events create a separate anonymous profile. The same user now has two profiles: one identified from web and one anonymous from mobile. Fix: call identify() on the mobile app after authentication.' - id: pitfall-dup-p4 type: true_false question: If a user is identified on the web app, PostHog will automatically connect their mobile anonymous events even if the mobile app never calls identify(). correct: 'false' - explanation: >- - PostHog cannot assume the mobile anonymous ID belongs to the same person unless the mobile app also identifies that user. If you answered true, the likely miss was assuming identity - propagates automatically across platforms. + explanation: PostHog cannot assume the mobile anonymous ID belongs to the same person unless the mobile app also identifies that user. If you answered true, the likely miss was assuming identity propagates automatically across platforms. - id: pitfall-dup-p5 type: multiple_choice question: What is the operational rule for preventing duplicate profiles across devices? @@ -3379,34 +2811,27 @@ concepts: - Use different distinct_ids for each device so PostHog can match them by IP - Disable anonymous tracking on all devices except the primary one correct: 1 - explanation: >- - If the same real user can authenticate on multiple surfaces, identify them on every one of those surfaces after authentication. This links all device-specific anonymous IDs to the - same known identity. PostHog does not infer cross-device identity from IP addresses. + explanation: If the same real user can authenticate on multiple surfaces, identify them on every one of those surfaces after authentication. This links all device-specific anonymous IDs to the same known identity. PostHog does not infer cross-device identity from IP addresses. + keyPrerequisite: person-merging - id: canonical-ids-across-systems - instruction: >- - The second version of duplicate profiles comes from inconsistent IDs across systems. If the web app uses email, the mobile app uses database ID, and the backend uses another string format, - PostHog receives several unrelated identifiers and cannot safely infer they belong to one person. The fix is to choose one canonical identifier, usually the database primary key, and reuse - that exact string everywhere. "Close enough" IDs are still different IDs. + instruction: The second version of duplicate profiles comes from inconsistent IDs across systems. If the web app uses email, the mobile app uses database ID, and the backend uses another string format, PostHog receives several unrelated identifiers and cannot safely infer they belong to one person. The fix is to choose one canonical identifier, usually the database primary key, and reuse that exact string everywhere. "Close enough" IDs are still different IDs. instructionContent: - type: link url: https://posthog.com/docs/getting-started/identify-users title: Identify users guide description: Official implementation guide for consistent IDs across SDKs and platforms. - workedExample: >- - If the frontend identifies with `user_42`, the backend should also capture with `user_42`, not `usr-42` and not `alice@example.com`. The real job is consistency, not human readability. + workedExample: If the frontend identifies with `user_42`, the backend should also capture with `user_42`, not `usr-42` and not `alice@example.com`. The real job is consistency, not human readability. problems: - id: pitfall-dup-p2 type: scenario - question: >- - A B2B SaaS company uses email addresses as the distinct_id in their identify() calls. Support agents sometimes log in to customer accounts to troubleshoot issues. The product team notices that some customer profiles have merged with support agent profiles. What is the root cause, and what identifier should they use instead? + question: A B2B SaaS company uses email addresses as the distinct_id in their identify() calls. Support agents sometimes log in to customer accounts to troubleshoot issues. The product team notices that some customer profiles have merged with support agent profiles. What is the root cause, and what identifier should they use instead? options: - Email is not unique enough — use phone numbers instead - The support agents' events are merging profiles because identify() links the agent's anonymous ID to the customer's email — use an internal database user ID instead of email - PostHog's merge algorithm has a bug with shared email domains - The support agents should use incognito mode to prevent profile merges correct: 1 - explanation: >- - When a support agent logs into a customer account and identify() fires with the customer's email, PostHog merges the agent's anonymous profile with the customer's profile. This is working as designed — identify() assumes the anonymous user IS the identified user. The fix: use an immutable, unique database primary key (like user_id from your database) as the distinct_id, not email. Additionally, support tools should use a separate PostHog project or be excluded from tracking. + explanation: 'When a support agent logs into a customer account and identify() fires with the customer''s email, PostHog merges the agent''s anonymous profile with the customer''s profile. This is working as designed — identify() assumes the anonymous user IS the identified user. The fix: use an immutable, unique database primary key (like user_id from your database) as the distinct_id, not email. Additionally, support tools should use a separate PostHog project or be excluded from tracking.' difficulty: 5 - id: pitfall-dup-p3 type: scenario @@ -3417,59 +2842,43 @@ concepts: - The backend event is rejected - PostHog merges them based on IP address correct: 1 - explanation: >- - 'user_42' and 'usr-42' are different strings, so PostHog treats them as different users. Two profiles are created. Fix: use the exact same ID string ('user_42') in both the frontend - identify() call and the backend capture() call. + explanation: '''user_42'' and ''usr-42'' are different strings, so PostHog treats them as different users. Two profiles are created. Fix: use the exact same ID string (''user_42'') in both the frontend identify() call and the backend capture() call.' - id: pitfall-dup-p6 type: true_false question: Using 'user_42' on the frontend and 'USER_42' on the backend is safe because PostHog treats distinct_ids as case-insensitive. correct: 'false' - explanation: >- - PostHog treats distinct_ids as exact string matches. 'user_42' and 'USER_42' are different identifiers and will create separate person profiles. Use the exact same canonical string - everywhere — case, formatting, and all. + explanation: PostHog treats distinct_ids as exact string matches. 'user_42' and 'USER_42' are different identifiers and will create separate person profiles. Use the exact same canonical string everywhere — case, formatting, and all. + keyPrerequisite: identify-call - id: cross-device-gaps - instruction: >- + instruction: |- Server-side SDKs do not have a browser session or auto-generated distinct_id. You must always provide a distinct_id explicitly. - **The common gap:** a user browses anonymously on the web (distinct_id = "abc-random"), then your server captures a backend event with their database ID ("user_42") before the frontend calls identify(). Those events will not link because PostHog has not been told that "abc-random" and "user_42" are the same person. - **The solution:** always call identify() on the frontend first. Once the frontend SDK knows the user is "user_42," subsequent events from both frontend and backend use the same identity. - **For fully server-side applications** (no frontend): use the database user ID as distinct_id from the start — there is no anonymous phase. - **For mobile apps with server-side components:** ensure the mobile app passes its known user ID to the server, and the server uses that same ID in capture() calls. - **The key principle:** identification flows from the client to the server, not the other way around. The client knows who the user is after login, and the server should use the same identifier. - workedExample: >- - If the backend sends `user_created` for `user_42` before the browser identifies its anonymous UUID as `user_42`, you briefly have two identity tracks. The frontend identify call is what - closes that gap and merges the histories. + workedExample: If the backend sends `user_created` for `user_42` before the browser identifies its anonymous UUID as `user_42`, you briefly have two identity tracks. The frontend identify call is what closes that gap and merges the histories. problems: - id: pitfall-xdev-p1 type: scenario - question: >- - A user signs up on your website. Your backend immediately sends a 'user_created' event via the Node.js SDK with distinct_id = 'user_42'. One second later, the frontend calls - posthog.identify('user_42'). Will the pre-signup anonymous browsing events link to 'user_42'? + question: A user signs up on your website. Your backend immediately sends a 'user_created' event via the Node.js SDK with distinct_id = 'user_42'. One second later, the frontend calls posthog.identify('user_42'). Will the pre-signup anonymous browsing events link to 'user_42'? options: - Yes — the backend event establishes the link - Yes — but only after identify() is called on the frontend - No — the backend event creates a separate profile for 'user_42' and the frontend anonymous events stay orphaned until identify() runs and merges them - No — backend events cannot be linked to frontend events correct: 2 - explanation: >- - The backend event creates a person profile for 'user_42'. When the frontend calls identify('user_42') one second later, PostHog merges the anonymous frontend profile with 'user_42'. The - events do link — but only because identify() runs on the frontend. If identify() never ran, the anonymous browsing would remain separate. + explanation: The backend event creates a person profile for 'user_42'. When the frontend calls identify('user_42') one second later, PostHog merges the anonymous frontend profile with 'user_42'. The events do link — but only because identify() runs on the frontend. If identify() never ran, the anonymous browsing would remain separate. - id: pitfall-xdev-p2 type: true_false question: For fully server-side applications with no frontend (e.g., a CLI tool), you should still use random anonymous distinct_ids and call identify() later. correct: 'false' - explanation: >- - For fully server-side applications, there is no anonymous phase. Use the database user ID as distinct_id from the start in every capture() call. There is no need for random IDs or - identify() because you always know who the user is on the server. + explanation: For fully server-side applications, there is no anonymous phase. Use the database user ID as distinct_id from the start in every capture() call. There is no need for random IDs or identify() because you always know who the user is on the server. - id: pitfall-xdev-p3 type: multiple_choice question: What is the correct order for linking frontend and backend events for the same user? @@ -3479,9 +2888,8 @@ concepts: - Both can happen in any order — PostHog handles it automatically - Frontend and backend events cannot be linked correct: 1 - explanation: >- - The safest pattern: frontend calls identify() first (linking anonymous browsing to the known ID), then the backend uses the same known ID in all capture() calls. This ensures all events - — anonymous frontend, identified frontend, and backend — are linked to one person. + explanation: 'The safest pattern: frontend calls identify() first (linking anonymous browsing to the known ID), then the backend uses the same known ID in all capture() calls. This ensures all events — anonymous frontend, identified frontend, and backend — are linked to one person.' + keyPrerequisite: identification-pitfalls section: identification - id: group-types name: Group Types — Modeling Organizations @@ -3498,9 +2906,7 @@ concepts: encompassing: [] knowledgePoints: - id: what-are-groups - instruction: >- - Groups let you associate events with entities beyond individual users, usually companies, teams, projects, or workspaces. In B2B analytics that matters because the important question is - often "which account used the feature?" rather than "which user clicked?" A group type defines the kind of higher-level entity you want to analyze. + instruction: Groups let you associate events with entities beyond individual users, usually companies, teams, projects, or workspaces. In B2B analytics that matters because the important question is often "which account used the feature?" rather than "which user clicked?" A group type defines the kind of higher-level entity you want to analyze. instructionContent: - type: link url: https://posthog.com/docs/product-analytics/group-analytics @@ -3516,8 +2922,7 @@ concepts: - To group similar events into actions - To create user segments for email marketing correct: 1 - explanation: >- - Group analytics lets you associate events with higher-level entities such as companies or projects so you can analyze behavior at the organization level. + explanation: Group analytics lets you associate events with higher-level entities such as companies or projects so you can analyze behavior at the organization level. - id: groups-p2 type: multiple_choice question: How many group types does PostHog allow per project? @@ -3527,44 +2932,36 @@ concepts: - '10' - Unlimited correct: 1 - explanation: >- - PostHog allows up to 5 group types per project. If you picked a higher number, the likely miss was treating groups like free-form tags instead of a constrained part of the data model. + explanation: PostHog allows up to 5 group types per project. If you picked a higher number, the likely miss was treating groups like free-form tags instead of a constrained part of the data model. - id: groups-p5 type: scenario - question: >- - A B2B customer asks: 'Can I use person properties to store company_name on each user and then aggregate by company?' What is the limitation of this approach compared to group analytics? + question: 'A B2B customer asks: ''Can I use person properties to store company_name on each user and then aggregate by company?'' What is the limitation of this approach compared to group analytics?' options: - There is no limitation — person properties work just as well - Person properties require you to duplicate company data on every user and cannot natively count unique companies or filter insights by company-level attributes - Person properties are more expensive than group analytics - Person properties do not support string values correct: 1 - explanation: >- - Storing company_name as a person property duplicates the data on every user and does not give you a real company entity to aggregate over. Group analytics creates a proper company - entity with its own properties, enabling questions like 'how many companies used feature X?' without duplication. + explanation: Storing company_name as a person property duplicates the data on every user and does not give you a real company entity to aggregate over. Group analytics creates a proper company entity with its own properties, enabling questions like 'how many companies used feature X?' without duplication. + keyPrerequisite: ph-persons - id: modeling-with-groups - instruction: >- - A good group type represents a real entity you want to aggregate over, not just another label. Company, team, or workspace are strong candidates when multiple users belong to the same - higher-level account. Groups are also a paid capability, so TAMs need to connect the modeling choice to the customer's B2B reporting needs. + instruction: A good group type represents a real entity you want to aggregate over, not just another label. Company, team, or workspace are strong candidates when multiple users belong to the same higher-level account. Groups are also a paid capability, so TAMs need to connect the modeling choice to the customer's B2B reporting needs. problems: - id: groups-p3 type: true_false question: Group analytics is included in all PostHog plans at no additional cost. correct: 'false' - explanation: >- - If you answered true because the use case feels core to B2B analytics, that is a packaging mistake rather than a modeling one. Group analytics is a paid capability, so plan fit matters. + explanation: If you answered true because the use case feels core to B2B analytics, that is a packaging mistake rather than a modeling one. Group analytics is a paid capability, so plan fit matters. - id: groups-p4 type: scenario - question: >- - A B2B SaaS customer wants to answer "how many companies used feature X this month?" even when multiple users from the same account used it. What is the right modeling tool? + question: A B2B SaaS customer wants to answer "how many companies used feature X this month?" even when multiple users from the same account used it. What is the right modeling tool? options: - Person properties only - Group analytics with a company group type - Actions only - Session properties correct: 1 - explanation: >- - This is the core use case for group analytics. You need a company-level entity so multiple users can roll up to the same account. + explanation: This is the core use case for group analytics. You need a company-level entity so multiple users can roll up to the same account. - id: groups-p6 type: multiple_choice question: Which of the following is NOT a good candidate for a PostHog group type? @@ -3574,9 +2971,8 @@ concepts: - Browser (a property of each event, not a multi-user entity) - Team (multiple users belong to one team) correct: 2 - explanation: >- - Browser is an event-level property, not a higher-level entity that multiple users belong to. Group types should represent real organizational entities where you want to aggregate - user behavior. Company, Workspace, and Team are all valid because multiple users share them. + explanation: Browser is an event-level property, not a higher-level entity that multiple users belong to. Group types should represent real organizational entities where you want to aggregate user behavior. Company, Workspace, and Team are all valid because multiple users share them. + keyPrerequisite: group-types section: group-analytics - id: group-identify name: Group Identify & Group Properties @@ -3596,9 +2992,7 @@ concepts: weight: 0.45 knowledgePoints: - id: creating-groups-and-properties - instruction: >- - Group identify creates or updates the group profile and, in the frontend SDK, also sets the current session's group context. In the JS web SDK, `posthog.group('company', 'acme-inc', {...})` - associates subsequent events with that company and updates its group properties. Group properties persist on the group profile the same way person properties persist on a person. + instruction: Group identify creates or updates the group profile and, in the frontend SDK, also sets the current session's group context. In the JS web SDK, `posthog.group('company', 'acme-inc', {...})` associates subsequent events with that company and updates its group properties. Group properties persist on the group profile the same way person properties persist on a person. instructionContent: - type: link url: https://posthog.com/docs/product-analytics/group-analytics @@ -3614,35 +3008,26 @@ concepts: - Creates a person profile with company name 'acme-inc' - Sends an email notification to the acme-inc team correct: 1 - explanation: >- - If you chose a person-profile answer, you collapsed company identity into user identity. `group()` sets group context for the session and updates properties on that group record. + explanation: If you chose a person-profile answer, you collapsed company identity into user identity. `group()` sets group context for the session and updates properties on that group record. - id: grpid-p3 type: true_false question: In the JS Web SDK, after calling posthog.group('company', 'acme-inc'), all subsequent events in the session automatically include the company group association. correct: 'true' - explanation: >- - This is true in the JS web SDK because it remembers group context for the current session. If you answered false, you were probably thinking of backend SDKs, which do not keep that - state. + explanation: This is true in the JS web SDK because it remembers group context for the current session. If you answered false, you were probably thinking of backend SDKs, which do not keep that state. - id: grpid-p5 type: scenario - question: >- - A customer calls posthog.group('company', 'acme-inc') on their frontend but never passes any group properties. What will they see in the People/Groups tab for 'acme-inc'? + question: A customer calls posthog.group('company', 'acme-inc') on their frontend but never passes any group properties. What will they see in the People/Groups tab for 'acme-inc'? options: - A fully populated company profile - The group exists in the data model but may appear empty or invisible in the UI without properties - An error because groups require at least one property - Nothing — the group call is ignored without properties correct: 1 - explanation: >- - Events will link to the group, but the group profile in the UI needs at least one property to be visible and useful. The group exists in the data model, but the People/Groups view - may not show it or it appears empty. Always set group properties via the third argument or group_identify. + explanation: Events will link to the group, but the group profile in the UI needs at least one property to be visible and useful. The group exists in the data model, but the People/Groups view may not show it or it appears empty. Always set group properties via the third argument or group_identify. + keyPrerequisite: identify-call - id: backend-group-identify-pattern - instruction: >- - Backend SDKs do not have persistent session context, so the pattern is split in two. First call group_identify to create or update the group profile. Then attach the `groups` object on each - capture call that should link the event to that group. This is also where you decide whether a fact belongs on the company profile or on the individual user profile. - workedExample: >- - A customer wants every API call tied to a company account. Their backend first sets group properties with group_identify for company `acme-inc`, then includes `groups: { company: - 'acme-inc' }` on each API event. The company plan belongs on the group, not duplicated as a separate person property on every user. + instruction: Backend SDKs do not have persistent session context, so the pattern is split in two. First call group_identify to create or update the group profile. Then attach the `groups` object on each capture call that should link the event to that group. This is also where you decide whether a fact belongs on the company profile or on the individual user profile. + workedExample: 'A customer wants every API call tied to a company account. Their backend first sets group properties with group_identify for company `acme-inc`, then includes `groups: { company: ''acme-inc'' }` on each API event. The company plan belongs on the group, not duplicated as a separate person property on every user.' problems: - id: grpid-p2 type: scenario @@ -3653,8 +3038,7 @@ concepts: - Set company name as a person property on each user - Use the HTTP API instead of the Python SDK correct: 1 - explanation: >- - Backend SDKs do not keep persistent session state. You must update the group profile separately and attach the group on each capture call. + explanation: Backend SDKs do not keep persistent session state. You must update the group profile separately and attach the group on each capture call. - id: grpid-p4 type: multiple_choice question: A customer's subscription plan is shared by every user in the same company account. Where is the best place to store that fact? @@ -3664,15 +3048,13 @@ concepts: - As an action - As a session property correct: 0 - explanation: >- - If the fact is shared by the whole company, put it on the group. Storing it separately on every person duplicates account state and creates drift when one copy changes. + explanation: If the fact is shared by the whole company, put it on the group. Storing it separately on every person duplicates account state and creates drift when one copy changes. - id: grpid-p6 type: true_false question: In a backend SDK, calling group_identify once is sufficient to automatically link all future events from that backend to the group. correct: 'false' - explanation: >- - group_identify only creates or updates the group profile. It does not set session context on the backend because backend SDKs have no persistent session. You must still attach the - groups object on every capture() call to link events to the group. + explanation: group_identify only creates or updates the group profile. It does not set session context on the backend because backend SDKs have no persistent session. You must still attach the groups object on every capture() call to link events to the group. + keyPrerequisite: group-identify section: group-analytics - id: linking-events-to-groups name: Linking Events to Groups @@ -3689,9 +3071,7 @@ concepts: weight: 0.55 knowledgePoints: - id: frontend-vs-backend-patterns - instruction: >- - Frontend and backend SDKs link events to groups differently. In the frontend, calling `group()` once sets group context for the session. In the backend, there is no session context, so you - must pass the `groups` object on each capture call. The mental model is simple: frontend can remember state for you; backend cannot. + instruction: 'Frontend and backend SDKs link events to groups differently. In the frontend, calling `group()` once sets group context for the session. In the backend, there is no session context, so you must pass the `groups` object on each capture call. The mental model is simple: frontend can remember state for you; backend cannot.' instructionContent: - type: link url: https://posthog.com/docs/product-analytics/group-analytics @@ -3700,44 +3080,34 @@ concepts: problems: - id: link-grp-p1 type: multiple_choice - question: >- - A customer's backend service sends 1,000 events per hour to PostHog. In their insights, none of these events are associated with any company group, even though they called group_identify() once at startup. What is the most likely cause? + question: A customer's backend service sends 1,000 events per hour to PostHog. In their insights, none of these events are associated with any company group, even though they called group_identify() once at startup. What is the most likely cause? options: - group_identify() needs to be called more frequently to refresh the link - Backend SDKs do not persist group context — the groups object must be passed on every capture() call - The group type 'company' was not registered in PostHog project settings - ClickHouse has not finished processing the group_identify event yet correct: 1 - explanation: >- - Unlike frontend SDKs, backend SDKs are stateless — they do not maintain session context between calls. Calling group_identify() teaches PostHog about the group's properties, but it does not automatically attach future events to that group. Each posthog.capture() call must include a `groups: {'company': 'company_id'}` parameter. The fix is to pass the groups object on every capture call. + explanation: 'Unlike frontend SDKs, backend SDKs are stateless — they do not maintain session context between calls. Calling group_identify() teaches PostHog about the group''s properties, but it does not automatically attach future events to that group. Each posthog.capture() call must include a `groups: {''company'': ''company_id''}` parameter. The fix is to pass the groups object on every capture call.' difficulty: 4 - id: link-grp-p2 type: true_false question: A single PostHog event can be linked to multiple groups of the same type (e.g., two different companies). correct: 'false' - explanation: >- - An event can link to only one group instance per type. You can link to multiple types, but not multiple companies on the same event. + explanation: An event can link to only one group instance per type. You can link to multiple types, but not multiple companies on the same event. - id: link-grp-p5 type: scenario - question: >- - A customer uses the JS web SDK and calls posthog.group('company', 'acme-inc') during session start. Later in the same session, they capture a 'feature_used' event. Is this event linked - to acme-inc? + question: A customer uses the JS web SDK and calls posthog.group('company', 'acme-inc') during session start. Later in the same session, they capture a 'feature_used' event. Is this event linked to acme-inc? options: - No — each event needs an explicit group attachment - Yes — the frontend SDK remembers group context for the session after group() is called - Only if they also call identify() in the same session - Only if the event name starts with '$' correct: 1 - explanation: >- - The JS web SDK persists group context for the session. After calling group(), all subsequent events in that session automatically include the group association. This is the key - difference from backend SDKs, which have no persistent session state. + explanation: The JS web SDK persists group context for the session. After calling group(), all subsequent events in that session automatically include the group association. This is the key difference from backend SDKs, which have no persistent session state. + keyPrerequisite: group-identify - id: group-linking-constraints - instruction: >- - One event can carry multiple group types at once, such as company and project, but only one instance of each type. That limitation matters in consulting or marketplace use cases where a - person may relate to multiple companies. The event still needs one clear company owner unless you redesign the model. - workedExample: >- - A consultant might belong to both `acme` and `globex`, but a single invoice export event still needs one company owner if you want clean company-level reporting. If both companies matter, - the model needs a different event design, not two company IDs on one event. + instruction: One event can carry multiple group types at once, such as company and project, but only one instance of each type. That limitation matters in consulting or marketplace use cases where a person may relate to multiple companies. The event still needs one clear company owner unless you redesign the model. + workedExample: A consultant might belong to both `acme` and `globex`, but a single invoice export event still needs one company owner if you want clean company-level reporting. If both companies matter, the model needs a different event design, not two company IDs on one event. problems: - id: link-grp-p3 type: scenario @@ -3748,8 +3118,7 @@ concepts: - Yes — call posthog.group('company', ...) twice - Yes — use the alias() function to link both companies correct: 1 - explanation: >- - PostHog only supports one group instance per group type per event. The model needs to choose one company or use a different grouping design. + explanation: PostHog only supports one group instance per group type per event. The model needs to choose one company or use a different grouping design. - id: link-grp-p4 type: multiple_choice question: Which combination is allowed on a single PostHog event? @@ -3759,15 +3128,13 @@ concepts: - Two projects and two companies - Unlimited groups of the same type correct: 1 - explanation: >- - A single event can link to multiple group types at once, such as one company and one project, but only one instance of each type. + explanation: A single event can link to multiple group types at once, such as one company and one project, but only one instance of each type. - id: link-grp-p6 type: true_false question: A single PostHog event can be linked to one company group and one project group at the same time. correct: 'true' - explanation: >- - An event can carry multiple group types simultaneously — for example, one company and one project. The constraint is one instance per type, not one group total. This is useful when - events need to be analyzed at both the company and project level. + explanation: An event can carry multiple group types simultaneously — for example, one company and one project. The constraint is one instance per type, not one group total. This is useful when events need to be analyzed at both the company and project level. + keyPrerequisite: linking-events-to-groups section: group-analytics - id: group-gotchas name: Group Analytics Gotchas @@ -3782,22 +3149,17 @@ concepts: encompassing: [] knowledgePoints: - id: important-limitations - instruction: >- - Two group gotchas show up early. First, groups still depend on identified event flow. Anonymous events in `identified_only` mode do not link to groups. Second, a group needs at least one - property to show up in the UI. If you only attach group keys to events but never set properties, the group exists in the data model but stays effectively invisible in the People/Groups view. + instruction: Two group gotchas show up early. First, groups still depend on identified event flow. Anonymous events in `identified_only` mode do not link to groups. Second, a group needs at least one property to show up in the UI. If you only attach group keys to events but never set properties, the group exists in the data model but stays effectively invisible in the People/Groups view. instructionContent: - type: callout title: Data-model vs UI gap - body: >- - A group can participate in event linkage before it feels "real" in the UI. Visibility usually arrives only after you also set group properties. + body: A group can participate in event linkage before it feels "real" in the UI. Visibility usually arrives only after you also set group properties. problems: - id: gotcha-p1 type: true_false question: Anonymous events (in 'identified_only' mode) can still be linked to groups. correct: 'false' - explanation: >- - Anonymous events in `identified_only` mode skip person processing, so group linkage never gets established. If you answered true, the likely miss was assuming groups bypass the normal - identity pipeline. + explanation: Anonymous events in `identified_only` mode skip person processing, so group linkage never gets established. If you answered true, the likely miss was assuming groups bypass the normal identity pipeline. - id: gotcha-p2 type: multiple_choice question: A customer created a group type 'company' and linked events to it, but they cannot see any company groups in the People/Groups tab. What is the most likely cause? @@ -3807,25 +3169,21 @@ concepts: - The People/Groups tab does not support group analytics - They need to wait 24 hours for groups to appear correct: 1 - explanation: >- - A group needs at least one property to appear in the UI. Linking events alone is not enough to make it visible in the People/Groups view. + explanation: A group needs at least one property to appear in the UI. Linking events alone is not enough to make it visible in the People/Groups view. - id: gotcha-p5 type: scenario - question: >- - A customer set up group analytics for their 'workspace' group type. They can see workspace groups listed in People > Groups, and events are linked to workspaces in insights. But when they try to use a workspace-level property in a feature flag targeting rule, it doesn't appear as an option. What should you investigate? + question: A customer set up group analytics for their 'workspace' group type. They can see workspace groups listed in People > Groups, and events are linked to workspaces in insights. But when they try to use a workspace-level property in a feature flag targeting rule, it doesn't appear as an option. What should you investigate? options: - Feature flags do not support group-level property targeting — only person properties work - The workspace properties were set with $set_once and may not have propagated yet - Group properties are only available for feature flags if the group type has been registered in Project Settings and group_identify() has been called with properties - ClickHouse needs time to index the new group properties — wait 24 hours correct: 2 - explanation: >- - Group properties become available for feature flag targeting when: (1) the group type exists in Project Settings, (2) group_identify() has been called with properties for that group. If group_identify() was called without properties, or only posthog.group() was used on the frontend without properties, the group exists but has no properties to target against. Check that group_identify() includes the properties object. + explanation: 'Group properties become available for feature flag targeting when: (1) the group type exists in Project Settings, (2) group_identify() has been called with properties for that group. If group_identify() was called without properties, or only posthog.group() was used on the frontend without properties, the group exists but has no properties to target against. Check that group_identify() includes the properties object.' difficulty: 4 + keyPrerequisite: linking-events-to-groups - id: limits-and-feature-constraints - instruction: >- - The second set of gotchas is product limits. Projects support at most 5 group types, so the customer must model carefully. Some product surfaces also do not support groups directly. That - means a workable group model can still fail if the team assumes every other feature in PostHog understands groups the same way. + instruction: The second set of gotchas is product limits. Projects support at most 5 group types, so the customer must model carefully. Some product surfaces also do not support groups directly. That means a workable group model can still fail if the team assumes every other feature in PostHog understands groups the same way. instructionContent: - type: link url: https://posthog.com/docs/product-analytics/group-analytics @@ -3841,9 +3199,7 @@ concepts: - Each group type requires a separate PostHog project - Group types must be approved by PostHog support correct: 1 - explanation: >- - If you picked unlimited, you were reasoning from the business model instead of the product constraint. PostHog caps projects at 5 group types, so the customer must prioritize the most - valuable rollups. + explanation: If you picked unlimited, you were reasoning from the business model instead of the product constraint. PostHog caps projects at 5 group types, so the customer must prioritize the most valuable rollups. - id: gotcha-p4 type: true_false question: You can target groups directly with PostHog's early access feature management. @@ -3851,17 +3207,15 @@ concepts: explanation: Early access feature management does not support groups directly, so teams need to verify feature support instead of assuming every group-aware surface works the same way. - id: gotcha-p6 type: multiple_choice - question: >- - A customer wants to use groups in PostHog Session Replay to filter recordings by company. Before recommending this, what should you verify first? + question: A customer wants to use groups in PostHog Session Replay to filter recordings by company. Before recommending this, what should you verify first? options: - That the customer has more than 5 group types configured - Whether Session Replay supports group-level filtering, since not all PostHog surfaces support groups equally - That the customer is on the free plan - That the customer has disabled person profiles correct: 1 - explanation: >- - Not every PostHog product surface supports groups the same way. Before recommending group-based filtering in a specific feature, verify that the feature actually supports it. A - workable group model can still fail if the team assumes every surface understands groups identically. + explanation: Not every PostHog product surface supports groups the same way. Before recommending group-based filtering in a specific feature, verify that the feature actually supports it. A workable group model can still fail if the team assumes every surface understands groups identically. + keyPrerequisite: group-gotchas section: group-analytics - id: ph-cdp-overview name: PostHog CDP — Sources, Transformations, Destinations @@ -3881,9 +3235,7 @@ concepts: weight: 0.4 knowledgePoints: - id: three-pieces - instruction: >- - PostHog's CDP breaks into three surfaces. Sources bring external data into PostHog's warehouse. Transformations modify events during ingestion. Destinations send data out of PostHog to - other tools. The important idea is that these surfaces map to different moments in the data flow: import, modify, export. + instruction: 'PostHog''s CDP breaks into three surfaces. Sources bring external data into PostHog''s warehouse. Transformations modify events during ingestion. Destinations send data out of PostHog to other tools. The important idea is that these surfaces map to different moments in the data flow: import, modify, export.' instructionContent: - type: link url: https://posthog.com/docs/cdp @@ -3909,29 +3261,22 @@ concepts: - Batch exports - Cohorts correct: 1 - explanation: >- - Transformations modify events in-flight during ingestion, which is where PII scrubbing belongs. If you chose Source or Destination, you placed the fix on the wrong side of storage. + explanation: Transformations modify events in-flight during ingestion, which is where PII scrubbing belongs. If you chose Source or Destination, you placed the fix on the wrong side of storage. - id: cdp-p5 type: true_false question: PostHog CDP Transformations can modify events after they have already been stored in ClickHouse. correct: 'false' - explanation: >- - Transformations modify events in-flight during ingestion, before they reach storage. Once events are stored in ClickHouse, they are immutable. If you answered true, the likely - confusion is between in-flight transformation and post-storage editing. + explanation: Transformations modify events in-flight during ingestion, before they reach storage. Once events are stored in ClickHouse, they are immutable. If you answered true, the likely confusion is between in-flight transformation and post-storage editing. + keyPrerequisite: ph-ingestion-pipeline - id: choosing-the-cdp-surface - instruction: >- - The practical skill is choosing the right surface for the job. If the customer wants extra data available inside PostHog, think Sources. If they need to change incoming events before - storage, think Transformations. If they need PostHog data to leave for another system, think Destinations. - workedExample: >- - A TAM helps a customer bring Stripe billing data into PostHog, strip email addresses from signup events before storage, and then export cleaned usage data to BigQuery every night. That one - workflow touches all three CDP surfaces in sequence: import, modify, export. + instruction: The practical skill is choosing the right surface for the job. If the customer wants extra data available inside PostHog, think Sources. If they need to change incoming events before storage, think Transformations. If they need PostHog data to leave for another system, think Destinations. + workedExample: 'A TAM helps a customer bring Stripe billing data into PostHog, strip email addresses from signup events before storage, and then export cleaned usage data to BigQuery every night. That one workflow touches all three CDP surfaces in sequence: import, modify, export.' problems: - id: cdp-p3 type: true_false question: PostHog CDP Sources allow you to query external data (like Stripe or Hubspot) alongside PostHog event data. correct: 'true' - explanation: >- - Sources are the import surface. If you answered false, you likely mixed them up with destinations, which move PostHog data out to other tools. + explanation: Sources are the import surface. If you answered false, you likely mixed them up with destinations, which move PostHog data out to other tools. - id: cdp-p4 type: scenario question: A customer wants Stripe subscription data available inside PostHog so they can join it with product usage in SQL. Which CDP surface is the best fit? @@ -3941,23 +3286,18 @@ concepts: - Realtime destination - Cohort correct: 0 - explanation: >- - If the goal is to bring external data into PostHog for analysis, the right surface is a Source. Choosing Transformation or Destination would confuse "bring data in" with "modify data" - or "send data out." + explanation: If the goal is to bring external data into PostHog for analysis, the right surface is a Source. Choosing Transformation or Destination would confuse "bring data in" with "modify data" or "send data out." - id: cdp-p6 type: scenario - question: >- - A customer workflow requires three things: import Stripe billing data into PostHog, strip PII from incoming events before storage, and send cleaned usage data to BigQuery nightly. How - many CDP surfaces does this touch? + question: 'A customer workflow requires three things: import Stripe billing data into PostHog, strip PII from incoming events before storage, and send cleaned usage data to BigQuery nightly. How many CDP surfaces does this touch?' options: - One — Destinations handles all three - Two — Sources and Destinations - Three — Sources (import), Transformations (PII stripping), and Destinations (BigQuery export) - None — this requires custom code outside PostHog correct: 2 - explanation: >- - Each step maps to a different CDP surface. Sources bring Stripe data in. Transformations strip PII during ingestion. Destinations export cleaned data to BigQuery. This is a real-world - example of all three surfaces working together in sequence. + explanation: Each step maps to a different CDP surface. Sources bring Stripe data in. Transformations strip PII during ingestion. Destinations export cleaned data to BigQuery. This is a real-world example of all three surfaces working together in sequence. + keyPrerequisite: ph-cdp-overview section: posthog-cdp - id: ph-destinations-exports name: Destinations & Batch Exports @@ -3974,9 +3314,7 @@ concepts: weight: 0.55 knowledgePoints: - id: realtime-vs-batch - instruction: >- - PostHog destinations come in two broad forms. Realtime destinations push matching events out immediately. Batch exports send data out on a schedule in bulk. Realtime is for triggers and - alerts. Batch is for warehouses, archives, and downstream modeling at scale. + instruction: PostHog destinations come in two broad forms. Realtime destinations push matching events out immediately. Batch exports send data out on a schedule in bulk. Realtime is for triggers and alerts. Batch is for warehouses, archives, and downstream modeling at scale. instructionContent: - type: link url: https://posthog.com/docs/cdp/batch-exports @@ -4007,16 +3345,11 @@ concepts: type: true_false question: Batch exports are the right choice when a customer needs sub-second delivery of every event to an external system. correct: 'false' - explanation: >- - Batch exports run on a schedule (hourly, daily) and send data in bulk. For sub-second delivery, a realtime destination is the right choice. Batch is for warehouses and archives where - freshness of minutes to hours is acceptable. + explanation: Batch exports run on a schedule (hourly, daily) and send data in bulk. For sub-second delivery, a realtime destination is the right choice. Batch is for warehouses and archives where freshness of minutes to hours is acceptable. + keyPrerequisite: ph-cdp-overview - id: operating-exports - instruction: >- - The second decision is operational: filtering, testing, and monitoring. Realtime flows should send only the events that matter. Batch exports should be tested before scheduling and monitored - once live. The wrong export type is usually expensive or noisy, but the unmonitored export is worse because it quietly fails. - workedExample: >- - A customer wants a Slack alert whenever an enterprise account churns and a nightly Snowflake sync of all events for BI reporting. The correct design uses both destination types together: a - realtime destination for the alert and a batch export for the nightly warehouse sync. + instruction: 'The second decision is operational: filtering, testing, and monitoring. Realtime flows should send only the events that matter. Batch exports should be tested before scheduling and monitored once live. The wrong export type is usually expensive or noisy, but the unmonitored export is worse because it quietly fails.' + workedExample: 'A customer wants a Slack alert whenever an enterprise account churns and a nightly Snowflake sync of all events for BI reporting. The correct design uses both destination types together: a realtime destination for the alert and a batch export for the nightly warehouse sync.' problems: - id: dest-p3 type: scenario @@ -4027,8 +3360,7 @@ concepts: - Manually exporting CSV files from the PostHog UI - Using PostHog's HogQL instead of Snowflake correct: 1 - explanation: >- - A batch export to Snowflake is the right fit: scheduled, bulk data transfer to a warehouse. Daily updates match the requirement. + explanation: 'A batch export to Snowflake is the right fit: scheduled, bulk data transfer to a warehouse. Daily updates match the requirement.' - id: dest-p4 type: multiple_choice question: Which extra step most helps prevent a batch export from failing silently after launch? @@ -4038,21 +3370,18 @@ concepts: - Removing all filters from the export - Replacing Snowflake with CSV downloads correct: 1 - explanation: >- - Monitoring is what catches broken credentials, schema drift, and downstream delivery failures before the customer discovers missing data. + explanation: Monitoring is what catches broken credentials, schema drift, and downstream delivery failures before the customer discovers missing data. - id: dest-p6 type: scenario - question: >- - A customer wants both a Slack alert when a VIP customer churns and a nightly sync of all events to Snowflake. How many destination types do they need? + question: A customer wants both a Slack alert when a VIP customer churns and a nightly sync of all events to Snowflake. How many destination types do they need? options: - One — a single batch export can handle both - One — a single realtime destination can handle both - Two — a realtime destination for Slack alerts and a batch export for the Snowflake sync - None — PostHog does not support both at the same time correct: 2 - explanation: >- - These are two different delivery patterns. The Slack alert needs immediate, event-driven delivery (realtime destination). The Snowflake sync needs scheduled bulk transfer (batch - export). The right design uses both destination types together. + explanation: These are two different delivery patterns. The Slack alert needs immediate, event-driven delivery (realtime destination). The Snowflake sync needs scheduled bulk transfer (batch export). The right design uses both destination types together. + keyPrerequisite: ph-destinations-exports section: posthog-cdp - id: cohorts name: Cohorts — Static and Dynamic User Groups @@ -4070,9 +3399,7 @@ concepts: weight: 0.45 knowledgePoints: - id: static-vs-dynamic - instruction: >- - A cohort is a saved group of persons you can reuse in analysis and targeting. Static cohorts are fixed lists. Dynamic cohorts recalculate based on criteria such as person properties, - behavior, or lifecycle state. That makes dynamic cohorts great for living segments and static cohorts great for frozen snapshots. + instruction: A cohort is a saved group of persons you can reuse in analysis and targeting. Static cohorts are fixed lists. Dynamic cohorts recalculate based on criteria such as person properties, behavior, or lifecycle state. That makes dynamic cohorts great for living segments and static cohorts great for frozen snapshots. instructionContent: - type: link url: https://posthog.com/docs/data/cohorts @@ -4088,9 +3415,7 @@ concepts: - Static cohorts support more filter types - Dynamic cohorts are only available on paid plans correct: 1 - explanation: >- - Static cohorts are fixed lists, while dynamic cohorts recalculate membership based on criteria. If you chose another option, the likely mistake was focusing on performance or plan limits - instead of membership behavior. + explanation: Static cohorts are fixed lists, while dynamic cohorts recalculate membership based on criteria. If you chose another option, the likely mistake was focusing on performance or plan limits instead of membership behavior. - id: cohort-p4 type: multiple_choice question: How often do dynamic cohorts in PostHog recalculate their membership? @@ -4100,64 +3425,48 @@ concepts: - Approximately every 24 hours - Only when manually triggered correct: 2 - explanation: >- - Dynamic cohorts update on a schedule, not on every event. If you expected instant membership changes, that is the operational assumption to correct. + explanation: Dynamic cohorts update on a schedule, not on every event. If you expected instant membership changes, that is the operational assumption to correct. - id: cohort-p5 type: scenario - question: >- - A customer wants to freeze the list of users who were active in January for a one-time promotion. They do not want the list to change as new users become active. Which cohort type - should they use? + question: A customer wants to freeze the list of users who were active in January for a one-time promotion. They do not want the list to change as new users become active. Which cohort type should they use? options: - Dynamic cohort — it will automatically keep January users - Static cohort — a fixed list that does not change after creation - A feature flag instead of a cohort - A HogQL query saved as a view correct: 1 - explanation: >- - A static cohort is a frozen snapshot of users. Once created, it does not change. A dynamic cohort would keep recalculating and might include or exclude users as their behavior changes. - For a one-time promotion tied to a specific historical window, static is the right choice. + explanation: A static cohort is a frozen snapshot of users. Once created, it does not change. A dynamic cohort would keep recalculating and might include or exclude users as their behavior changes. For a one-time promotion tied to a specific historical window, static is the right choice. + keyPrerequisite: ph-person-properties - id: cohorts-for-analysis-vs-rollout - instruction: >- - The common trap is assuming every cohort that is valid for analysis is also valid for feature-flag targeting. It is not. Behavioral and lifecycle dynamic cohorts are great for analysis, but - feature flags only support dynamic cohorts based on person properties. If you need a rollout based on recent behavior, create the behavioral cohort for analysis and then snapshot it into a - static cohort for targeting. - workedExample: >- - A product team wants to analyze users who completed onboarding in the last 7 days and also roll out a feature to that same set. The dynamic behavioral cohort works for analysis. The rollout - needs a static snapshot because feature flags cannot target dynamic behavioral cohorts directly. + instruction: The common trap is assuming every cohort that is valid for analysis is also valid for feature-flag targeting. It is not. Behavioral and lifecycle dynamic cohorts are great for analysis, but feature flags only support dynamic cohorts based on person properties. If you need a rollout based on recent behavior, create the behavioral cohort for analysis and then snapshot it into a static cohort for targeting. + workedExample: A product team wants to analyze users who completed onboarding in the last 7 days and also roll out a feature to that same set. The dynamic behavioral cohort works for analysis. The rollout needs a static snapshot because feature flags cannot target dynamic behavioral cohorts directly. problems: - id: cohort-p2 type: true_false question: You can target a feature flag using a dynamic cohort based on behavioral criteria (e.g., 'performed login in last 7 days'). correct: 'false' - explanation: >- - This is the common trap: a dynamic behavioral cohort works for analysis but not for feature-flag rollout. Flag targeting only supports dynamic cohorts based on person properties. + explanation: 'This is the common trap: a dynamic behavioral cohort works for analysis but not for feature-flag rollout. Flag targeting only supports dynamic cohorts based on person properties.' - id: cohort-p3 type: scenario - question: >- - A customer wants to roll out a feature flag to all users who completed onboarding in the last 30 days. They create a dynamic cohort with behavioral criteria 'performed - onboarding_complete in last 30 days.' They try to use it in a feature flag but it does not work. Why? + question: A customer wants to roll out a feature flag to all users who completed onboarding in the last 30 days. They create a dynamic cohort with behavioral criteria 'performed onboarding_complete in last 30 days.' They try to use it in a feature flag but it does not work. Why? options: - The cohort has too many members - Feature flags cannot target dynamic cohorts with behavioral criteria — only person property criteria - The event name 'onboarding_complete' is invalid - Feature flags do not support cohort targeting at all correct: 1 - explanation: >- - Feature flags only support dynamic cohorts based on person properties. The workaround is to snapshot the behavioral cohort into a static cohort for targeting. + explanation: Feature flags only support dynamic cohorts based on person properties. The workaround is to snapshot the behavioral cohort into a static cohort for targeting. - id: cohort-p6 type: multiple_choice - question: >- - A product team creates a dynamic cohort defined as 'users who performed purchase in last 7 days.' They want to use it for both a trends insight and a feature flag rollout. What will - happen? + question: A product team creates a dynamic cohort defined as 'users who performed purchase in last 7 days.' They want to use it for both a trends insight and a feature flag rollout. What will happen? options: - Both uses work perfectly - The trends insight works, but the feature flag will not accept a behavioral dynamic cohort — only person-property-based dynamic cohorts - Neither use works because dynamic cohorts are only for email targeting - The feature flag works but the trends insight does not correct: 1 - explanation: >- - Behavioral dynamic cohorts work in analysis (trends, funnels) but feature flags only support dynamic cohorts based on person properties. The workaround for rollout is to snapshot the - behavioral cohort into a static cohort and target the flag at that. + explanation: Behavioral dynamic cohorts work in analysis (trends, funnels) but feature flags only support dynamic cohorts based on person properties. The workaround for rollout is to snapshot the behavioral cohort into a static cohort and target the flag at that. + keyPrerequisite: cohorts section: querying - id: hogql-basics name: HogQL — SQL in PostHog @@ -4180,9 +3489,7 @@ concepts: weight: 0.3 knowledgePoints: - id: sql-expressions-and-insights - instruction: >- - HogQL shows up in two forms inside PostHog. SQL expressions are short snippets used inside existing UI builders. SQL insights are full queries with SELECT, FROM, WHERE, GROUP BY, ORDER BY, - and JOIN. Both are built on PostHog's SQL layer, but they solve different levels of problem. + instruction: HogQL shows up in two forms inside PostHog. SQL expressions are short snippets used inside existing UI builders. SQL insights are full queries with SELECT, FROM, WHERE, GROUP BY, ORDER BY, and JOIN. Both are built on PostHog's SQL layer, but they solve different levels of problem. instructionContent: - type: link url: https://posthog.com/docs/sql @@ -4203,29 +3510,21 @@ concepts: type: true_false question: HogQL should be the first tool you reach for when creating PostHog insights. correct: 'false' - explanation: >- - If you reached for HogQL first, you skipped the simpler tool. Start with the UI builder and drop to HogQL only when the query shape, joins, or custom logic truly require it. + explanation: If you reached for HogQL first, you skipped the simpler tool. Start with the UI builder and drop to HogQL only when the query shape, joins, or custom logic truly require it. - id: hogql-p5 type: scenario - question: >- - A customer wants to add a custom column to a PostHog Trends breakdown that concatenates browser and OS into a single label (e.g., 'Chrome / Mac OS X'). They do not need a full SQL query. - Which HogQL form should they use? + question: A customer wants to add a custom column to a PostHog Trends breakdown that concatenates browser and OS into a single label (e.g., 'Chrome / Mac OS X'). They do not need a full SQL query. Which HogQL form should they use? options: - A full SQL insight with SELECT, FROM, and GROUP BY - A HogQL expression inside the existing Trends UI builder - An action with a custom event name - A person property combining browser and OS correct: 1 - explanation: >- - For small, targeted customizations within the existing UI, a HogQL expression is the right tool. You can write concat(properties.$browser, ' / ', properties.$os) directly in the - breakdown field. A full SQL insight would be overkill for this use case. + explanation: For small, targeted customizations within the existing UI, a HogQL expression is the right tool. You can write concat(properties.$browser, ' / ', properties.$os) directly in the breakdown field. A full SQL insight would be overkill for this use case. + keyPrerequisite: ph-event-properties - id: when-to-use-hogql - instruction: >- - HogQL earns its complexity when the UI builder runs out of room. If you need custom bucketing logic, joins to persons or warehouse tables, or a query shape the insight builder cannot - express, HogQL becomes the right tool. The best practice is still the same: begin simple, then drop to SQL only when the extra flexibility is justified. - workedExample: >- - A customer wants to group browser values into custom families and join the result to person properties. A standard trend may get part of the way there, but the join and custom bucketing are - the signal that HogQL is now the better fit. + instruction: 'HogQL earns its complexity when the UI builder runs out of room. If you need custom bucketing logic, joins to persons or warehouse tables, or a query shape the insight builder cannot express, HogQL becomes the right tool. The best practice is still the same: begin simple, then drop to SQL only when the extra flexibility is justified.' + workedExample: A customer wants to group browser values into custom families and join the result to person properties. A standard trend may get part of the way there, but the join and custom bucketing are the signal that HogQL is now the better fit. problems: - id: hogql-p3 type: multiple_choice @@ -4236,25 +3535,21 @@ concepts: - sessions - groups correct: 1 - explanation: >- - If you chose `persons` or `sessions`, you mixed up supporting tables with the main event log. `events` is the base table for captured event records. + explanation: If you chose `persons` or `sessions`, you mixed up supporting tables with the main event log. `events` is the base table for captured event records. - id: hogql-p4 type: scenario - question: >- - A customer needs to join product events to person properties and a warehouse table with billing data, and the insight builder cannot express the full logic. What is the best next step? + question: A customer needs to join product events to person properties and a warehouse table with billing data, and the insight builder cannot express the full logic. What is the best next step? options: - Keep forcing the Trends UI to do it - Use HogQL in a SQL insight - Create an action and hope it is enough - Export the data manually as CSV first correct: 1 - explanation: >- - This is the kind of case where HogQL earns its complexity. Once you need joins and custom query structure beyond the UI, a SQL insight is the right tool. + explanation: This is the kind of case where HogQL earns its complexity. Once you need joins and custom query structure beyond the UI, a SQL insight is the right tool. - id: hogql-p6 type: true_false question: HogQL queries in PostHog can join the events table to external data warehouse tables that have been connected via Sources. correct: 'true' - explanation: >- - HogQL supports joins to warehouse tables, which is one of its key advantages over the UI builder. Once external data (like Stripe billing) is connected via Sources, you can join - it to event data in a SQL insight. This is the kind of use case where HogQL earns its complexity. + explanation: HogQL supports joins to warehouse tables, which is one of its key advantages over the UI builder. Once external data (like Stripe billing) is connected via Sources, you can join it to event data in a SQL insight. This is the kind of use case where HogQL earns its complexity. + keyPrerequisite: hogql-basics section: querying diff --git a/content/courses/posthog-use-case-selling.yaml b/content/courses/posthog-use-case-selling.yaml index 6cce62a..8046d0f 100644 --- a/content/courses/posthog-use-case-selling.yaml +++ b/content/courses/posthog-use-case-selling.yaml @@ -1,22 +1,16 @@ course: id: posthog-use-case-selling name: PostHog Use Case Selling - description: >- - How to sell PostHog through use cases, not products — the six use cases, product mappings, buyer personas, discovery - questions, competitive positioning, objection handling, and cross-sell strategy. + description: How to sell PostHog through use cases, not products — the six use cases, product mappings, buyer personas, discovery questions, competitive positioning, objection handling, and cross-sell strategy. estimatedHours: 4 version: '2026.1' sections: - id: foundations name: Use Case Selling Foundations - description: >- - The fundamental mindset shift from product selling to use case selling, and the product-to-use-case mapping that - underpins every conversation. + description: The fundamental mindset shift from product selling to use case selling, and the product-to-use-case mapping that underpins every conversation. - id: product-intelligence name: Product Intelligence - description: >- - Selling the Product Intelligence use case — helping teams understand what users do, why they do it, and what to - build next. + description: Selling the Product Intelligence use case — helping teams understand what users do, why they do it, and what to build next. - id: release-engineering name: Release Engineering description: Selling the Release Engineering use case — helping teams ship faster without breaking things. @@ -25,22 +19,16 @@ sections: description: Selling the Observability use case — helping teams know when things break, understand why, and fix them fast. - id: growth-marketing name: Growth & Marketing - description: >- - Selling the Growth & Marketing use case — helping teams understand what drives acquisition, conversion, and - revenue. + description: Selling the Growth & Marketing use case — helping teams understand what drives acquisition, conversion, and revenue. - id: ai-llm-obs name: AI/LLM Observability - description: >- - Selling the AI/LLM Observability use case — helping teams understand how AI features perform, what they cost, and - how users interact with them. + description: Selling the AI/LLM Observability use case — helping teams understand how AI features perform, what they cost, and how users interact with them. - id: data-infra name: Data Infrastructure description: Selling the Data Infrastructure use case — helping teams unify product data with business data. - id: customer-experience name: Customer Experience - description: >- - Selling the Customer Experience use case — helping teams quickly understand issues, identify problems, and verify - fixes. + description: Selling the Customer Experience use case — helping teams quickly understand issues, identify problems, and verify fixes. - id: cross-sell name: Cross-Sell Strategy description: How to move customers between use cases using adoption signals, natural expansion pathways, and multithreading. @@ -56,53 +44,37 @@ concepts: sourceRef: use-case-selling.md knowledgePoints: - id: use-case-vs-product-kp1 - instruction: >- - PostHog sells products. Customers buy solutions. When you pitch "add Surveys," it sounds like you're trying to - increase their bill. When you pitch "here's how to close the loop on why users drop off," it sounds like - you're solving their problem. Same product. Different framing. Very different conversion rate. - - - A use case is a discrete problem a team is trying to solve, supported by a combination of PostHog products. - Billing, metering, and packaging don't change. What changes is how you talk about it, how you organize around - it, and how you measure adoption. + instruction: |- + PostHog sells products. Customers buy solutions. When you pitch "add Surveys," it sounds like you're trying to increase their bill. When you pitch "here's how to close the loop on why users drop off," it sounds like you're solving their problem. Same product. Different framing. Very different conversion rate. + A use case is a discrete problem a team is trying to solve, supported by a combination of PostHog products. Billing, metering, and packaging don't change. What changes is how you talk about it, how you organize around it, and how you measure adoption. The rule is simple: use cases are how we sell, products are how we bill. instructionContent: - - body: >- - Use cases are how we sell. Products are how we bill. Billing, metering, and packaging don't change. What - changes is how you talk about it, how you organize around it, and how you measure adoption. + - body: Use cases are how we sell. Products are how we bill. Billing, metering, and packaging don't change. What changes is how you talk about it, how you organize around it, and how you measure adoption. type: callout title: The Rule - url: https://posthog.com/handbook/growth/use-case-selling/use-case-selling type: link title: Use Case Selling Handbook description: The foundational playbook for use case selling at PostHog - workedExample: >- + workedExample: |- Bad pitch: "You should add Surveys to your plan — it's only $X/month." - - Good pitch: "You're watching Session Replays of drop-off users. What if you could ask those users directly - what tripped them up, right at the moment of friction? Surveys lets you do that, and the responses tie - straight back to their behavior data." - + Good pitch: "You're watching Session Replays of drop-off users. What if you could ask those users directly what tripped them up, right at the moment of friction? Surveys lets you do that, and the responses tie straight back to their behavior data." Both pitches sell Surveys. The second one solves a problem the customer already told you about. problems: - id: ucvp-kp1-p1 type: multiple_choice - question: >- - A client is using Product Analytics. You want to upsell them on watching what users actually do. Which - framing best follows the use case selling approach? + question: A client is using Product Analytics. You want to upsell them on watching what users actually do. Which framing best follows the use case selling approach? correct: 1 options: - '"Session Replay is a great product — you should add it to your plan."' - '"You see a 40% drop at checkout step 3. Want to watch what users are actually doing at that step?"' - '"Session Replay costs less than Hotjar and has more features."' - '"Adding Session Replay will increase your total platform coverage."' - explanation: >- - Use case selling leads with the problem the customer already has (they see the drop-off but not why) and - positions the product as the solution. Option B connects directly to a known pain point. + explanation: Use case selling leads with the problem the customer already has (they see the drop-off but not why) and positions the product as the solution. Option B connects directly to a known pain point. difficulty: 2 - id: ucvp-kp1-p2 type: multiple_choice @@ -113,9 +85,7 @@ concepts: - We should rename our products to match use case names - The framing and discovery should center on problems, but invoices still show individual products - We should stop mentioning individual product names to customers - explanation: >- - Billing, metering, and packaging don't change — products are still how we bill. What changes is how we - frame conversations: lead with the problem (use case), not the product. + explanation: 'Billing, metering, and packaging don''t change — products are still how we bill. What changes is how we frame conversations: lead with the problem (use case), not the product.' - id: ucvp-kp1-p3 type: multiple_choice question: Why does framing an upsell as "solving a problem" convert better than framing it as "adding a tool"? @@ -125,55 +95,33 @@ concepts: - Because "add a product" sounds like increasing their bill; "solve a problem" sounds like you're helping - Because customers don't understand what our products do - Because use cases always involve more products, leading to higher revenue - explanation: >- - When you pitch "add Surveys" it sounds like increasing the bill. When you pitch "close the loop on why - users drop off," it sounds like solving their problem. Same product, different conversion rate. + explanation: When you pitch "add Surveys" it sounds like increasing the bill. When you pitch "close the loop on why users drop off," it sounds like solving their problem. Same product, different conversion rate. difficulty: 4 - id: use-case-vs-product-kp2 - instruction: >- + instruction: |- PostHog has seven use cases, each representing a distinct job a team is trying to do: - 1. **Product Intelligence**: "Help me understand what users do, why they do it, and what to build next." - 2. **Release Engineering**: "Help me ship faster without breaking things." - 3. **Observability**: "Help me know when things break, understand why, and fix them fast." - 4. **Growth & Marketing**: "Help me understand what drives acquisition, conversion, and revenue." - - 5. **AI/LLM Observability**: "Help me understand how my AI features perform, what they cost, and how users - interact with them." - + 5. **AI/LLM Observability**: "Help me understand how my AI features perform, what they cost, and how users interact with them." 6. **Data Infrastructure**: "Help me unify product data with business data and get it where it needs to go." + 7. **Customer Experience**: "Help me quickly understand what happened, identify the problem, and verify a fix." - 7. **Customer Experience**: "Help me quickly understand what happened, identify the problem, and verify a - fix." - - - Each use case has a different core buyer. Product Intelligence sells to PMs. Release Engineering sells to - engineering managers. Observability sells to SREs. Growth & Marketing sells to growth engineers and marketing - leads. These are separate budgets, separate champions, separate conversations. + Each use case has a different core buyer. Product Intelligence sells to PMs. Release Engineering sells to engineering managers. Observability sells to SREs. Growth & Marketing sells to growth engineers and marketing leads. These are separate budgets, separate champions, separate conversations. instructionContent: - - body: >- - Each use case has a different core buyer. PI sells to PMs. Release Engineering sells to EMs. Observability - sells to SREs. Growth & Marketing sells to growth engineers. These are separate budgets, separate - champions, separate conversations. + - body: Each use case has a different core buyer. PI sells to PMs. Release Engineering sells to EMs. Observability sells to SREs. Growth & Marketing sells to growth engineers. These are separate budgets, separate champions, separate conversations. type: callout title: Seven Use Cases, Seven Buyers - url: https://posthog.com/handbook/growth/use-case-selling/use-case-selling type: link title: Use Case Selling Handbook description: Overview of all seven use cases and their buyer personas - workedExample: >- - A customer's engineering team uses Feature Flags for releases. Their growth team wants to run A/B tests. Their - product team wants to understand retention. + workedExample: |- + A customer's engineering team uses Feature Flags for releases. Their growth team wants to run A/B tests. Their product team wants to understand retention. - - Without use case framing, you'd pitch this as "add Experiments, add Product Analytics." With use case framing, - you'd recognize three distinct conversations: Release Engineering (engineering), Growth & Marketing (growth - team), and Product Intelligence (product team). Each conversation leads with that team's specific job to be - done. + Without use case framing, you'd pitch this as "add Experiments, add Product Analytics." With use case framing, you'd recognize three distinct conversations: Release Engineering (engineering), Growth & Marketing (growth team), and Product Intelligence (product team). Each conversation leads with that team's specific job to be done. problems: - id: ucvp-kp2-p1 type: multiple_choice @@ -184,9 +132,7 @@ concepts: - Observability - Release Engineering - Data Infrastructure - explanation: >- - Release Engineering's job to be done is helping teams ship faster without breaking things — through - feature flags, experiments, and controlled rollouts. + explanation: Release Engineering's job to be done is helping teams ship faster without breaking things — through feature flags, experiments, and controlled rollouts. difficulty: 2 - id: ucvp-kp2-p2 type: multiple_choice @@ -197,9 +143,7 @@ concepts: - Growth & Marketing - Data Infrastructure - Product Intelligence - explanation: >- - Product Intelligence targets PMs and product leaders who want to understand what users do, why, and what - to build next — including proving business impact. + explanation: Product Intelligence targets PMs and product leaders who want to understand what users do, why, and what to build next — including proving business impact. difficulty: 2 - id: ucvp-kp2-p3 type: multiple_choice @@ -210,10 +154,9 @@ concepts: - Because each use case represents a different buyer, budget, and conversation - Because use cases are required for pricing and packaging - Because competitors organize around use cases - explanation: >- - Each use case has a different core buyer with different problems. Product Intelligence sells to PMs, - Release Engineering to EMs, Observability to SREs. These are separate budgets and separate conversations. + explanation: Each use case has a different core buyer with different problems. Product Intelligence sells to PMs, Release Engineering to EMs, Observability to SREs. These are separate budgets and separate conversations. difficulty: 4 + keyPrerequisite: use-case-vs-product - id: product-use-case-mapping name: Product-to-Use-Case Mapping section: foundations @@ -228,14 +171,10 @@ concepts: - use-case-vs-product knowledgePoints: - id: pucm-kp1 - instruction: >- - Every use case has a core product and expansion products. The core product is the entry point — it's what the - team needs first to solve their primary job. Expansion products extend the value once the core is established. - - - The product coverage matrix shows which products are primary for which use case and where they appear as - secondary: + instruction: |- + Every use case has a core product and expansion products. The core product is the entry point — it's what the team needs first to solve their primary job. Expansion products extend the value once the core is established. + The product coverage matrix shows which products are primary for which use case and where they appear as secondary: - Product Analytics is primary for Product Intelligence, secondary for Growth, AI, and Customer Experience. @@ -248,43 +187,28 @@ concepts: regressions introduced by new releases. - Web Analytics is primary for Growth & Marketing. - - LLM Observability is primary for AI/LLM Observability. - - Data Warehouse and Data Pipelines are primary for Data Infrastructure. - - Session Replay appears as secondary in nearly every use case — it's the most cross-cutting product. - Product Analytics and Session Replay together are primary for Customer Experience. - - Key insight: products can be primary for one use case and secondary for several others. Session Replay is a - secondary expansion product in six of seven use cases. This means the same product gets pitched differently - depending on context. + Key insight: products can be primary for one use case and secondary for several others. Session Replay is a secondary expansion product in six of seven use cases. This means the same product gets pitched differently depending on context. instructionContent: - - body: >- - Session Replay appears as secondary in 6 of 7 use cases. The same product gets pitched differently - depending on context. "Watch the drop-off" (PI), "watch the error" (Obs), "watch the bug report" (CX) — - same product, different framing. + - body: Session Replay appears as secondary in 6 of 7 use cases. The same product gets pitched differently depending on context. "Watch the drop-off" (PI), "watch the error" (Obs), "watch the bug report" (CX) — same product, different framing. type: callout title: Session Replay Is Cross-Cutting - url: https://posthog.com/handbook/growth/use-case-selling/use-case-selling type: link title: Use Case Selling Handbook description: Full product-to-use-case coverage matrix - workedExample: >- - Session Replay pitched in Product Intelligence: "You see the 40% drop-off. Want to watch what users are - actually doing?" - + workedExample: |- + Session Replay pitched in Product Intelligence: "You see the 40% drop-off. Want to watch what users are actually doing?" - Session Replay pitched in Observability: "You see the stack trace. Want to watch the user's actual session - when the error fired?" - - - Session Replay pitched in Customer Experience: "Support got a bug report. Want to watch exactly what the - customer experienced?" + Session Replay pitched in Observability: "You see the stack trace. Want to watch the user's actual session when the error fired?" + Session Replay pitched in Customer Experience: "Support got a bug report. Want to watch exactly what the customer experienced?" Same product, three different pitches, each anchored in the use case's job to be done. problems: @@ -297,9 +221,7 @@ concepts: - Product Analytics - Error Tracking - Logging - explanation: >- - Error Tracking is the core product for Observability. Session Replay, Product Analytics, and Logging are - expansion products that extend the value. + explanation: Error Tracking is the core product for Observability. Session Replay, Product Analytics, and Logging are expansion products that extend the value. difficulty: 2 - id: pucm-kp1-p2 type: multiple_choice @@ -310,10 +232,7 @@ concepts: - Three — Product Intelligence, Observability, and Release Engineering - Four — it's common but not everywhere - Six — it's the most cross-cutting product - explanation: >- - Session Replay is secondary in Product Intelligence, Release Engineering, Observability, AI/LLM - Observability, Growth & Marketing, and Customer Experience. It appears in nearly every use case because - "watch what the user actually did" is universally useful. + explanation: Session Replay is secondary in Product Intelligence, Release Engineering, Observability, AI/LLM Observability, Growth & Marketing, and Customer Experience. It appears in nearly every use case because "watch what the user actually did" is universally useful. - id: pucm-kp1-p3 type: multiple_choice question: What are the primary tools for the Data Infrastructure use case? @@ -323,91 +242,64 @@ concepts: - Data Warehouse and Batch Exports / Data Pipelines - Data Warehouse only - HogQL and Data Warehouse - explanation: >- - Data Infrastructure has two core products — Data Warehouse (bring external data IN) and Data Pipelines / - Batch Exports (send PostHog data OUT). Both are primary because the use case is about bidirectional data - flow. + explanation: Data Infrastructure has two core products — Data Warehouse (bring external data IN) and Data Pipelines / Batch Exports (send PostHog data OUT). Both are primary because the use case is about bidirectional data flow. + keyPrerequisite: use-case-vs-product - id: pucm-kp2 - instruction: >- - Every expansion path follows one shape: each step solves a limitation that the previous step exposed. The - pitch always takes the same form — "You can see X, but you can't see Y. This next product gives you Y." - - - You don't need to memorize all seven paths. You need to recognize the pattern so you can run it live in any - conversation. When a customer is active on one product and describes a pain point, your job is to name what - they can see today, what they can't, and which PostHog product closes that gap. + instruction: |- + Every expansion path follows one shape: each step solves a limitation that the previous step exposed. The pitch always takes the same form — "You can see X, but you can't see Y. This next product gives you Y." + You don't need to memorize all seven paths. You need to recognize the pattern so you can run it live in any conversation. When a customer is active on one product and describes a pain point, your job is to name what they can see today, what they can't, and which PostHog product closes that gap. - Each use case has its own path, and you'll learn the specific sequences inside each use-case lesson. This - knowledge point is only about the shape all paths share. + Each use case has its own path, and you'll learn the specific sequences inside each use-case lesson. This knowledge point is only about the shape all paths share. instructionContent: - - body: >- - "You can see X, but you can't see Y. This next product gives you Y." Every expansion pitch is a variation - on this sentence. Learn the shape once; apply it everywhere. + - body: '"You can see X, but you can''t see Y. This next product gives you Y." Every expansion pitch is a variation on this sentence. Learn the shape once; apply it everywhere.' type: callout title: The Expansion Pitch Pattern - url: https://posthog.com/handbook/growth/use-case-selling/use-case-selling type: link title: Use Case Selling Handbook description: Reference for all seven expansion paths - workedExample: >- + workedExample: |- A customer using Product Analytics says "we see a 40% drop at checkout step 3, but we have no idea why." + Run the pattern. What can they see? The drop (the what). What can't they see? Why users are dropping (the why). Which product closes that gap? Session Replay. - Run the pattern. What can they see? The drop (the what). What can't they see? Why users are dropping (the - why). Which product closes that gap? Session Replay. - - - Your pitch: "You see the 40% drop, but you can't see what users are actually doing at that step. Session - Replay lets you watch their real sessions and figure out the why." Same pattern works whether the customer is - on Error Tracking, Feature Flags, or Web Analytics — only the X, Y, and Z change. + Your pitch: "You see the 40% drop, but you can't see what users are actually doing at that step. Session Replay lets you watch their real sessions and figure out the why." Same pattern works whether the customer is on Error Tracking, Feature Flags, or Web Analytics — only the X, Y, and Z change. problems: - id: pucm-kp2-p1 type: multiple_choice - question: >- - What sentence shape does every PostHog expansion pitch follow? + question: What sentence shape does every PostHog expansion pitch follow? correct: 1 options: - '"Product Z is cheaper than your current tool — you should switch."' - '"You can see X, but you can''t see Y. This next product gives you Y."' - '"Here are all the features of Product Z — which ones sound useful?"' - '"Your competitors are using Product Z, so you should too."' - explanation: >- - Every expansion pitch follows the same pattern: name what the customer can already see (X), name the gap - (Y), and offer the product that closes the gap (Z). The specific X, Y, and Z change per use case — the - shape does not. + explanation: 'Every expansion pitch follows the same pattern: name what the customer can already see (X), name the gap (Y), and offer the product that closes the gap (Z). The specific X, Y, and Z change per use case — the shape does not.' difficulty: 2 - id: pucm-kp2-p2 type: multiple_choice - question: >- - A customer on Error Tracking says "we catch the errors fine, but we can't tell what the user was doing - when the error fired." Which step of the expansion pattern is the customer describing? + question: A customer on Error Tracking says "we catch the errors fine, but we can't tell what the user was doing when the error fired." Which step of the expansion pattern is the customer describing? correct: 1 options: - They are describing X (what they can see) and asking for Y (what they can't) - They are describing Y (what they can't see) — there is no X here - They are describing the billing step of the pattern - They are rejecting the expansion pattern - explanation: >- - "We catch the errors fine" is X — what they can see. "Can't tell what the user was doing" is Y — the gap. - Session Replay is Z — the product that closes the gap. When a customer names an X and a Y in the same - breath, they are handing you the pitch. + explanation: '"We catch the errors fine" is X — what they can see. "Can''t tell what the user was doing" is Y — the gap. Session Replay is Z — the product that closes the gap. When a customer names an X and a Y in the same breath, they are handing you the pitch.' difficulty: 3 - id: pucm-kp2-p3 type: multiple_choice - question: >- - Why does the course teach the meta-pattern before teaching each use case's specific expansion path? + question: Why does the course teach the meta-pattern before teaching each use case's specific expansion path? correct: 1 options: - Because memorizing seven paths is faster than learning one pattern - Because the pattern is the transferable skill — you apply it live, per customer, without needing to recall a specific path - Because the specific paths are wrong and the pattern replaces them - Because every use case has the same products, only reordered - explanation: >- - The specific paths are useful as reference material, but in a live conversation you will not retrieve them - from memory fast enough. You will listen for what the customer can and can't see, name the gap, and - suggest the product that closes it. The pattern is the skill; the paths are the reference. + explanation: The specific paths are useful as reference material, but in a live conversation you will not retrieve them from memory fast enough. You will listen for what the customer can and can't see, name the gap, and suggest the product that closes it. The pattern is the skill; the paths are the reference. difficulty: 4 + keyPrerequisite: product-use-case-mapping - id: product-intelligence name: Product Intelligence section: product-intelligence @@ -422,55 +314,33 @@ concepts: - product-use-case-mapping knowledgePoints: - id: pi-kp1 - instruction: >- - Product Intelligence is about helping teams understand what users do, why they do it, and what to build next. - The core product is Product Analytics (funnels, retention, cohorts, lifecycle, trends, paths). - - - The primary buyers are Product Managers, Product Engineers, UX Researchers, Designers, and early-stage - Founders. Each cares about different things: + instruction: |- + Product Intelligence is about helping teams understand what users do, why they do it, and what to build next. The core product is Product Analytics (funnels, retention, cohorts, lifecycle, trends, paths). + The primary buyers are Product Managers, Product Engineers, UX Researchers, Designers, and early-stage Founders. Each cares about different things: - PMs want feature adoption, retention, and proving ROI to leadership. - - Product Engineers want fast instrumentation and reliable data. - - UX Researchers want behavior patterns and session-level detail. - - Designers want before/after impact of design changes. - - Founders want to figure out what to build next. + The expansion path follows a clear logic: Analytics shows the "what" (40% drop at step 3). Replay shows the "why" (qualitative context). Surveys let you ask users directly. Experiments let you test fixes. Revenue Analytics proves business impact. Workflows and Product Tours automate action on insights. - The expansion path follows a clear logic: Analytics shows the "what" (40% drop at step 3). Replay shows the - "why" (qualitative context). Surveys let you ask users directly. Experiments let you test fixes. Revenue - Analytics proves business impact. Workflows and Product Tours automate action on insights. - - - For B2B accounts, Group Analytics is a significant upsell opportunity — it answers "which companies are most - engaged?" not just "which users." + For B2B accounts, Group Analytics is a significant upsell opportunity — it answers "which companies are most engaged?" not just "which users." instructionContent: - - body: >- - Analytics shows the "what" (40% drop at step 3). Replay shows the "why." Surveys let you ask users - directly. Experiments test fixes. Each step builds on the previous insight. For B2B, Group Analytics is a - significant upsell. + - body: Analytics shows the "what" (40% drop at step 3). Replay shows the "why." Surveys let you ask users directly. Experiments test fixes. Each step builds on the previous insight. For B2B, Group Analytics is a significant upsell. type: callout title: Expansion Logic - url: https://posthog.com/handbook/growth/use-case-selling/product-intelligence type: link title: Product Intelligence Playbook description: Buyer personas and expansion path - workedExample: >- - A PM at a SaaS company says: "We can see that 40% of users drop off at the third step of our onboarding flow, - but we have no idea why." - - - Your response: "That's the classic analytics gap — you see the what but not the why. Session Replay would let - you watch exactly what those users are doing at that step. And once you have a hypothesis, you could run a - Survey right at that friction point to ask them directly. Then test a fix with Experiments." + workedExample: |- + A PM at a SaaS company says: "We can see that 40% of users drop off at the third step of our onboarding flow, but we have no idea why." + Your response: "That's the classic analytics gap — you see the what but not the why. Session Replay would let you watch exactly what those users are doing at that step. And once you have a hypothesis, you could run a Survey right at that friction point to ask them directly. Then test a fix with Experiments." - You've just outlined three expansion products (Replay, Surveys, Experiments) without pitching any of them by - name — you pitched solutions to a problem the PM already told you about. + You've just outlined three expansion products (Replay, Surveys, Experiments) without pitching any of them by name — you pitched solutions to a problem the PM already told you about. problems: - id: pi-kp1-p1 type: multiple_choice @@ -481,24 +351,18 @@ concepts: - Feature Flags - Product Analytics - Surveys - explanation: >- - Product Analytics is the core product for Product Intelligence. Everything else (Replay, Surveys, - Experiments) are expansion products. + explanation: Product Analytics is the core product for Product Intelligence. Everything else (Replay, Surveys, Experiments) are expansion products. difficulty: 2 - id: pi-kp1-p2 type: multiple_choice - question: >- - A B2B SaaS company uses Product Analytics but has no Group capability. What use case selling opportunity - does this represent? + question: A B2B SaaS company uses Product Analytics but has no Group capability. What use case selling opportunity does this represent? correct: 1 options: - They should switch to the Release Engineering use case - Group Analytics adds account-level insights like "which companies are most engaged" - Group Analytics is not relevant to Product Intelligence - You should pitch Data Infrastructure instead - explanation: >- - For B2B accounts without Group Analytics, it's a significant upsell. It answers "which companies are most - engaged?" — a question PMs and CS teams care deeply about. + explanation: For B2B accounts without Group Analytics, it's a significant upsell. It answers "which companies are most engaged?" — a question PMs and CS teams care deeply about. - id: pi-kp1-p3 type: multiple_choice question: In the Product Intelligence growth path, why does experimentation come after Surveys, not before? @@ -508,25 +372,19 @@ concepts: - Surveys helps form hypotheses that Experiments then validates - Surveys requires Experiments to work - There is no specific order — either can come first - explanation: >- - The logic is: Replays form hypotheses about friction. Surveys ask users directly to confirm. Then - Experiments tests whether a proposed fix actually works. Each step builds on the previous insight. + explanation: 'The logic is: Replays form hypotheses about friction. Surveys ask users directly to confirm. Then Experiments tests whether a proposed fix actually works. Each step builds on the previous insight.' difficulty: 4 + keyPrerequisite: product-use-case-mapping - id: pi-kp2 - instruction: >- - Competitive positioning for Product Intelligence centers on platform breadth. PostHog is the only tool that - goes from quantitative analytics to qualitative replay to direct feedback to experimentation to action — in - one platform. - + instruction: |- + Competitive positioning for Product Intelligence centers on platform breadth. PostHog is the only tool that goes from quantitative analytics to qualitative replay to direct feedback to experimentation to action — in one platform. Key competitive advantages: - - vs Amplitude: Broader platform (replay, flags, surveys, workflows). Better pricing. Open source. Amplitude has more mature ML (predictions, audiences) and a larger enterprise install base. - vs Mixpanel: Broader platform, no sampling. Mixpanel has strong mobile analytics. - - vs Hotjar: Engineering-grade analytics alongside replay and experiments. Hotjar is simpler for non-technical users. @@ -537,13 +395,9 @@ concepts: Pendo has more mature in-app guides and enterprise PM workflow features. - The sweet spot for Product Intelligence: technical product teams at companies with engineers who value depth, - flexibility, and not paying for 5 tools. Weaker against very large enterprises (Amplitude's ML) and - non-technical teams (Hotjar/Pendo's simpler UX). + The sweet spot for Product Intelligence: technical product teams at companies with engineers who value depth, flexibility, and not paying for 5 tools. Weaker against very large enterprises (Amplitude's ML) and non-technical teams (Hotjar/Pendo's simpler UX). instructionContent: - - body: >- - Technical product teams with engineers who value depth, flexibility, and not paying for 5 tools. Weaker - against very large enterprises (Amplitude's ML) and non-technical teams (Hotjar/Pendo's simpler UX). + - body: Technical product teams with engineers who value depth, flexibility, and not paying for 5 tools. Weaker against very large enterprises (Amplitude's ML) and non-technical teams (Hotjar/Pendo's simpler UX). type: callout title: Sweet Spot - url: https://posthog.com/handbook/growth/use-case-selling/product-intelligence @@ -553,19 +407,14 @@ concepts: problems: - id: pi-kp2-p1 type: multiple_choice - question: >- - A buyer says "We use Amplitude and we're happy with it." What is the top differentiator for Product - Intelligence? + question: A buyer says "We use Amplitude and we're happy with it." What is the top differentiator for Product Intelligence? correct: 1 options: - PostHog has better ML predictions than Amplitude - PostHog combines analytics + replay + surveys + experiments + workflows in one platform - PostHog has a larger enterprise install base - PostHog has better mobile analytics - explanation: >- - PostHog's main advantage over Amplitude is platform breadth — analytics, replay, surveys, flags, - experiments, and workflows all in one tool. Amplitude actually has more mature ML features and a larger - enterprise base. + explanation: PostHog's main advantage over Amplitude is platform breadth — analytics, replay, surveys, flags, experiments, and workflows all in one tool. Amplitude actually has more mature ML features and a larger enterprise base. - id: pi-kp2-p2 type: multiple_choice question: When are we weakest for the Product Intelligence use case? @@ -575,25 +424,20 @@ concepts: - Technical product teams with engineers - Very large enterprises needing mature ML predictions and audiences - Companies that want open-source tools - explanation: >- - PostHog is weakest against very large enterprises where Amplitude's ML features (predictions, audiences) - and enterprise sales motion are more mature. PostHog is strongest with technical product teams. + explanation: PostHog is weakest against very large enterprises where Amplitude's ML features (predictions, audiences) and enterprise sales motion are more mature. PostHog is strongest with technical product teams. difficulty: 4 - id: pi-kp2-p3 type: multiple_choice - question: >- - A lead currently uses Hotjar to watch user behavior and a separate Amplitude instance. What's the best - Product Intelligence argument? + question: A lead currently uses Hotjar to watch user behavior and a separate Amplitude instance. What's the best Product Intelligence argument? correct: 1 options: - PostHog's replay is cheaper than Hotjar - PostHog connects replay to funnels, experiments, and surveys in one platform — no context-switching - Hotjar is going to shut down soon - PostHog has better heatmaps than Hotjar - explanation: >- - The advantage over Hotjar is engineering-grade analytics alongside replay plus experiments and flags. - PostHog actually doesn't have built-in heatmaps — don't claim features that don't exist. + explanation: The advantage over Hotjar is engineering-grade analytics alongside replay plus experiments and flags. PostHog actually doesn't have built-in heatmaps — don't claim features that don't exist. difficulty: 4 + keyPrerequisite: product-intelligence - id: release-engineering name: Release Engineering section: release-engineering @@ -608,13 +452,10 @@ concepts: - product-use-case-mapping knowledgePoints: - id: re-kp1 - instruction: >- - Release Engineering's job is "Help me ship faster without breaking things." The core product is Feature Flags - — controlled rollouts, percentage-based releases, and kill switches. - + instruction: |- + Release Engineering's job is "Help me ship faster without breaking things." The core product is Feature Flags — controlled rollouts, percentage-based releases, and kill switches. Key expansion products: - - Experiments: Billed with Feature Flags (same billing). Measures whether a release actually improved the target metric, not just that it didn't crash. @@ -622,39 +463,25 @@ concepts: replays by flag variant to see why. - The primary buyers are Engineering Managers, Platform Engineers, Individual Developers, and Founding - Engineers. They care about release velocity, incident rate, rollback time, and SDK quality. - + The primary buyers are Engineering Managers, Platform Engineers, Individual Developers, and Founding Engineers. They care about release velocity, incident rate, rollback time, and SDK quality. - Critical business insight: Feature flags in the codebase are extremely sticky — they're infrastructure, not a - dashboard. Once embedded, they're very hard to rip out. This makes Release Engineering one of the - highest-retention use cases. + Critical business insight: Feature flags in the codebase are extremely sticky — they're infrastructure, not a dashboard. Once embedded, they're very hard to rip out. This makes Release Engineering one of the highest-retention use cases. - - The tight flags + experiments integration is genuinely differentiated. No other flag tool lets you create a - flag → run an experiment → measure in analytics → watch sessions by variant, all in one platform. + The tight flags + experiments integration is genuinely differentiated. No other flag tool lets you create a flag → run an experiment → measure in analytics → watch sessions by variant, all in one platform. instructionContent: - - body: >- - Feature flags in the codebase are infrastructure, not a dashboard. Once embedded, they're very hard to rip - out. This makes Release Engineering one of the highest-retention use cases. + - body: Feature flags in the codebase are infrastructure, not a dashboard. Once embedded, they're very hard to rip out. This makes Release Engineering one of the highest-retention use cases. type: callout title: Stickiness Factor - url: https://posthog.com/handbook/growth/use-case-selling/release-engineering type: link title: Release Engineering Playbook description: Buyer personas, expansion path, and competitive positioning - workedExample: >- + workedExample: |- A customer says: "We use LaunchDarkly for feature flags. It's expensive but works." + Your response: "What happens after you ship behind a flag? Do you measure whether the feature actually improved your target metric? With PostHog, experiments are included with flags — same billing. You can go from flag to experiment to watching the losing variant's replays in one workflow. And the pricing is significantly lower because we bundle experiments instead of charging separately." - Your response: "What happens after you ship behind a flag? Do you measure whether the feature actually - improved your target metric? With PostHog, experiments are included with flags — same billing. You can go from - flag to experiment to watching the losing variant's replays in one workflow. And the pricing is significantly - lower because we bundle experiments instead of charging separately." - - - You've hit three points: functionality gap (experiments), integrated workflow (flag → experiment → replay), - and cost (bundled pricing vs separate tools). + You've hit three points: functionality gap (experiments), integrated workflow (flag → experiment → replay), and cost (bundled pricing vs separate tools). problems: - id: re-kp1-p1 type: multiple_choice @@ -665,9 +492,7 @@ concepts: - They are embedded in the codebase as infrastructure, making them very hard to rip out - They are the cheapest product - They require the most training to use - explanation: >- - Feature flags live in the codebase as infrastructure. Unlike a dashboard you can stop visiting, flags are - woven into production code. This makes them extremely sticky. + explanation: Feature flags live in the codebase as infrastructure. Unlike a dashboard you can stop visiting, flags are woven into production code. This makes them extremely sticky. - id: re-kp1-p2 type: multiple_choice question: How are Experiments billed in relation to flag usage? @@ -677,9 +502,7 @@ concepts: - Experiments is included with Feature Flags — same billing - Experiments requires a separate Enterprise license - Experiments is free for all customers - explanation: >- - Experiments are billed with Feature Flags. This is a key selling point — the barrier to experiments - adoption is usage, not cost. + explanation: Experiments are billed with Feature Flags. This is a key selling point — the barrier to experiments adoption is usage, not cost. difficulty: 2 - id: re-kp1-p3 type: multiple_choice @@ -687,27 +510,18 @@ concepts: correct: 1 options: - '"You need Product Analytics to understand deploy impact."' - - >- - "Feature Flags let you ship to 5% first, monitor, then expand — with instant kill switches if something - goes wrong." + - '"Feature Flags let you ship to 5% first, monitor, then expand — with instant kill switches if something goes wrong."' - '"You should slow down your release velocity."' - '"Error Tracking will catch issues after full rollout."' - explanation: >- - The Release Engineering entry point is gradual rollout. Ship to 5%, monitor, expand. Kill switch if - something goes wrong. No more all-or-nothing deploys. + explanation: The Release Engineering entry point is gradual rollout. Ship to 5%, monitor, expand. Kill switch if something goes wrong. No more all-or-nothing deploys. + keyPrerequisite: product-use-case-mapping - id: re-kp2 - instruction: >- - The main competitor for Release Engineering is LaunchDarkly. PostHog's advantages: experiments included with - flags, analytics integration, replay filtered by variant, and significantly better pricing (bundles vs - separate tools). - - - LaunchDarkly's advantages: more mature enterprise flag management, more complex targeting rules, and a larger - enterprise base. + instruction: |- + The main competitor for Release Engineering is LaunchDarkly. PostHog's advantages: experiments included with flags, analytics integration, replay filtered by variant, and significantly better pricing (bundles vs separate tools). + LaunchDarkly's advantages: more mature enterprise flag management, more complex targeting rules, and a larger enterprise base. Other competitors: - - Statsig: Purpose-built for experimentation with a strong warehouse-native story. PostHog is broader (replay, surveys, workflows) and open source. @@ -718,16 +532,11 @@ concepts: and broader platform. - The sweet spot: engineering teams wanting the full loop (flag → measure → debug) who are paying LaunchDarkly - prices for flags alone without experiments. + The sweet spot: engineering teams wanting the full loop (flag → measure → debug) who are paying LaunchDarkly prices for flags alone without experiments. - - Known limitation: PostHog uses Bayesian statistics for experiments. This is faster to reach conclusions and - easier to interpret, but is a real limitation for teams that require frequentist methodology. + Known limitation: PostHog uses Bayesian statistics for experiments. This is faster to reach conclusions and easier to interpret, but is a real limitation for teams that require frequentist methodology. instructionContent: - - body: >- - PostHog uses Bayesian statistics for experiments. Faster conclusions, easier to interpret, but a real - limitation for teams that require frequentist methodology. Be upfront about this — honesty builds trust. + - body: PostHog uses Bayesian statistics for experiments. Faster conclusions, easier to interpret, but a real limitation for teams that require frequentist methodology. Be upfront about this — honesty builds trust. type: callout title: Bayesian Limitation - url: https://posthog.com/handbook/growth/use-case-selling/release-engineering @@ -737,18 +546,14 @@ concepts: problems: - id: re-kp2-p1 type: multiple_choice - question: >- - A lead uses LaunchDarkly for rollouts and a separate tool for Experiments. What's the primary argument for - consolidating onto PostHog? + question: A lead uses LaunchDarkly for rollouts and a separate tool for Experiments. What's the primary argument for consolidating onto PostHog? correct: 1 options: - PostHog has more complex targeting rules than LaunchDarkly - PostHog bundles flags + experiments + analytics + replay in one platform at lower cost - PostHog has a larger enterprise install base - PostHog uses frequentist statistics which are more rigorous - explanation: >- - PostHog's advantage is the bundled platform at lower cost. LaunchDarkly actually has more mature - enterprise flag management. PostHog uses Bayesian (not frequentist) statistics. + explanation: PostHog's advantage is the bundled platform at lower cost. LaunchDarkly actually has more mature enterprise flag management. PostHog uses Bayesian (not frequentist) statistics. - id: re-kp2-p2 type: multiple_choice question: What is a genuine limitation of PostHog's Experiments that you must be upfront about? @@ -758,9 +563,7 @@ concepts: - PostHog uses Bayesian statistics, which is a real limitation for teams requiring frequentist methodology - Experiments don't integrate with Feature Flags - Results take months to generate - explanation: >- - PostHog uses Bayesian statistics — faster conclusions, easier to interpret, but a real limitation for - teams that require frequentist methodology. Being honest about this builds trust. + explanation: PostHog uses Bayesian statistics — faster conclusions, easier to interpret, but a real limitation for teams that require frequentist methodology. Being honest about this builds trust. difficulty: 4 - id: re-kp2-p3 type: multiple_choice @@ -771,10 +574,9 @@ concepts: - When the growth team wants experiments (requiring flags), pulling engineering into the same platform - When you run multiple experiments simultaneously - When flag evaluations exceed the free tier - explanation: >- - Multithreading happens when growth defines a hypothesis and engineering implements the flag. Both teams - are now active in PostHog — growth in the Growth & Marketing use case, engineering in Release Engineering. + explanation: Multithreading happens when growth defines a hypothesis and engineering implements the flag. Both teams are now active in PostHog — growth in the Growth & Marketing use case, engineering in Release Engineering. difficulty: 4 + keyPrerequisite: release-engineering - id: observability-uc name: Observability section: observability @@ -789,50 +591,34 @@ concepts: - product-use-case-mapping knowledgePoints: - id: obs-kp1 - instruction: >- - Observability's job is "Help me know when things break, understand why, and fix them fast." The core product - is Error Tracking. - + instruction: |- + Observability's job is "Help me know when things break, understand why, and fix them fast." The core product is Error Tracking. The expansion path: Error Tracking → Session Replay → Logging → Product Analytics. - - Error Tracking → Replay: See the error and stack trace, but not what the user was doing. Click from an error to the user's actual session. This is the single most differentiated feature vs Sentry. - Replay → Logging (beta): Frontend error context covered; now need backend logs. - - Logging → Product Analytics: Individual debugging done; now measure aggregate impact (how many users affected? Revenue impact?). - The primary buyers are SREs, Backend Engineers, Product Engineers, Engineering Managers, and early-stage - Founders. + The primary buyers are SREs, Backend Engineers, Product Engineers, Engineering Managers, and early-stage Founders. - - Key business insight: observability data connected to product analytics is a moat. Only PostHog can say "this - error affected 500 users, 30 were in checkout, $15k lost revenue this week." Sentry gives you a stack trace. - PostHog gives you business impact. + Key business insight: observability data connected to product analytics is a moat. Only PostHog can say "this error affected 500 users, 30 were in checkout, $15k lost revenue this week." Sentry gives you a stack trace. PostHog gives you business impact. instructionContent: - - body: >- - Observability data connected to product analytics is PostHog's moat. Only PostHog can say "this error - affected 500 users, 30 were in checkout, $15k lost revenue this week." Sentry gives a stack trace. PostHog - gives business impact. + - body: Observability data connected to product analytics is PostHog's moat. Only PostHog can say "this error affected 500 users, 30 were in checkout, $15k lost revenue this week." Sentry gives a stack trace. PostHog gives business impact. type: callout title: The Moat - url: https://posthog.com/handbook/growth/use-case-selling/observability type: link title: Observability Playbook description: Expansion path and buyer personas - workedExample: >- - A customer says: "We use Sentry for error tracking. It catches errors fine but when we get a bug report, it - still takes hours to reproduce." - + workedExample: |- + A customer says: "We use Sentry for error tracking. It catches errors fine but when we get a bug report, it still takes hours to reproduce." - Your response: "That reproduction time is exactly what Session Replay eliminates. In PostHog, you click from - an error directly to the user's session recording. You see exactly what they did, what they saw, and where - things went wrong — no reproduction needed. Sentry gives you the stack trace. PostHog gives you the stack - trace plus the user's actual experience." + Your response: "That reproduction time is exactly what Session Replay eliminates. In PostHog, you click from an error directly to the user's session recording. You see exactly what they did, what they saw, and where things went wrong — no reproduction needed. Sentry gives you the stack trace. PostHog gives you the stack trace plus the user's actual experience." problems: - id: obs-kp1-p1 type: multiple_choice @@ -843,9 +629,7 @@ concepts: - Clicking from an error directly to the user's session recording - Built-in incident management workflows - APM and distributed tracing - explanation: >- - The error-to-replay connection is the killer feature. Sentry gives you a stack trace; PostHog gives you - the stack trace plus the user's actual experience. No other error tracking tool offers this. + explanation: The error-to-replay connection is the killer feature. Sentry gives you a stack trace; PostHog gives you the stack trace plus the user's actual experience. No other error tracking tool offers this. - id: obs-kp1-p2 type: multiple_choice question: What is a known gap in the Observability story that you must be transparent about? @@ -855,10 +639,7 @@ concepts: - PostHog has no APM or distributed tracing yet — it can't fully replace Datadog today - Session Replay doesn't work with Error Tracking - Logging is not on the roadmap - explanation: >- - PostHog has no APM or tracing yet. Be honest: "For error tracking, better than Sentry because of user - context. For full observability, building toward it — in the meantime, product analytics connection gives - you something no other observability tool offers." + explanation: 'PostHog has no APM or tracing yet. Be honest: "For error tracking, better than Sentry because of user context. For full observability, building toward it — in the meantime, product analytics connection gives you something no other observability tool offers."' difficulty: 4 - id: obs-kp1-p3 type: multiple_choice @@ -866,45 +647,28 @@ concepts: correct: 1 options: - Because it makes PostHog's error tracking faster - - >- - Because only PostHog can quantify error impact in business terms — affected users, revenue lost, funnel - impact + - Because only PostHog can quantify error impact in business terms — affected users, revenue lost, funnel impact - Because product analytics data helps fix bugs automatically - Because Datadog doesn't have error tracking - explanation: >- - Only PostHog connects errors to user behavior and business outcomes. "This error affected 500 users, 30 in - checkout, $15k lost revenue" is something no pure observability tool can tell you. + explanation: Only PostHog connects errors to user behavior and business outcomes. "This error affected 500 users, 30 in checkout, $15k lost revenue" is something no pure observability tool can tell you. difficulty: 4 + keyPrerequisite: product-use-case-mapping - id: obs-kp2 - instruction: >- + instruction: |- The three main Observability competitors are Sentry, Datadog, and New Relic. + vs Sentry: PostHog has deeper product analytics and replay context. Sentry has more mature error tracking, broader language support, and a larger install base. Best pitch: "Sentry gives you the stack trace. PostHog gives you the stack trace, the user's session, and the business impact." - vs Sentry: PostHog has deeper product analytics and replay context. Sentry has more mature error tracking, - broader language support, and a larger install base. Best pitch: "Sentry gives you the stack trace. PostHog - gives you the stack trace, the user's session, and the business impact." - - - vs Datadog: PostHog has product analytics integration, replay depth, and is much cheaper. Datadog has the - complete observability stack (APM, traces, metrics) and a massive enterprise ecosystem. Don't try to replace - Datadog entirely. - - - vs New Relic: Similar to Datadog — PostHog adds product analytics and replay, but New Relic has more mature - enterprise features. + vs Datadog: PostHog has product analytics integration, replay depth, and is much cheaper. Datadog has the complete observability stack (APM, traces, metrics) and a massive enterprise ecosystem. Don't try to replace Datadog entirely. + vs New Relic: Similar to Datadog — PostHog adds product analytics and replay, but New Relic has more mature enterprise features. Entry scenarios: - 1. Sentry replacement: Consolidate into PostHog already used for analytics/flags. - 2. First observability tool: Early-stage, 100K exceptions/month free tier. - 3. Session Replay → Error Tracking: Errors surfaced in replays tracked systematically. instructionContent: - - body: >- - "Sentry gives you the stack trace. PostHog gives you the stack trace, the user's session, and the business - impact." Don't try to fully replace Datadog — position as complement for user-facing issues. + - body: '"Sentry gives you the stack trace. PostHog gives you the stack trace, the user''s session, and the business impact." Don''t try to fully replace Datadog — position as complement for user-facing issues.' type: callout title: Sentry Pitch Formula - url: https://posthog.com/handbook/growth/use-case-selling/observability @@ -918,14 +682,10 @@ concepts: correct: 1 options: - '"Yes, PostHog can fully replace Datadog today."' - - >- - "PostHog can replace the error tracking part and add product analytics context, but Datadog is still - needed for APM and tracing." + - '"PostHog can replace the error tracking part and add product analytics context, but Datadog is still needed for APM and tracing."' - '"No, PostHog has no observability features."' - '"You should switch entirely — PostHog is cheaper."' - explanation: >- - Be honest. PostHog can't fully replace Datadog today (no APM/tracing). Position as complement that adds - something Datadog can't: product analytics context and session replay for user-facing issues. + explanation: 'Be honest. PostHog can''t fully replace Datadog today (no APM/tracing). Position as complement that adds something Datadog can''t: product analytics context and session replay for user-facing issues.' - id: obs-kp2-p2 type: multiple_choice question: Which entry scenario is best for getting an existing user into the Observability use case? @@ -935,9 +695,7 @@ concepts: - Sentry replacement — they already use PostHog for analytics/flags and can consolidate - Pitching a full Datadog replacement - Starting with Logging - explanation: >- - Sentry replacement is the strongest entry for existing PostHog customers. They already have the SDK, they - already know the platform — consolidating error tracking into PostHog eliminates a vendor. + explanation: Sentry replacement is the strongest entry for existing PostHog customers. They already have the SDK, they already know the platform — consolidating error tracking into PostHog eliminates a vendor. - id: obs-kp2-p3 type: multiple_choice question: What is the free tier for Error Tracking? @@ -947,10 +705,9 @@ concepts: - 50K exceptions/month - 100K exceptions/month - 1M exceptions/month - explanation: >- - Error Tracking has a generous free tier of 100K exceptions per month. For early-stage companies, this is a - strong entry point — free observability. + explanation: Error Tracking has a generous free tier of 100K exceptions per month. For early-stage companies, this is a strong entry point — free observability. difficulty: 2 + keyPrerequisite: observability-uc - id: growth-marketing name: Growth & Marketing section: growth-marketing @@ -965,50 +722,28 @@ concepts: - product-use-case-mapping knowledgePoints: - id: gm-kp1 - instruction: >- - Growth & Marketing's job is "Help me understand what drives acquisition, conversion, and revenue." The core - product is Web Analytics. - - - This is described internally as "probably the most underserved use case in our current motion." The products - exist but PostHog rarely leads with this story. Marketing teams spending $10k+/month on Segment, Mixpanel, - GA4, CDPs. + instruction: |- + Growth & Marketing's job is "Help me understand what drives acquisition, conversion, and revenue." The core product is Web Analytics. + This is described internally as "probably the most underserved use case in our current motion." The products exist but PostHog rarely leads with this story. Marketing teams spending $10k+/month on Segment, Mixpanel, GA4, CDPs. - The pitch is stack consolidation: replace 3-5 marketing tools with one platform that goes from ad click to - conversion to revenue. + The pitch is stack consolidation: replace 3-5 marketing tools with one platform that goes from ad click to conversion to revenue. + The primary buyers are Growth Engineers, Marketing Leads, CRO/Growth PMs, Founding Growth, and Marketing Analysts. These are separate budgets from engineering — a different buyer than Product Intelligence or Release Engineering. - The primary buyers are Growth Engineers, Marketing Leads, CRO/Growth PMs, Founding Growth, and Marketing - Analysts. These are separate budgets from engineering — a different buyer than Product Intelligence or Release - Engineering. - - - Critical expansion mechanism: Experiments + Feature Flags create a multithreading bridge. The growth team - defines the hypothesis, engineering implements the flag. Both teams are now active in PostHog. This is the - highest-value cross-team play because it creates flags in the codebase (sticky) and pulls in engineering (new - champion). + Critical expansion mechanism: Experiments + Feature Flags create a multithreading bridge. The growth team defines the hypothesis, engineering implements the flag. Both teams are now active in PostHog. This is the highest-value cross-team play because it creates flags in the codebase (sticky) and pulls in engineering (new champion). instructionContent: - - body: >- - Growth & Marketing is "probably the most underserved use case" internally. Marketing teams spending - $10k+/month on Segment, Mixpanel, GA4, CDPs. The pitch is stack consolidation: replace 3-5 tools with one - platform from ad click to revenue. + - body: 'Growth & Marketing is "probably the most underserved use case" internally. Marketing teams spending $10k+/month on Segment, Mixpanel, GA4, CDPs. The pitch is stack consolidation: replace 3-5 tools with one platform from ad click to revenue.' type: callout title: Underserved Opportunity - url: https://posthog.com/handbook/growth/use-case-selling/growth-and-marketing type: link title: Growth & Marketing Playbook description: Expansion path, buyer personas, and competitive positioning - workedExample: >- - A growth lead says: "We use GA4 for web analytics, Segment for data piping, and Amplitude for product - analytics. It costs $12k/month across all three." + workedExample: |- + A growth lead says: "We use GA4 for web analytics, Segment for data piping, and Amplitude for product analytics. It costs $12k/month across all three." - - Your response: "That's a common stack. Here's what PostHog consolidates: Web Analytics replaces GA4 with - first-party data that isn't blocked by ad blockers. Product Analytics gives you the funnel depth Amplitude - has. Data Pipelines replaces the Segment pipe to push conversions back to ad platforms and your CRM. You'd go - from three vendors to one, save most of that $12k, and get things none of those three can do — like - Experiments to A/B test your signup flow measured against actual revenue." + Your response: "That's a common stack. Here's what PostHog consolidates: Web Analytics replaces GA4 with first-party data that isn't blocked by ad blockers. Product Analytics gives you the funnel depth Amplitude has. Data Pipelines replaces the Segment pipe to push conversions back to ad platforms and your CRM. You'd go from three vendors to one, save most of that $12k, and get things none of those three can do — like Experiments to A/B test your signup flow measured against actual revenue." problems: - id: gm-kp1-p1 type: multiple_choice @@ -1019,9 +754,7 @@ concepts: - Marketing Analytics - Web Analytics - Data Pipelines - explanation: >- - Web Analytics is the core product — traffic, referrers, UTM tracking, bounce rates. It's the GA4 - replacement entry point. Marketing Analytics, Product Analytics, and others are expansion products. + explanation: Web Analytics is the core product — traffic, referrers, UTM tracking, bounce rates. It's the GA4 replacement entry point. Marketing Analytics, Product Analytics, and others are expansion products. difficulty: 2 - id: gm-kp1-p2 type: multiple_choice @@ -1029,37 +762,27 @@ concepts: correct: 1 options: - Because PostHog doesn't have any marketing products - - >- - Because the products exist but PostHog rarely leads with this story, despite marketing teams spending - $10k+/month on tools PostHog could replace + - Because the products exist but PostHog rarely leads with this story, despite marketing teams spending $10k+/month on tools PostHog could replace - Because marketing teams don't want analytics - Because Web Analytics is too new to sell - explanation: >- - The products exist and the opportunity is large (marketing teams spending heavily on multiple tools), but - PostHog's current sales motion rarely leads with the Growth & Marketing story. + explanation: The products exist and the opportunity is large (marketing teams spending heavily on multiple tools), but PostHog's current sales motion rarely leads with the Growth & Marketing story. - id: gm-kp1-p3 type: multiple_choice question: What makes the Experiments + Feature Flags growth step in Growth & Marketing so strategically valuable? correct: 1 options: - It's the most expensive product combination - - >- - It creates a multithreading bridge — growth defines hypotheses, engineering implements flags, both teams - are active in PostHog + - It creates a multithreading bridge — growth defines hypotheses, engineering implements flags, both teams are active in PostHog - It's the only way to run A/B tests - It replaces GA4 completely - explanation: >- - The growth-to-engineering bridge is the highest-value cross-team play. Growth gets experiment capability. - Engineering gets flag infrastructure for their own releases. Both teams are now in PostHog with flags - embedded in the codebase. + explanation: The growth-to-engineering bridge is the highest-value cross-team play. Growth gets experiment capability. Engineering gets flag infrastructure for their own releases. Both teams are now in PostHog with flags embedded in the codebase. difficulty: 4 + keyPrerequisite: product-use-case-mapping - id: gm-kp2 - instruction: >- + instruction: |- Competitive positioning for Growth & Marketing centers on full-funnel consolidation and first-party data. - PostHog advantages: - - Full-funnel in one platform: web traffic → attribution → funnels → behavior → revenue → engagement. GA4 stops at the website. Segment stops at the pipe. Amplitude stops at the dashboard. @@ -1068,29 +791,18 @@ concepts: attribution, higher match rates when pushing conversions to ad platforms. - Analytics + automation (Workflows, Product Tours) in the same tool. - - Stack consolidation = real, quantifiable cost savings. - Honest weaknesses: - - Marketing Analytics is beta — set expectations. - - Workflows is less mature than HubSpot/Braze for complex email nurture. - - Product Tours is alpha. - - Pipeline destination coverage is less than Segment. - - Non-technical marketers may find the UI intimidating initially. - - Key objection: "We already use GA4 and it's free." Response: "GA4 shows visits. PostHog shows which channels - drive users who activate and pay. PostHog starts free too, and goes all the way to revenue." + Key objection: "We already use GA4 and it's free." Response: "GA4 shows visits. PostHog shows which channels drive users who activate and pay. PostHog starts free too, and goes all the way to revenue." instructionContent: - - body: >- - "GA4 shows visits. PostHog shows which channels drive users who activate and pay — and starts free too." - Acknowledge GA4's free tier, then reframe on depth: visits vs revenue attribution. + - body: '"GA4 shows visits. PostHog shows which channels drive users who activate and pay — and starts free too." Acknowledge GA4''s free tier, then reframe on depth: visits vs revenue attribution.' type: callout title: GA4 Objection Response - url: https://posthog.com/handbook/growth/use-case-selling/growth-and-marketing @@ -1107,39 +819,29 @@ concepts: - '"GA4 shows visits. PostHog shows which channels drive users who activate and pay — and starts free too."' - '"PostHog is cheaper than GA4."' - '"You should keep GA4 and add PostHog on top."' - explanation: >- - The response acknowledges GA4's free tier while positioning PostHog's depth: it goes beyond visits to - activation, retention, and revenue. PostHog also starts free, so the cost objection is neutralized. + explanation: 'The response acknowledges GA4''s free tier while positioning PostHog''s depth: it goes beyond visits to activation, retention, and revenue. PostHog also starts free, so the cost objection is neutralized.' - id: gm-kp2-p2 type: multiple_choice question: What is the first-party data advantage for marketing teams? correct: 1 options: - PostHog's data is stored on the customer's own servers - - >- - First-party data isn't blocked by ad blockers, giving more accurate attribution and higher match rates - for ad platforms + - First-party data isn't blocked by ad blockers, giving more accurate attribution and higher match rates for ad platforms - First-party data means PostHog collects less data - First-party data is only relevant for GDPR compliance - explanation: >- - First-party data collection means ad blockers don't block PostHog's tracking. This gives more accurate - data, better attribution, and higher match rates when pushing conversions back to ad platforms like Meta - and Google. + explanation: First-party data collection means ad blockers don't block PostHog's tracking. This gives more accurate data, better attribution, and higher match rates when pushing conversions back to ad platforms like Meta and Google. - id: gm-kp2-p3 type: multiple_choice question: A buyer says "We need Segment for our data pipelines." What's the candid response? correct: 1 options: - '"PostHog has more destination integrations than Segment."' - - >- - "Check what destinations you actually need — PostHog has built-in Pipelines, and webhooks bridge gaps. - But verify before promising." + - '"Check what destinations you actually need — PostHog has built-in Pipelines, and webhooks bridge gaps. But verify before promising."' - '"Segment is obsolete."' - '"You should rip out Segment immediately."' - explanation: >- - Be honest. PostHog has fewer destination integrations than Segment. The right response is to check what - the prospect actually needs. PostHog's Pipelines cover many common destinations, and webhooks bridge gaps. + explanation: Be honest. PostHog has fewer destination integrations than Segment. The right response is to check what the prospect actually needs. PostHog's Pipelines cover many common destinations, and webhooks bridge gaps. difficulty: 4 + keyPrerequisite: growth-marketing - id: ai-llm-observability name: AI/LLM Observability section: ai-llm-obs @@ -1154,14 +856,10 @@ concepts: - product-use-case-mapping knowledgePoints: - id: ai-kp1 - instruction: >- - AI/LLM Observability's job is "Help me understand how my AI features perform, what they cost, and how users - interact with them." The core product is LLM Observability (model performance, cost tracking, latency - monitoring, trace individual calls with inputs/outputs/tokens/latency/cost). - + instruction: |- + AI/LLM Observability's job is "Help me understand how my AI features perform, what they cost, and how users interact with them." The core product is LLM Observability (model performance, cost tracking, latency monitoring, trace individual calls with inputs/outputs/tokens/latency/cost). The expansion path: LLM Obs → AI Evals → Product Analytics → Experiments → Error Tracking → Session Replay. - - LLM Obs → AI Evals: See latency and cost, but not whether output quality is good. AI Evals scores quality and detects regressions. @@ -1174,28 +872,19 @@ concepts: The primary buyers are AI Engineers, AI Product Managers, AI Founders, and AI Product Engineers. - - Key differentiation: No one else connects model performance → quality → user behavior → business outcomes in - one platform. Langfuse does tracing. Amplitude does analytics. Sentry does errors. Nobody connects all four. + Key differentiation: No one else connects model performance → quality → user behavior → business outcomes in one platform. Langfuse does tracing. Amplitude does analytics. Sentry does errors. Nobody connects all four. instructionContent: - - body: >- - No one else connects model performance, output quality, user behavior, and business outcomes in one - platform. Langfuse does tracing. Amplitude does analytics. Sentry does errors. Nobody connects all four. + - body: No one else connects model performance, output quality, user behavior, and business outcomes in one platform. Langfuse does tracing. Amplitude does analytics. Sentry does errors. Nobody connects all four. type: callout title: Key Differentiator - url: https://posthog.com/handbook/growth/use-case-selling/ai-llm-observability type: link title: AI/LLM Observability Playbook description: Expansion path and buyer personas - workedExample: >- - An AI startup says: "We use Langfuse for LLM tracing and Amplitude for product analytics. We changed our - prompt last week and users seem less happy but we can't prove it." + workedExample: |- + An AI startup says: "We use Langfuse for LLM tracing and Amplitude for product analytics. We changed our prompt last week and users seem less happy but we can't prove it." - - Your response: "That's exactly the gap between model metrics and user outcomes. PostHog connects both. AI - Evals would have caught the quality regression when you changed the prompt. Product Analytics shows the user - behavior change — acceptance rates, regeneration rates, downstream conversion. And you'd A/B test the next - prompt change with Experiments, measured against user behavior, not benchmarks." + Your response: "That's exactly the gap between model metrics and user outcomes. PostHog connects both. AI Evals would have caught the quality regression when you changed the prompt. Product Analytics shows the user behavior change — acceptance rates, regeneration rates, downstream conversion. And you'd A/B test the next prompt change with Experiments, measured against user behavior, not benchmarks." problems: - id: ai-kp1-p1 type: multiple_choice @@ -1206,9 +895,7 @@ concepts: - Product Analytics - Error Tracking - LLM Observability - explanation: >- - LLM Observability is the core product — tracing individual calls with inputs, outputs, tokens, latency, - and cost. AI Evals and Product Analytics are expansion products. + explanation: LLM Observability is the core product — tracing individual calls with inputs, outputs, tokens, latency, and cost. AI Evals and Product Analytics are expansion products. difficulty: 2 - id: ai-kp1-p2 type: multiple_choice @@ -1219,56 +906,36 @@ concepts: - It scores output quality and detects regressions that latency/cost metrics miss - It replaces the need for Product Analytics - It provides Session Replay of AI interactions - explanation: >- - LLM Obs shows latency, cost, and tokens — but not whether the output is good. AI Evals scores quality and - catches regressions after prompt or model changes. + explanation: LLM Obs shows latency, cost, and tokens — but not whether the output is good. AI Evals scores quality and catches regressions after prompt or model changes. - id: ai-kp1-p3 type: multiple_choice question: Why are AI-native companies said to have "uniquely strong" cross-sell potential? correct: 1 options: - Because they have the largest budgets - - >- - Because AI products sit at the intersection of 4+ use cases — model performance, product analytics, - error tracking, experimentation + - Because AI products sit at the intersection of 4+ use cases — model performance, product analytics, error tracking, experimentation - Because they only need one PostHog product - Because they don't use competitors - explanation: >- - AI products touch model performance (AI/LLM Obs), user behavior (Product Intelligence), errors - (Observability), controlled rollouts (Release Engineering), and more. This makes cross-sell natural across - multiple use cases. + explanation: AI products touch model performance (AI/LLM Obs), user behavior (Product Intelligence), errors (Observability), controlled rollouts (Release Engineering), and more. This makes cross-sell natural across multiple use cases. difficulty: 4 + keyPrerequisite: product-use-case-mapping - id: ai-kp2 - instruction: >- + instruction: |- The main AI/LLM Observability competitors are Langfuse, Helicone, Braintrust, and Datadog LLM Monitoring. + vs Langfuse: PostHog has broader platform and user behavior metrics. Langfuse has more mature LLM-specific features, open-source community, and purpose-built prompt management. - vs Langfuse: PostHog has broader platform and user behavior metrics. Langfuse has more mature LLM-specific - features, open-source community, and purpose-built prompt management. - - - vs Helicone: PostHog has broader platform and experiments. Helicone has simpler LLM logging and built-in - caching/rate limiting. - + vs Helicone: PostHog has broader platform and experiments. Helicone has simpler LLM logging and built-in caching/rate limiting. - vs Braintrust: PostHog has broader platform and production monitoring. Braintrust has a more mature eval - framework and better prompt playground. + vs Braintrust: PostHog has broader platform and production monitoring. Braintrust has a more mature eval framework and better prompt playground. + vs Datadog LLM Monitoring: PostHog has product analytics, user behavior, and is much cheaper for AI startups. Datadog has the full APM stack and enterprise ecosystem. - vs Datadog LLM Monitoring: PostHog has product analytics, user behavior, and is much cheaper for AI startups. - Datadog has the full APM stack and enterprise ecosystem. + Sweet spot: AI-native startups and teams building AI inside existing products who want model performance connected to user outcomes without managing 4 vendors. - - Sweet spot: AI-native startups and teams building AI inside existing products who want model performance - connected to user outcomes without managing 4 vendors. - - - Be honest about maturity: LLM Obs feature set is newer than Langfuse's. Platform breadth is the - differentiator, not depth on LLM-specific tooling. + Be honest about maturity: LLM Obs feature set is newer than Langfuse's. Platform breadth is the differentiator, not depth on LLM-specific tooling. instructionContent: - - body: >- - LLM Obs feature set is newer than Langfuse's. Platform breadth is the differentiator, not depth on - LLM-specific tooling. Lead with the connection to user outcomes, not feature-by-feature comparison. + - body: LLM Obs feature set is newer than Langfuse's. Platform breadth is the differentiator, not depth on LLM-specific tooling. Lead with the connection to user outcomes, not feature-by-feature comparison. type: callout title: Honesty Check - url: https://posthog.com/handbook/growth/use-case-selling/ai-llm-observability @@ -1282,14 +949,10 @@ concepts: correct: 1 options: - PostHog has more mature LLM-specific features than Langfuse - - >- - PostHog's LLM features are newer, but the platform breadth (analytics, experiments, error tracking) is - the differentiator + - PostHog's LLM features are newer, but the platform breadth (analytics, experiments, error tracking) is the differentiator - Langfuse is shutting down - PostHog has better prompt management than Langfuse - explanation: >- - Be honest. Langfuse has more mature LLM-specific tooling. PostHog's advantage is connecting model metrics - to user behavior, experiments, and error tracking in one platform. + explanation: Be honest. Langfuse has more mature LLM-specific tooling. PostHog's advantage is connecting model metrics to user behavior, experiments, and error tracking in one platform. - id: ai-kp2-p2 type: multiple_choice question: Which offering serves as a bridge between AI/LLM Observability and Release workflows? @@ -1299,9 +962,7 @@ concepts: - Session Replay - AI Evals - Data Pipelines - explanation: >- - AI Evals bridges AI/LLM Obs and Release Engineering. It catches quality regressions after prompt or model - changes — the AI equivalent of catching bugs after a deploy. + explanation: AI Evals bridges AI/LLM Obs and Release Engineering. It catches quality regressions after prompt or model changes — the AI equivalent of catching bugs after a deploy. difficulty: 4 - id: ai-kp2-p3 type: multiple_choice @@ -1309,16 +970,12 @@ concepts: correct: 1 options: - Because benchmarks are inaccurate - - >- - Because PostHog measures prompt/model changes against real user behavior (acceptance, conversion), not - synthetic scores + - Because PostHog measures prompt/model changes against real user behavior (acceptance, conversion), not synthetic scores - Because PostHog doesn't support benchmark testing - Because BLEU scores are deprecated - explanation: >- - PostHog's Experiments tests prompt/model changes against real user outcomes (acceptance rates, conversion, - retention) — not synthetic benchmarks. Real user behavior is a more meaningful signal than BLEU or similar - scores. + explanation: PostHog's Experiments tests prompt/model changes against real user outcomes (acceptance rates, conversion, retention) — not synthetic benchmarks. Real user behavior is a more meaningful signal than BLEU or similar scores. difficulty: 4 + keyPrerequisite: ai-llm-observability - id: data-infrastructure name: Data Infrastructure section: data-infra @@ -1333,25 +990,16 @@ concepts: - product-use-case-mapping knowledgePoints: - id: di-kp1 - instruction: >- - Data Infrastructure's job is "Help me unify product data with business data and get it where it needs to go." - The core products are Data Warehouse (bring external data IN — Stripe, HubSpot, Salesforce, databases) and - Data Pipelines / Batch Exports (send PostHog data OUT — S3, Snowflake, BigQuery, ad platforms). - + instruction: |- + Data Infrastructure's job is "Help me unify product data with business data and get it where it needs to go." The core products are Data Warehouse (bring external data IN — Stripe, HubSpot, Salesforce, databases) and Data Pipelines / Batch Exports (send PostHog data OUT — S3, Snowflake, BigQuery, ad platforms). - This is the "stickiness" use case. Once PostHog receives data from Stripe/HubSpot and feeds data out to - warehouses, it's very hard to rip out. Highest retention rates of any use case. - - - But it's also the hardest to sell into. Data teams are skeptical of analytics tools in the data engineering - space. + This is the "stickiness" use case. Once PostHog receives data from Stripe/HubSpot and feeds data out to warehouses, it's very hard to rip out. Highest retention rates of any use case. + But it's also the hardest to sell into. Data teams are skeptical of analytics tools in the data engineering space. The primary buyers are Data Engineers, Data Team Leads, Product Ops / BizOps, and early-stage Founders. - Two entry scenarios: - 1. Data OUT (Batch Exports first): Export PostHog events to existing warehouse. PostHog as data source. @@ -1360,26 +1008,19 @@ concepts: because it keeps teams inside PostHog. - The "lightweight warehouse" pitch works for early-stage companies who don't have Snowflake yet. PostHog gives - them warehouse capabilities without a separate vendor. + The "lightweight warehouse" pitch works for early-stage companies who don't have Snowflake yet. PostHog gives them warehouse capabilities without a separate vendor. instructionContent: - - body: >- - Data Infrastructure is the stickiest use case. Once PostHog receives data from Stripe/HubSpot and feeds - data out to warehouses, ripping it out means rebuilding multiple integrations. Highest retention rates. + - body: Data Infrastructure is the stickiest use case. Once PostHog receives data from Stripe/HubSpot and feeds data out to warehouses, ripping it out means rebuilding multiple integrations. Highest retention rates. type: callout title: Stickiness Insight - url: https://posthog.com/handbook/growth/use-case-selling/data-infrastructure type: link title: Data Infrastructure Playbook description: Entry scenarios and expansion paths - workedExample: >- - A founder says: "We want to see retention broken down by Stripe subscription plan, but our product data is in - PostHog and our billing data is in Stripe." + workedExample: |- + A founder says: "We want to see retention broken down by Stripe subscription plan, but our product data is in PostHog and our billing data is in Stripe." - - Your response: "That's a two-minute setup. Connect your Stripe account in Data Warehouse, and you can write a - HogQL query that joins PostHog events with Stripe subscription data. 'Show me 30-day retention by plan tier' — - no data engineering required, no separate warehouse needed." + Your response: "That's a two-minute setup. Connect your Stripe account in Data Warehouse, and you can write a HogQL query that joins PostHog events with Stripe subscription data. 'Show me 30-day retention by plan tier' — no data engineering required, no separate warehouse needed." problems: - id: di-kp1-p1 type: multiple_choice @@ -1387,14 +1028,10 @@ concepts: correct: 1 options: - Because it has the most features - - >- - Because once PostHog receives and sends data through pipelines, ripping it out means rebuilding multiple - integrations + - Because once PostHog receives and sends data through pipelines, ripping it out means rebuilding multiple integrations - Because Data Warehouse has the highest free tier - Because data teams are the most loyal customers - explanation: >- - Once PostHog is receiving data from Stripe/HubSpot and feeding data out to warehouses/BI tools, removing - it means rebuilding multiple data pipelines. This creates the highest retention of any use case. + explanation: Once PostHog is receiving data from Stripe/HubSpot and feeding data out to warehouses/BI tools, removing it means rebuilding multiple data pipelines. This creates the highest retention of any use case. difficulty: 2 - id: di-kp1-p2 type: multiple_choice @@ -1405,9 +1042,7 @@ concepts: - Data IN (Data Warehouse) because it keeps teams inside PostHog for enriched analytics - Neither is stronger — it depends entirely on the customer - Data IN because it's cheaper - explanation: >- - Data IN is the stronger entry because it keeps teams inside PostHog. "Show me retention by Stripe plan" is - a powerful demo that demonstrates value without requiring the customer to build external pipelines. + explanation: Data IN is the stronger entry because it keeps teams inside PostHog. "Show me retention by Stripe plan" is a powerful demo that demonstrates value without requiring the customer to build external pipelines. - id: di-kp1-p3 type: multiple_choice question: For which type of company does the "lightweight warehouse" story work best? @@ -1417,38 +1052,23 @@ concepts: - Early-stage companies who don't have a separate warehouse yet - Data engineering teams at large companies - Companies already using Fivetran - explanation: >- - The lightweight warehouse pitch resonates with early-stage companies who need to query Stripe alongside - PostHog without setting up Snowflake. For mature data stacks, PostHog is a complement, not a replacement. + explanation: The lightweight warehouse pitch resonates with early-stage companies who need to query Stripe alongside PostHog without setting up Snowflake. For mature data stacks, PostHog is a complement, not a replacement. + keyPrerequisite: product-use-case-mapping - id: di-kp2 - instruction: >- - The main competitors for Data Infrastructure are Snowflake/BigQuery (real warehouses), Fivetran (pipeline - tool), and Census/Hightouch (reverse ETL). - - - vs Snowflake/BigQuery: Don't try to replace them. For mature data stacks, PostHog is a complement — bring key - business data into PostHog for enriched analytics, and export PostHog data to the warehouse. Full replacement - pitch only works for early-stage without a warehouse. + instruction: |- + The main competitors for Data Infrastructure are Snowflake/BigQuery (real warehouses), Fivetran (pipeline tool), and Census/Hightouch (reverse ETL). + vs Snowflake/BigQuery: Don't try to replace them. For mature data stacks, PostHog is a complement — bring key business data into PostHog for enriched analytics, and export PostHog data to the warehouse. Full replacement pitch only works for early-stage without a warehouse. - vs Fivetran: PostHog is analytics platform AND pipe. Simpler for early-stage. Fivetran has far more connectors - and more mature governance. + vs Fivetran: PostHog is analytics platform AND pipe. Simpler for early-stage. Fivetran has far more connectors and more mature governance. + vs Census/Hightouch: PostHog pushes data directly without a warehouse intermediate. Simpler architecture. They have more destination integrations and audience management. - vs Census/Hightouch: PostHog pushes data directly without a warehouse intermediate. Simpler architecture. They - have more destination integrations and audience management. + vs Segment: PostHog is analytics platform AND pipe. No separate CDP needed. Segment has more integrations and a more mature enterprise CDP. - - vs Segment: PostHog is analytics platform AND pipe. No separate CDP needed. Segment has more integrations and - a more mature enterprise CDP. - - - Key honest limitation: data engineering teams may not trust PostHog as a warehouse. Don't oversell. Position - as complement. Demonstrate HogQL with their actual data to build credibility. + Key honest limitation: data engineering teams may not trust PostHog as a warehouse. Don't oversell. Position as complement. Demonstrate HogQL with their actual data to build credibility. instructionContent: - - body: >- - For mature data stacks, PostHog is a complement, not a replacement. Don't try to replace Snowflake. - Demonstrate HogQL with their actual data to build credibility with skeptical data teams. + - body: For mature data stacks, PostHog is a complement, not a replacement. Don't try to replace Snowflake. Demonstrate HogQL with their actual data to build credibility with skeptical data teams. type: callout title: Positioning Rule - url: https://posthog.com/handbook/growth/use-case-selling/data-infrastructure @@ -1462,28 +1082,20 @@ concepts: correct: 1 options: - Yes — PostHog can fully replace Snowflake - - >- - No — position PostHog as a complement that brings key business data into PostHog and exports PostHog - data to Snowflake + - No — position PostHog as a complement that brings key business data into PostHog and exports PostHog data to Snowflake - Yes — PostHog is cheaper than Snowflake - No — Data Infrastructure isn't relevant for Snowflake customers - explanation: >- - For mature data stacks, PostHog is a complement, not a replacement. Bring key business data into PostHog - for enriched analytics. Export PostHog events to Snowflake for the BI team. Don't oversell. + explanation: For mature data stacks, PostHog is a complement, not a replacement. Bring key business data into PostHog for enriched analytics. Export PostHog events to Snowflake for the BI team. Don't oversell. - id: di-kp2-p2 type: multiple_choice question: A lead says "We maintain 6 custom ETL scripts to move data around." Which capabilities address this? correct: 1 options: - Only Product Analytics - - >- - Data Warehouse (bring data IN) and Data Pipelines (send data OUT) — replacing custom scripts with - managed integrations + - Data Warehouse (bring data IN) and Data Pipelines (send data OUT) — replacing custom scripts with managed integrations - Only Batch Exports - Feature Flags and Experiments - explanation: >- - Data Warehouse replaces custom scripts that pull data in (Stripe, CRM, databases). Data Pipelines replaces - custom scripts that push data out (warehouse, ad platforms, CRMs). Both eliminate custom ETL maintenance. + explanation: Data Warehouse replaces custom scripts that pull data in (Stripe, CRM, databases). Data Pipelines replaces custom scripts that push data out (warehouse, ad platforms, CRMs). Both eliminate custom ETL maintenance. - id: di-kp2-p3 type: multiple_choice question: What's the best way to build credibility with a skeptical data team? @@ -1493,10 +1105,9 @@ concepts: - Demonstrate HogQL with their actual data — join their Stripe data with PostHog events in a live query - Tell them PostHog is better than Snowflake - Focus on the free tier pricing - explanation: >- - Data teams are skeptical of analytics tools in the data engineering space. Demonstrating HogQL with their - actual data (not slides or marketing) is the most effective way to build credibility. + explanation: Data teams are skeptical of analytics tools in the data engineering space. Demonstrating HogQL with their actual data (not slides or marketing) is the most effective way to build credibility. difficulty: 4 + keyPrerequisite: data-infrastructure - id: customer-experience-uc name: Customer Experience section: customer-experience @@ -1511,15 +1122,11 @@ concepts: - product-use-case-mapping knowledgePoints: - id: cx-kp1 - instruction: >- - Customer Experience's job is "Help me quickly understand what happened, identify the problem, and verify a - fix." The core products are Product Analytics and Session Replay. - + instruction: |- + Customer Experience's job is "Help me quickly understand what happened, identify the problem, and verify a fix." The core products are Product Analytics and Session Replay. The expansion path: Product Analytics → Session Replay → Error Tracking → Logging/LLM Obs → Surveys. - - Analytics → Replay: Know what happened, need to see why. - - Replay → Error Tracking: Visual context isn't enough; want structured, queryable errors tied to users and releases. @@ -1532,28 +1139,19 @@ concepts: Primary buyers: Support Leaders, Engineering Leads, Product Managers, AI Leads, CS Leaders. - - Key business impact: engineering time savings. Bug reproduction drops from 2 hours to 30-60 minutes. Support - shares one link (replay + errors + logs) and engineering has full context in seconds. Can justify the entire - PostHog contract on debugging time savings alone. + Key business impact: engineering time savings. Bug reproduction drops from 2 hours to 30-60 minutes. Support shares one link (replay + errors + logs) and engineering has full context in seconds. Can justify the entire PostHog contract on debugging time savings alone. instructionContent: - - body: >- - Bug reproduction drops from 2 hours to 30-60 minutes. Support shares one link (replay + errors + logs) and - engineering has full context in seconds. This alone can justify the entire PostHog contract. + - body: Bug reproduction drops from 2 hours to 30-60 minutes. Support shares one link (replay + errors + logs) and engineering has full context in seconds. This alone can justify the entire PostHog contract. type: callout title: ROI Anchor - url: https://posthog.com/handbook/growth/use-case-selling/customer-experience type: link title: Customer Experience Playbook description: Expansion path and buyer personas - workedExample: >- - A support leader says: "When a customer reports a bug, we ask them to describe what happened, then engineering - spends hours trying to reproduce it." - + workedExample: |- + A support leader says: "When a customer reports a bug, we ask them to describe what happened, then engineering spends hours trying to reproduce it." - Your response: "With Session Replay, support searches for the user, watches their session, sees exactly what - happened, and shares a link with engineering. No reproduction needed — engineering sees the replay, the - errors, and the logs all in one view. You go from hours of back-and-forth to a 2-minute handoff." + Your response: "With Session Replay, support searches for the user, watches their session, sees exactly what happened, and shares a link with engineering. No reproduction needed — engineering sees the replay, the errors, and the logs all in one view. You go from hours of back-and-forth to a 2-minute handoff." problems: - id: cx-kp1-p1 type: multiple_choice @@ -1564,9 +1162,7 @@ concepts: - Bug reproduction time dropping from 2 hours to 30-60 minutes — engineering time savings - Higher feature flag evaluation volume - More data warehouse queries - explanation: >- - The engineering time savings alone can justify the PostHog contract. Bug reproduction drops from hours to - minutes. Fewer escalations, fewer context switches, more roadmap velocity. + explanation: The engineering time savings alone can justify the PostHog contract. Bug reproduction drops from hours to minutes. Fewer escalations, fewer context switches, more roadmap velocity. difficulty: 2 - id: cx-kp1-p2 type: multiple_choice @@ -1574,60 +1170,38 @@ concepts: correct: 1 options: - Because Surveys is the most expensive product - - >- - Because you first stabilize debugging (Replay, Errors, Logs), then proactively detect frustration and - close the feedback loop + - Because you first stabilize debugging (Replay, Errors, Logs), then proactively detect frustration and close the feedback loop - Because Surveys don't work with Session Replay - Because customers don't want surveys - explanation: >- - The expansion path builds from reactive debugging (Replay, Error Tracking, Logs) to proactive detection - (Surveys for NPS/CSAT). Surveys closes the loop — detect frustration before it becomes churn. + explanation: The expansion path builds from reactive debugging (Replay, Error Tracking, Logs) to proactive detection (Surveys for NPS/CSAT). Surveys closes the loop — detect frustration before it becomes churn. - id: cx-kp1-p3 type: multiple_choice question: An account currently uses FullStory for Session Replay. What's the best CX argument for consolidating? correct: 1 options: - PostHog replays look nicer than FullStory - - >- - PostHog connects replay to error tracking, logs, analytics, and surveys — one platform instead of replay - plus 3 separate tools + - PostHog connects replay to error tracking, logs, analytics, and surveys — one platform instead of replay plus 3 separate tools - PostHog has more enterprise CX features - FullStory is more expensive in every case - explanation: >- - PostHog's advantage over FullStory/LogRocket is consolidation: replay + errors + logs + analytics + - surveys in one platform. No more switching between 3-4 tabs to debug one issue. + explanation: 'PostHog''s advantage over FullStory/LogRocket is consolidation: replay + errors + logs + analytics + surveys in one platform. No more switching between 3-4 tabs to debug one issue.' + keyPrerequisite: product-use-case-mapping - id: cx-kp2 - instruction: >- + instruction: |- Customer Experience has strong objection-handling patterns: + "We already have Hotjar/FullStory/LogRocket." → PostHog connects replay to errors, logs, analytics, and surveys in one platform. No more 3-4 tab switching. Consolidation saves vendor costs. - "We already have Hotjar/FullStory/LogRocket." → PostHog connects replay to errors, logs, analytics, and - surveys in one platform. No more 3-4 tab switching. Consolidation saves vendor costs. + "Support team isn't technical enough." → The replay viewer is visual and intuitive. Support searches for a user, watches the session, shares a link. Training takes one session. + "We need Zendesk/Intercom integration." → Paste replay links in tickets today. Pipelines push events via webhooks for automated workflows. - "Support team isn't technical enough." → The replay viewer is visual and intuitive. Support searches for a - user, watches the session, shares a link. Training takes one session. + "Session replay has privacy concerns." → Extensive controls: input masking, DOM blocking, network filtering. HIPAA BAA available with Boost package. + "Not sure this justifies another tool." → If already on PostHog, it's not another tool — it's enabling more of the existing platform. If not on PostHog, free tiers let you evaluate without financial risk. - "We need Zendesk/Intercom integration." → Paste replay links in tickets today. Pipelines push events via - webhooks for automated workflows. - - - "Session replay has privacy concerns." → Extensive controls: input masking, DOM blocking, network filtering. - HIPAA BAA available with Boost package. - - - "Not sure this justifies another tool." → If already on PostHog, it's not another tool — it's enabling more of - the existing platform. If not on PostHog, free tiers let you evaluate without financial risk. - - - For healthcare/regulated environments: may need heavy masking or skip replay entirely. Focus on Error Tracking - + Logs + Analytics instead. + For healthcare/regulated environments: may need heavy masking or skip replay entirely. Focus on Error Tracking + Logs + Analytics instead. instructionContent: - - body: >- - Session Replay has extensive controls — input masking, DOM blocking, network filtering. HIPAA BAA - available with Boost package. If replay is still too sensitive, pivot to Error Tracking + Logs + - Analytics. + - body: Session Replay has extensive controls — input masking, DOM blocking, network filtering. HIPAA BAA available with Boost package. If replay is still too sensitive, pivot to Error Tracking + Logs + Analytics. type: callout title: Privacy Objection Response - url: https://posthog.com/handbook/growth/use-case-selling/customer-experience @@ -1641,31 +1215,20 @@ concepts: correct: 1 options: - '"They need engineering training first."' - - >- - "The replay viewer is visual and intuitive — support searches for a user, watches the session, and - shares a link. One training session." + - '"The replay viewer is visual and intuitive — support searches for a user, watches the session, and shares a link. One training session."' - '"Support should not use PostHog — it is for engineers only."' - '"We can build a simpler interface for them."' - explanation: >- - Session Replay is the most accessible PostHog feature for non-technical users. Search for a user, watch - what happened, share a link. It's visual, not analytical. + explanation: Session Replay is the most accessible PostHog feature for non-technical users. Search for a user, watch what happened, share a link. It's visual, not analytical. - id: cx-kp2-p2 type: multiple_choice - question: >- - A healthcare company is interested in Session Replay but has strict PHI requirements. What do you - recommend? + question: A healthcare company is interested in Session Replay but has strict PHI requirements. What do you recommend? correct: 1 options: - '"Session Replay doesn''t work in healthcare."' - - >- - "Configure extensive masking and blocking. HIPAA BAA available with Boost package. If replay is too - sensitive, focus on Error Tracking + Logs + Analytics." + - '"Configure extensive masking and blocking. HIPAA BAA available with Boost package. If replay is too sensitive, focus on Error Tracking + Logs + Analytics."' - '"Skip PostHog entirely."' - '"Disable all data collection."' - explanation: >- - PostHog has extensive privacy controls (masking, blocking, network filtering) and offers HIPAA BAA with - the Boost package. If replay is still too sensitive, Error Tracking + Logs + Analytics provide value - without recording sessions. + explanation: PostHog has extensive privacy controls (masking, blocking, network filtering) and offers HIPAA BAA with the Boost package. If replay is still too sensitive, Error Tracking + Logs + Analytics provide value without recording sessions. difficulty: 4 - id: cx-kp2-p3 type: multiple_choice @@ -1676,10 +1239,9 @@ concepts: - PostHog has no native ticketing integration — it complements rather than replaces ITSM workflows - PostHog is too expensive for enterprise - PostHog doesn't support session replay at scale - explanation: >- - PostHog doesn't have native ticketing/ITSM integration. For enterprises deep in ServiceNow or Jira Service - Management, PostHog is a debugging context complement, not an ITSM replacement. + explanation: PostHog doesn't have native ticketing/ITSM integration. For enterprises deep in ServiceNow or Jira Service Management, PostHog is a debugging context complement, not an ITSM replacement. difficulty: 4 + keyPrerequisite: customer-experience-uc - id: cross-sell-strategy name: Cross-Sell Strategy section: cross-sell @@ -1700,91 +1262,57 @@ concepts: - customer-experience-uc knowledgePoints: - id: cs-kp1 - instruction: >- - Cross-selling between use cases follows natural bridges. The most important bridges create "multithreading" — - getting multiple teams in a customer organization active in PostHog. - + instruction: |- + Cross-selling between use cases follows natural bridges. The most important bridges create "multithreading" — getting multiple teams in a customer organization active in PostHog. The highest-value cross-sell bridges: + 1. Release Engineering → Product Intelligence: "Engineers use PostHog for releases. Has the product team seen the analytics?" Engineering champion introduces product team. - 1. Release Engineering → Product Intelligence: "Engineers use PostHog for releases. Has the product team seen - the analytics?" Engineering champion introduces product team. - + 2. Growth & Marketing → Release Engineering: "Growth team started experiments. Engineering already implementing flags — have they considered using flags for all releases?" Growth champions engineering adoption. - 2. Growth & Marketing → Release Engineering: "Growth team started experiments. Engineering already - implementing flags — have they considered using flags for all releases?" Growth champions engineering - adoption. + 3. Product Intelligence → Growth & Marketing: "Product team uses PostHog. Has the growth team seen Web Analytics and attribution?" + 4. Any use case → Data Infrastructure: "You're measuring conversion. Are you sending those conversions back to Meta and Google for optimization?" Data flow creates stickiness. - 3. Product Intelligence → Growth & Marketing: "Product team uses PostHog. Has the growth team seen Web - Analytics and attribution?" + 5. AI/LLM Obs → Multiple: AI products sit at the intersection of 4+ use cases, making AI companies the strongest cross-sell targets. - - 4. Any use case → Data Infrastructure: "You're measuring conversion. Are you sending those conversions back to - Meta and Google for optimization?" Data flow creates stickiness. - - - 5. AI/LLM Obs → Multiple: AI products sit at the intersection of 4+ use cases, making AI companies the - strongest cross-sell targets. - - - The pattern: each use case creates champions in one team. Cross-selling means leveraging that champion to - introduce PostHog to an adjacent team with an adjacent problem. + The pattern: each use case creates champions in one team. Cross-selling means leveraging that champion to introduce PostHog to an adjacent team with an adjacent problem. instructionContent: - - body: >- - Each use case creates a champion in one team. Cross-selling means leveraging that champion to introduce - PostHog to an adjacent team with an adjacent problem. Multiple teams = multiple budgets = defensible - account. + - body: Each use case creates a champion in one team. Cross-selling means leveraging that champion to introduce PostHog to an adjacent team with an adjacent problem. Multiple teams = multiple budgets = defensible account. type: callout title: Multithreading Rule - url: https://posthog.com/handbook/growth/use-case-selling/use-case-selling type: link title: Use Case Selling Handbook description: Full cross-sell playbook and bridge patterns - workedExample: >- - Account situation: Engineering team uses Feature Flags heavily (Release Engineering). Growth team is asking - about A/B testing. - + workedExample: |- + Account situation: Engineering team uses Feature Flags heavily (Release Engineering). Growth team is asking about A/B testing. - Cross-sell play: Experiments are included with Feature Flags. The growth team defines the hypothesis. - Engineering implements the flag (they already know how). Now both teams are active in PostHog. + Cross-sell play: Experiments are included with Feature Flags. The growth team defines the hypothesis. Engineering implements the flag (they already know how). Now both teams are active in PostHog. - - Next move: Growth team sees value in Web Analytics and attribution. Product team hears about experiments and - wants retention analysis. Three teams in PostHog, three use cases, one platform. + Next move: Growth team sees value in Web Analytics and attribution. Product team hears about experiments and wants retention analysis. Three teams in PostHog, three use cases, one platform. problems: - id: cs-kp1-p1 type: multiple_choice - question: >- - An account's dev team uses Feature Flags. The growth team wants to measure impact with controlled tests. - What's the cross-sell play? + question: An account's dev team uses Feature Flags. The growth team wants to measure impact with controlled tests. What's the cross-sell play? correct: 1 options: - Sell them a separate Experiments tool - - >- - "Experiments are included with Feature Flags. Growth defines hypotheses, engineering implements flags. - Both teams in PostHog." + - '"Experiments are included with Feature Flags. Growth defines hypotheses, engineering implements flags. Both teams in PostHog."' - Tell them to use a dedicated experimentation platform - Suggest they switch from Release Engineering to Growth & Marketing - explanation: >- - Experiments are billed with Feature Flags. This is the perfect multithreading moment — growth gets - experiment capability, engineering uses existing flag infrastructure. Both teams are now active. + explanation: Experiments are billed with Feature Flags. This is the perfect multithreading moment — growth gets experiment capability, engineering uses existing flag infrastructure. Both teams are now active. - id: cs-kp1-p2 type: multiple_choice question: Why are AI-native companies the best cross-sell targets? correct: 1 options: - Because they have the largest budgets - - >- - Because AI products sit at the intersection of 4+ use cases — model performance, user behavior, errors, - releases, and experimentation + - Because AI products sit at the intersection of 4+ use cases — model performance, user behavior, errors, releases, and experimentation - Because they only use one product - Because they are less price-sensitive - explanation: >- - AI products naturally touch AI/LLM Obs (model metrics), Product Intelligence (user behavior), - Observability (errors), Release Engineering (controlled rollouts), and more. Cross-sell is natural, not - forced. + explanation: AI products naturally touch AI/LLM Obs (model metrics), Product Intelligence (user behavior), Observability (errors), Release Engineering (controlled rollouts), and more. Cross-sell is natural, not forced. difficulty: 4 - id: cs-kp1-p3 type: multiple_choice @@ -1795,45 +1323,28 @@ concepts: - Getting multiple teams (engineering, growth, product) active in PostHog as separate champions - Using PostHog's multi-threading API - Having multiple projects in one PostHog organization - explanation: >- - Multithreading means multiple teams with separate budgets and champions using PostHog. Each team anchored - in a different use case. This makes the account more defensible and creates multiple expansion paths. + explanation: Multithreading means multiple teams with separate budgets and champions using PostHog. Each team anchored in a different use case. This makes the account more defensible and creates multiple expansion paths. difficulty: 2 + keyPrerequisite: product-use-case-mapping - id: cs-kp2 - instruction: >- - Adoption signals tell you when a customer is ready for expansion. These come from Vitally traits and PostHog - usage data. - + instruction: |- + Adoption signals tell you when a customer is ready for expansion. These come from Vitally traits and PostHog usage data. Key signals by use case: + Product Intelligence: Single-product account (analytics only), high insight creation, Session Replay not used yet, B2B without Group Analytics, multiple PM/design roles in user list. - Product Intelligence: Single-product account (analytics only), high insight creation, Session Replay not used - yet, B2B without Group Analytics, multiple PM/design roles in user list. + Release Engineering: Feature Flags is primary/only paid product, high flag evaluations but low experiment count, customer mentions LaunchDarkly, engineering-only users. + Observability: Error Tracking active but low product count, customer mentions Sentry/Datadog, high Replay usage with error filtering, engineering-heavy users. - Release Engineering: Feature Flags is primary/only paid product, high flag evaluations but low experiment - count, customer mentions LaunchDarkly, engineering-only users. + Growth & Marketing: Web Analytics active but no other products, mentions GA4/Segment/CDP, multiple marketing/growth members invited, low Pipelines despite high analytics. + Data Infrastructure: Active batch exports, active external data schemas, high rows synced, mentions Fivetran/Snowflake, high HogQL usage. - Observability: Error Tracking active but low product count, customer mentions Sentry/Datadog, high Replay - usage with error filtering, engineering-heavy users. - - - Growth & Marketing: Web Analytics active but no other products, mentions GA4/Segment/CDP, multiple - marketing/growth members invited, low Pipelines despite high analytics. - - - Data Infrastructure: Active batch exports, active external data schemas, high rows synced, mentions - Fivetran/Snowflake, high HogQL usage. - - - The general pattern: look for single-product accounts, mentions of competitor tools, team composition (which - roles are active), and usage gaps (high activity on one product, zero on the logical next step). + The general pattern: look for single-product accounts, mentions of competitor tools, team composition (which roles are active), and usage gaps (high activity on one product, zero on the logical next step). instructionContent: - - body: >- - Look for three things: single-product accounts, mentions of competitor tools in notes, and usage gaps - (high activity on one product, zero on the logical next step). These signal expansion readiness. + - body: 'Look for three things: single-product accounts, mentions of competitor tools in notes, and usage gaps (high activity on one product, zero on the logical next step). These signal expansion readiness.' type: callout title: Adoption Signal Pattern problems: @@ -1846,26 +1357,17 @@ concepts: - They're using flags for rollouts but not measuring impact — Experiments is the natural next step - They don't need Experiments - They should reduce their flag usage - explanation: >- - High flag volume + zero experiments means they're doing controlled rollouts without measuring impact. - Experiments (included with flags) is the obvious next step: "Do you know if these features are actually - working?" + explanation: 'High flag volume + zero experiments means they''re doing controlled rollouts without measuring impact. Experiments (included with flags) is the obvious next step: "Do you know if these features are actually working?"' - id: cs-kp2-p2 type: multiple_choice - question: >- - In Vitally, you see an account with Web traffic tracking active, mentions GA4 in notes, and multiple - marketing team members invited. Which use case upsell should you pursue? + question: In Vitally, you see an account with Web traffic tracking active, mentions GA4 in notes, and multiple marketing team members invited. Which use case upsell should you pursue? correct: 2 options: - Release Engineering - Data Infrastructure - - >- - Growth & Marketing — full expansion from Web Analytics into Marketing Analytics, Product Analytics, - Experiments, and Pipelines + - Growth & Marketing — full expansion from Web Analytics into Marketing Analytics, Product Analytics, Experiments, and Pipelines - Observability - explanation: >- - Web Analytics active + GA4 mentions + marketing team members = Growth & Marketing use case is live. The - expansion path is Web Analytics → Marketing Analytics → Product Analytics → Experiments → Pipelines. + explanation: Web Analytics active + GA4 mentions + marketing team members = Growth & Marketing use case is live. The expansion path is Web Analytics → Marketing Analytics → Product Analytics → Experiments → Pipelines. difficulty: 4 - id: cs-kp2-p3 type: multiple_choice @@ -1876,8 +1378,6 @@ concepts: - A significant Product Intelligence upsell — Group Analytics answers "which companies are most engaged" - A Release Engineering opportunity - An Observability opportunity - explanation: >- - B2B company without Group Analytics is a significant Product Intelligence upsell. It answers "which - companies are most engaged?" — critical for B2B account-level insights. + explanation: B2B company without Group Analytics is a significant Product Intelligence upsell. It answers "which companies are most engaged?" — critical for B2B account-level insights. difficulty: 4 - + keyPrerequisite: cross-sell-strategy diff --git a/content/electrical-nec/course.yaml b/content/electrical-nec/course.yaml index 6585a0a..cec28e4 100644 --- a/content/electrical-nec/course.yaml +++ b/content/electrical-nec/course.yaml @@ -1,2526 +1,2620 @@ course: id: electrical-nec-2023 - name: "NEC 2023 Electrical Exam Prep" - description: "Complete coverage of the National Electrical Code (NFPA 70) 2023 edition for Journeyman and Master Electrician exams." + name: NEC 2023 Electrical Exam Prep + description: Complete coverage of the National Electrical Code (NFPA 70) 2023 edition for Journeyman and Master Electrician exams. estimatedHours: 80 - version: "2024.1" - sourceDocument: "NFPA 70: National Electrical Code, 2023 Edition" - + version: '2024.1' + sourceDocument: 'NFPA 70: National Electrical Code, 2023 Edition' concepts: - - # ============================================================ - # FOUNDATIONAL — NEC Structure & Definitions - # ============================================================ - - id: nec-overview - name: "NEC Purpose, Scope, and Article Structure" + name: NEC Purpose, Scope, and Article Structure difficulty: 2 estimatedMinutes: 20 - tags: [foundational, nec-structure] - sourceRef: "NEC 2023 Article 90" + tags: + - foundational + - nec-structure + sourceRef: NEC 2023 Article 90 knowledgePoints: - id: nec-purpose - instruction: "The National Electrical Code (NEC), also known as NFPA 70, provides the practical safeguarding of persons and property from hazards arising from the use of electricity. Per Article 90.1, the NEC is not a design manual or instruction guide -- it establishes minimum safety requirements. The NEC is organized into an Introduction (Article 90) and nine Chapters. Chapters 1-4 apply generally. Chapters 5-7 supplement or modify Chapters 1-4 for special occupancies, equipment, and conditions. Chapter 8 covers communications systems and is independent of Chapters 1-7 except where specifically referenced. Chapter 9 contains tables." - workedExample: "Example: A question asks whether NEC Chapter 5 rules override Chapter 2 rules. The answer is yes -- per 90.3, Chapters 5-7 can supplement OR modify Chapters 1-4. So if Article 501 (Hazardous Locations) has a stricter wiring method requirement than Article 300, Article 501 controls." + instruction: The National Electrical Code (NEC), also known as NFPA 70, provides the practical safeguarding of persons and property from hazards arising from the use of electricity. Per Article 90.1, the NEC is not a design manual or instruction guide -- it establishes minimum safety requirements. The NEC is organized into an Introduction (Article 90) and nine Chapters. Chapters 1-4 apply generally. Chapters 5-7 supplement or modify Chapters 1-4 for special occupancies, equipment, and conditions. Chapter 8 covers communications systems and is independent of Chapters 1-7 except where specifically referenced. Chapter 9 contains tables. + workedExample: 'Example: A question asks whether NEC Chapter 5 rules override Chapter 2 rules. The answer is yes -- per 90.3, Chapters 5-7 can supplement OR modify Chapters 1-4. So if Article 501 (Hazardous Locations) has a stricter wiring method requirement than Article 300, Article 501 controls.' problems: - id: nec-overview-p1 type: multiple_choice - question: "What is the primary purpose of the NEC as stated in Article 90.1?" + question: What is the primary purpose of the NEC as stated in Article 90.1? options: - - "To serve as a design manual for electrical installations" - - "The practical safeguarding of persons and property from hazards arising from the use of electricity" - - "To establish maximum performance standards for electrical equipment" - - "To provide instructions for untrained persons" + - To serve as a design manual for electrical installations + - The practical safeguarding of persons and property from hazards arising from the use of electricity + - To establish maximum performance standards for electrical equipment + - To provide instructions for untrained persons correct: 1 - explanation: "Per NEC 90.1(A), the purpose of the NEC is the practical safeguarding of persons and property from hazards arising from the use of electricity. It is not a design manual (90.1(A) Note)." + explanation: Per NEC 90.1(A), the purpose of the NEC is the practical safeguarding of persons and property from hazards arising from the use of electricity. It is not a design manual (90.1(A) Note). - id: nec-overview-p2 type: multiple_choice - question: "According to NEC 90.3, how do Chapters 5, 6, and 7 relate to Chapters 1 through 4?" + question: According to NEC 90.3, how do Chapters 5, 6, and 7 relate to Chapters 1 through 4? options: - - "They are completely independent of Chapters 1-4" - - "They can supplement or modify the rules in Chapters 1-4" - - "They only apply to residential installations" - - "They replace Chapters 1-4 entirely" + - They are completely independent of Chapters 1-4 + - They can supplement or modify the rules in Chapters 1-4 + - They only apply to residential installations + - They replace Chapters 1-4 entirely correct: 1 - explanation: "Per NEC 90.3, Chapters 5, 6, and 7 supplement or modify Chapters 1-4. Chapter 8 is independent except where specifically referenced." + explanation: Per NEC 90.3, Chapters 5, 6, and 7 supplement or modify Chapters 1-4. Chapter 8 is independent except where specifically referenced. - id: nec-overview-p3 type: true_false - question: "Chapter 8 of the NEC (Communications Systems) is independent of Chapters 1-7 unless specifically referenced." - correct: "true" - explanation: "Per NEC 90.3, Chapter 8 covers communications systems and is not subject to the requirements of Chapters 1-7 except where the requirements are specifically referenced in Chapter 8." + question: Chapter 8 of the NEC (Communications Systems) is independent of Chapters 1-7 unless specifically referenced. + correct: 'true' + explanation: Per NEC 90.3, Chapter 8 covers communications systems and is not subject to the requirements of Chapters 1-7 except where the requirements are specifically referenced in Chapter 8. - id: nec-overview-p4 type: fill_blank - question: "The NEC is organized into an Introduction (Article 90) and ___ chapters." - correct: "nine" - explanation: "The NEC contains nine chapters. Chapters 1-4 apply generally, Chapters 5-7 supplement or modify Chapters 1-4, Chapter 8 covers communications, and Chapter 9 contains tables." + question: The NEC is organized into an Introduction (Article 90) and ___ chapters. + correct: nine + explanation: The NEC contains nine chapters. Chapters 1-4 apply generally, Chapters 5-7 supplement or modify Chapters 1-4, Chapter 8 covers communications, and Chapter 9 contains tables. - id: nec-overview-p5 type: ordering - question: "Place these NEC chapter topics in order from Chapter 1 to Chapter 4." - options: - - "Wiring Methods and Materials" - - "Wiring and Protection" - - "General" - - "Equipment for General Use" - correct: "2,1,0,3" - explanation: "NEC chapters in order: Chapter 1 - General, Chapter 2 - Wiring and Protection, Chapter 3 - Wiring Methods and Materials, Chapter 4 - Equipment for General Use." + question: Place these NEC chapter topics in order from Chapter 1 to Chapter 4. + options: + - Wiring Methods and Materials + - Wiring and Protection + - General + - Equipment for General Use + correct: 2,1,0,3 + explanation: 'NEC chapters in order: Chapter 1 - General, Chapter 2 - Wiring and Protection, Chapter 3 - Wiring Methods and Materials, Chapter 4 - Equipment for General Use.' - id: nec-article-structure - instruction: "The NEC is organized into Articles, each covering a specific topic. Articles are divided into Parts (Roman numerals), then Sections (e.g., 210.8), then subsections. Key foundational articles include: Article 90 (Introduction), Article 100 (Definitions), Article 110 (Requirements for Electrical Installations), Article 200 (Use and Identification of Grounded Conductors), Article 210 (Branch Circuits), Article 215 (Feeders), Article 220 (Branch-Circuit, Feeder, and Service Load Calculations), Article 225 (Outside Branch Circuits and Feeders), Article 230 (Services), Article 240 (Overcurrent Protection), Article 250 (Grounding and Bonding)." + instruction: 'The NEC is organized into Articles, each covering a specific topic. Articles are divided into Parts (Roman numerals), then Sections (e.g., 210.8), then subsections. Key foundational articles include: Article 90 (Introduction), Article 100 (Definitions), Article 110 (Requirements for Electrical Installations), Article 200 (Use and Identification of Grounded Conductors), Article 210 (Branch Circuits), Article 215 (Feeders), Article 220 (Branch-Circuit, Feeder, and Service Load Calculations), Article 225 (Outside Branch Circuits and Feeders), Article 230 (Services), Article 240 (Overcurrent Protection), Article 250 (Grounding and Bonding).' problems: - id: nec-structure-p1 type: multiple_choice - question: "Which NEC article covers the definitions of terms used throughout the Code?" + question: Which NEC article covers the definitions of terms used throughout the Code? options: - - "Article 90" - - "Article 100" - - "Article 110" - - "Article 200" + - Article 90 + - Article 100 + - Article 110 + - Article 200 correct: 1 - explanation: "Article 100 contains definitions essential to proper application of the NEC. Only definitions of terms used in two or more articles are included in Article 100." + explanation: Article 100 contains definitions essential to proper application of the NEC. Only definitions of terms used in two or more articles are included in Article 100. - id: nec-structure-p2 type: multiple_choice - question: "Which NEC article covers overcurrent protection?" + question: Which NEC article covers overcurrent protection? options: - - "Article 210" - - "Article 230" - - "Article 240" - - "Article 250" + - Article 210 + - Article 230 + - Article 240 + - Article 250 correct: 2 - explanation: "Article 240 covers overcurrent protection including fuses, circuit breakers, and their ratings and applications." - + explanation: Article 240 covers overcurrent protection including fuses, circuit breakers, and their ratings and applications. + keyPrerequisite: nec-overview - id: article-100-definitions - name: "Article 100 — Key NEC Definitions" + name: Article 100 — Key NEC Definitions difficulty: 3 estimatedMinutes: 25 - tags: [foundational, definitions] - sourceRef: "NEC 2023 Article 100" + tags: + - foundational + - definitions + sourceRef: NEC 2023 Article 100 prerequisites: - nec-overview knowledgePoints: - id: definitions-current - instruction: "Article 100 defines terms critical to exam success. Ampacity is the maximum current a conductor can carry continuously under conditions of use without exceeding its temperature rating. A Branch Circuit is the circuit conductors between the final overcurrent device and the outlet(s). A Feeder is all circuit conductors between the service equipment (or source of a separately derived system) and the final branch-circuit overcurrent device. Service refers to the conductors and equipment for delivering electric energy from the serving utility to the wiring system of the premises served." - workedExample: "Example: A question asks what separates a feeder from a branch circuit. The key distinction is the final overcurrent device. Everything from the service panel to the last breaker protecting a circuit is a feeder. Everything downstream of that breaker to the outlets is a branch circuit." + instruction: Article 100 defines terms critical to exam success. Ampacity is the maximum current a conductor can carry continuously under conditions of use without exceeding its temperature rating. A Branch Circuit is the circuit conductors between the final overcurrent device and the outlet(s). A Feeder is all circuit conductors between the service equipment (or source of a separately derived system) and the final branch-circuit overcurrent device. Service refers to the conductors and equipment for delivering electric energy from the serving utility to the wiring system of the premises served. + workedExample: 'Example: A question asks what separates a feeder from a branch circuit. The key distinction is the final overcurrent device. Everything from the service panel to the last breaker protecting a circuit is a feeder. Everything downstream of that breaker to the outlets is a branch circuit.' problems: - id: def-p1 type: multiple_choice - question: "Per NEC Article 100, what is the definition of 'ampacity'?" + question: Per NEC Article 100, what is the definition of 'ampacity'? options: - - "The total power consumed by a circuit" - - "The maximum current a conductor can carry continuously under conditions of use without exceeding its temperature rating" - - "The voltage drop across a conductor" - - "The resistance of a conductor per foot" + - The total power consumed by a circuit + - The maximum current a conductor can carry continuously under conditions of use without exceeding its temperature rating + - The voltage drop across a conductor + - The resistance of a conductor per foot correct: 1 - explanation: "Ampacity is defined in Article 100 as the maximum current, in amperes, that a conductor can carry continuously under the conditions of use without exceeding its temperature rating." + explanation: Ampacity is defined in Article 100 as the maximum current, in amperes, that a conductor can carry continuously under the conditions of use without exceeding its temperature rating. - id: def-p2 type: multiple_choice - question: "According to Article 100, a 'feeder' is defined as:" + question: 'According to Article 100, a ''feeder'' is defined as:' options: - - "The conductors between the utility transformer and the service point" - - "All circuit conductors between the service equipment and the final branch-circuit overcurrent device" - - "The conductors between the meter base and the main panel" - - "Any conductor rated over 100 amperes" + - The conductors between the utility transformer and the service point + - All circuit conductors between the service equipment and the final branch-circuit overcurrent device + - The conductors between the meter base and the main panel + - Any conductor rated over 100 amperes correct: 1 - explanation: "Per Article 100, a feeder is all circuit conductors between the service equipment, the source of a separately derived system, or other power supply source, and the final branch-circuit overcurrent device." + explanation: Per Article 100, a feeder is all circuit conductors between the service equipment, the source of a separately derived system, or other power supply source, and the final branch-circuit overcurrent device. + keyPrerequisite: nec-overview - id: definitions-grounding - instruction: "Grounding-related definitions are frequently tested. Grounded means connected to ground or to a conductive body that extends the ground connection. Grounded Conductor is a system or circuit conductor that is intentionally grounded (typically the neutral). Grounding Conductor, Equipment (EGC) is the conductive path that provides a ground-fault current path and connects normally non-current-carrying metal parts of equipment together and to the system grounded conductor, the grounding electrode conductor, or both. Ground-Fault Current Path is an electrically conductive path from the point of a ground fault on a wiring system through normally non-current-carrying conductors to the electrical supply source." + instruction: Grounding-related definitions are frequently tested. Grounded means connected to ground or to a conductive body that extends the ground connection. Grounded Conductor is a system or circuit conductor that is intentionally grounded (typically the neutral). Grounding Conductor, Equipment (EGC) is the conductive path that provides a ground-fault current path and connects normally non-current-carrying metal parts of equipment together and to the system grounded conductor, the grounding electrode conductor, or both. Ground-Fault Current Path is an electrically conductive path from the point of a ground fault on a wiring system through normally non-current-carrying conductors to the electrical supply source. problems: - id: def-ground-p1 type: multiple_choice - question: "What is the 'grounded conductor' in a typical residential electrical system?" + question: What is the 'grounded conductor' in a typical residential electrical system? options: - - "The bare copper wire in the panel" - - "The neutral conductor (white or gray)" - - "The hot conductor (black)" - - "The grounding electrode conductor" + - The bare copper wire in the panel + - The neutral conductor (white or gray) + - The hot conductor (black) + - The grounding electrode conductor correct: 1 - explanation: "The grounded conductor is the system conductor that is intentionally grounded. In a standard 120/240V residential system, this is the neutral conductor, identified by white or gray insulation per Article 200.6." + explanation: The grounded conductor is the system conductor that is intentionally grounded. In a standard 120/240V residential system, this is the neutral conductor, identified by white or gray insulation per Article 200.6. - id: def-ground-p2 type: true_false - question: "The equipment grounding conductor (EGC) normally carries current during regular operation." - correct: "false" - explanation: "The EGC connects normally non-current-carrying metal parts of equipment. It only carries current during a ground fault condition to facilitate overcurrent device operation." + question: The equipment grounding conductor (EGC) normally carries current during regular operation. + correct: 'false' + explanation: The EGC connects normally non-current-carrying metal parts of equipment. It only carries current during a ground fault condition to facilitate overcurrent device operation. - id: def-p3 type: fill_blank - question: "Per Article 100, ___ is defined as the maximum current a conductor can carry continuously under conditions of use without exceeding its temperature rating." - correct: "ampacity" - explanation: "Ampacity is one of the most important definitions in Article 100. It determines how much current a conductor can safely carry on a continuous basis." + question: Per Article 100, ___ is defined as the maximum current a conductor can carry continuously under conditions of use without exceeding its temperature rating. + correct: ampacity + explanation: Ampacity is one of the most important definitions in Article 100. It determines how much current a conductor can safely carry on a continuous basis. - id: def-p4 type: matching - question: "Match each NEC term with its definition." - options: - - "Ampacity|Maximum continuous current without exceeding temperature rating" - - "Branch Circuit|Conductors between final overcurrent device and outlets" - - "Feeder|Conductors between service equipment and final branch-circuit overcurrent device" - - "Service|Conductors and equipment delivering energy from the utility" - correct: "0,1,2,3" - explanation: "These are foundational Article 100 definitions. Each describes a specific portion of the electrical distribution system from utility to outlet." - + question: Match each NEC term with its definition. + options: + - Ampacity|Maximum continuous current without exceeding temperature rating + - Branch Circuit|Conductors between final overcurrent device and outlets + - Feeder|Conductors between service equipment and final branch-circuit overcurrent device + - Service|Conductors and equipment delivering energy from the utility + correct: 0,1,2,3 + explanation: These are foundational Article 100 definitions. Each describes a specific portion of the electrical distribution system from utility to outlet. + keyPrerequisite: article-100-definitions - id: article-110-requirements - name: "Article 110 — General Requirements for Electrical Installations" + name: Article 110 — General Requirements for Electrical Installations difficulty: 3 estimatedMinutes: 20 - tags: [foundational, installation-requirements] - sourceRef: "NEC 2023 Article 110" + tags: + - foundational + - installation-requirements + sourceRef: NEC 2023 Article 110 prerequisites: - nec-overview knowledgePoints: - id: working-space - instruction: "Section 110.26 requires adequate working space around electrical equipment. For 0-150V to ground, the minimum clear working space depth is 3 feet (914 mm). For 151-600V, it is 3 feet (Condition 1), 3.5 feet (Condition 2), or 4 feet (Condition 3). The width of working space must be 30 inches (762 mm) minimum or the width of the equipment, whichever is greater. The workspace must have adequate illumination (110.26(D)) and a dedicated equipment space (110.26(E)). For equipment rated 1200A or more and over 6 feet wide, there must be one entrance/egress at each end of the working space (110.26(C)(2))." - workedExample: "Example: A 480V panelboard is installed against a concrete wall (grounded surface) with exposed live parts on the front. An electrician asks the minimum working space. This is Condition 2 (exposed live parts on one side and grounded parts on the other). Per Table 110.26(A)(1), 151-600V Condition 2 requires 3.5 feet (1.07m) minimum depth." + instruction: Section 110.26 requires adequate working space around electrical equipment. For 0-150V to ground, the minimum clear working space depth is 3 feet (914 mm). For 151-600V, it is 3 feet (Condition 1), 3.5 feet (Condition 2), or 4 feet (Condition 3). The width of working space must be 30 inches (762 mm) minimum or the width of the equipment, whichever is greater. The workspace must have adequate illumination (110.26(D)) and a dedicated equipment space (110.26(E)). For equipment rated 1200A or more and over 6 feet wide, there must be one entrance/egress at each end of the working space (110.26(C)(2)). + workedExample: 'Example: A 480V panelboard is installed against a concrete wall (grounded surface) with exposed live parts on the front. An electrician asks the minimum working space. This is Condition 2 (exposed live parts on one side and grounded parts on the other). Per Table 110.26(A)(1), 151-600V Condition 2 requires 3.5 feet (1.07m) minimum depth.' problems: - id: art110-p1 type: multiple_choice - question: "What is the minimum working space depth in front of a 120/240V residential panel (Condition 1)?" + question: What is the minimum working space depth in front of a 120/240V residential panel (Condition 1)? options: - - "2 feet" - - "2.5 feet" - - "3 feet" - - "4 feet" + - 2 feet + - 2.5 feet + - 3 feet + - 4 feet correct: 2 - explanation: "Per Table 110.26(A)(1), for 0-150V nominal to ground, Condition 1 requires a minimum of 3 feet (914 mm) clear working space depth." + explanation: Per Table 110.26(A)(1), for 0-150V nominal to ground, Condition 1 requires a minimum of 3 feet (914 mm) clear working space depth. - id: art110-p2 type: multiple_choice - question: "What is the minimum width of the working space in front of electrical equipment?" + question: What is the minimum width of the working space in front of electrical equipment? options: - - "24 inches" - - "30 inches or the width of the equipment, whichever is greater" - - "36 inches" - - "42 inches" + - 24 inches + - 30 inches or the width of the equipment, whichever is greater + - 36 inches + - 42 inches correct: 1 - explanation: "Per 110.26(A)(2), the width of the working space must be not less than 30 inches (762 mm) or the width of the equipment, whichever is greater." + explanation: Per 110.26(A)(2), the width of the working space must be not less than 30 inches (762 mm) or the width of the equipment, whichever is greater. + keyPrerequisite: nec-overview - id: conductor-terminations - instruction: "Section 110.14 covers electrical connections. Conductors must be terminated using devices identified for the conductor material (110.14(A)). Temperature ratings of terminations are critical: unless the equipment is listed and marked otherwise, conductors must be selected based on the lowest temperature rating of any connected termination, conductor, or device. Most equipment terminations are rated for 75 degrees C. This means even if you use 90 degree C rated THHN wire, you must use the 75 degree C ampacity column from Table 310.16 for sizing -- unless the equipment is specifically listed for 90 degrees C terminations." + instruction: 'Section 110.14 covers electrical connections. Conductors must be terminated using devices identified for the conductor material (110.14(A)). Temperature ratings of terminations are critical: unless the equipment is listed and marked otherwise, conductors must be selected based on the lowest temperature rating of any connected termination, conductor, or device. Most equipment terminations are rated for 75 degrees C. This means even if you use 90 degree C rated THHN wire, you must use the 75 degree C ampacity column from Table 310.16 for sizing -- unless the equipment is specifically listed for 90 degrees C terminations.' problems: - id: art110-term-p1 type: multiple_choice - question: "When terminating THHN (90 degrees C rated) conductors on equipment with 75 degrees C rated terminals, which ampacity column from Table 310.16 must be used?" + question: When terminating THHN (90 degrees C rated) conductors on equipment with 75 degrees C rated terminals, which ampacity column from Table 310.16 must be used? options: - - "60 degrees C column" - - "75 degrees C column" - - "90 degrees C column" - - "Any column -- the conductor rating determines ampacity" + - 60 degrees C column + - 75 degrees C column + - 90 degrees C column + - Any column -- the conductor rating determines ampacity correct: 1 - explanation: "Per 110.14(C), conductors must be selected based on the lowest temperature rating of any connected termination. Since the equipment terminals are rated 75 degrees C, the 75 degrees C ampacity column must be used." + explanation: Per 110.14(C), conductors must be selected based on the lowest temperature rating of any connected termination. Since the equipment terminals are rated 75 degrees C, the 75 degrees C ampacity column must be used. - id: art110-term-p2 type: multiple_choice - question: "For equipment with 1200A rating and over 6 feet wide, how many entrances are required to the working space?" + question: For equipment with 1200A rating and over 6 feet wide, how many entrances are required to the working space? options: - - "One" - - "Two (one at each end)" - - "Three" - - "One per 10 feet of equipment width" + - One + - Two (one at each end) + - Three + - One per 10 feet of equipment width correct: 1 - explanation: "Per 110.26(C)(2), for equipment rated 1200 amperes or more and over 6 feet (1.8 m) wide, there must be one entrance to and egress from the required working space at each end of the equipment." + explanation: Per 110.26(C)(2), for equipment rated 1200 amperes or more and over 6 feet (1.8 m) wide, there must be one entrance to and egress from the required working space at each end of the equipment. - id: art110-p3 type: fill_blank - question: "Per 110.26(A)(2), the minimum width of working space in front of electrical equipment is ___ inches or the width of the equipment, whichever is greater." - correct: "30" - explanation: "Per 110.26(A)(2), the width must be not less than 30 inches (762 mm) or the width of the equipment, whichever is greater." + question: Per 110.26(A)(2), the minimum width of working space in front of electrical equipment is ___ inches or the width of the equipment, whichever is greater. + correct: '30' + explanation: Per 110.26(A)(2), the width must be not less than 30 inches (762 mm) or the width of the equipment, whichever is greater. - id: art110-p4 type: ordering - question: "Place these working space depth conditions in order from least to most depth required (151-600V)." - options: - - "Condition 2 — exposed live parts one side, grounded parts other" - - "Condition 3 — exposed live parts on both sides" - - "Condition 1 — exposed live parts on one side, no live or grounded on other" - correct: "2,0,1" - explanation: "Per Table 110.26(A)(1) at 151-600V: Condition 1 = 3 feet, Condition 2 = 3.5 feet, Condition 3 = 4 feet." - - # ============================================================ - # CONDUCTORS — Sizing, Types, Ampacity - # ============================================================ - + question: Place these working space depth conditions in order from least to most depth required (151-600V). + options: + - Condition 2 — exposed live parts one side, grounded parts other + - Condition 3 — exposed live parts on both sides + - Condition 1 — exposed live parts on one side, no live or grounded on other + correct: 2,0,1 + explanation: 'Per Table 110.26(A)(1) at 151-600V: Condition 1 = 3 feet, Condition 2 = 3.5 feet, Condition 3 = 4 feet.' + keyPrerequisite: article-100-definitions - id: conductor-sizing - name: "Conductor Sizing and Ampacity Tables" + name: Conductor Sizing and Ampacity Tables difficulty: 4 estimatedMinutes: 30 - tags: [conductors, ampacity, table-310-16] - sourceRef: "NEC 2023 Article 310, Table 310.16" + tags: + - conductors + - ampacity + - table-310-16 + sourceRef: NEC 2023 Article 310, Table 310.16 prerequisites: - article-100-definitions - article-110-requirements knowledgePoints: - id: table-310-16 - instruction: "Table 310.16 is the most frequently referenced table on electrician exams. It provides allowable ampacities of insulated conductors rated up to 2000 volts, based on not more than 3 current-carrying conductors in raceway or cable, at an ambient temperature of 30 degrees C (86 degrees F). Key values to memorize: 14 AWG copper at 60C = 15A, at 75C = 20A. 12 AWG copper at 60C = 20A, at 75C = 25A. 10 AWG copper at 60C = 30A, at 75C = 35A. 8 AWG copper at 75C = 50A. 6 AWG copper at 75C = 65A. 4 AWG copper at 75C = 85A. 3 AWG copper at 75C = 100A. 2 AWG copper at 75C = 115A. 1 AWG copper at 75C = 130A. 1/0 AWG copper at 75C = 150A. 2/0 AWG copper at 75C = 175A. 3/0 AWG copper at 75C = 200A. 4/0 AWG copper at 75C = 230A. 250 kcmil copper at 75C = 255A. 500 kcmil copper at 75C = 380A." - workedExample: "Example: What size THWN copper conductor is needed for a 100A continuous load? Step 1: 100A continuous load requires 125% capacity per 210.19(A)(1) = 125A minimum ampacity. Step 2: THWN is rated 75C, so use the 75C column. Step 3: From Table 310.16 at 75C, 1 AWG copper = 130A >= 125A. Answer: 1 AWG copper THWN." + instruction: 'Table 310.16 is the most frequently referenced table on electrician exams. It provides allowable ampacities of insulated conductors rated up to 2000 volts, based on not more than 3 current-carrying conductors in raceway or cable, at an ambient temperature of 30 degrees C (86 degrees F). Key values to memorize: 14 AWG copper at 60C = 15A, at 75C = 20A. 12 AWG copper at 60C = 20A, at 75C = 25A. 10 AWG copper at 60C = 30A, at 75C = 35A. 8 AWG copper at 75C = 50A. 6 AWG copper at 75C = 65A. 4 AWG copper at 75C = 85A. 3 AWG copper at 75C = 100A. 2 AWG copper at 75C = 115A. 1 AWG copper at 75C = 130A. 1/0 AWG copper at 75C = 150A. 2/0 AWG copper at 75C = 175A. 3/0 AWG copper at 75C = 200A. 4/0 AWG copper at 75C = 230A. 250 kcmil copper at 75C = 255A. 500 kcmil copper at 75C = 380A.' + workedExample: 'Example: What size THWN copper conductor is needed for a 100A continuous load? Step 1: 100A continuous load requires 125% capacity per 210.19(A)(1) = 125A minimum ampacity. Step 2: THWN is rated 75C, so use the 75C column. Step 3: From Table 310.16 at 75C, 1 AWG copper = 130A >= 125A. Answer: 1 AWG copper THWN.' problems: - id: cond-size-p1 type: multiple_choice - question: "Per Table 310.16, what is the ampacity of a 6 AWG copper THWN conductor (75 degrees C column)?" + question: Per Table 310.16, what is the ampacity of a 6 AWG copper THWN conductor (75 degrees C column)? options: - - "55 amperes" - - "65 amperes" - - "75 amperes" - - "85 amperes" + - 55 amperes + - 65 amperes + - 75 amperes + - 85 amperes correct: 1 - explanation: "Per Table 310.16, 6 AWG copper at 75 degrees C has an ampacity of 65 amperes." + explanation: Per Table 310.16, 6 AWG copper at 75 degrees C has an ampacity of 65 amperes. - id: cond-size-p2 type: multiple_choice - question: "What minimum size copper conductor (75 degrees C) is required for a 200A feeder?" + question: What minimum size copper conductor (75 degrees C) is required for a 200A feeder? options: - - "2/0 AWG" - - "3/0 AWG" - - "4/0 AWG" - - "250 kcmil" + - 2/0 AWG + - 3/0 AWG + - 4/0 AWG + - 250 kcmil correct: 1 - explanation: "Per Table 310.16, 3/0 AWG copper at 75 degrees C has an ampacity of 200A, which meets the 200A requirement." + explanation: Per Table 310.16, 3/0 AWG copper at 75 degrees C has an ampacity of 200A, which meets the 200A requirement. + keyPrerequisite: article-110-requirements - id: conductor-small-conductors - instruction: "Section 240.4(D) sets specific overcurrent protection limits for small conductors: 14 AWG must be protected at not more than 15A, 12 AWG at not more than 20A, and 10 AWG at not more than 30A. These are hard limits -- even if Table 310.16 shows a higher ampacity at 75C or 90C column, the overcurrent device cannot exceed these values for these wire sizes. Exception: motor circuits and certain other specific applications listed in 240.4(D) exceptions." + instruction: 'Section 240.4(D) sets specific overcurrent protection limits for small conductors: 14 AWG must be protected at not more than 15A, 12 AWG at not more than 20A, and 10 AWG at not more than 30A. These are hard limits -- even if Table 310.16 shows a higher ampacity at 75C or 90C column, the overcurrent device cannot exceed these values for these wire sizes. Exception: motor circuits and certain other specific applications listed in 240.4(D) exceptions.' problems: - id: cond-small-p1 type: multiple_choice - question: "What is the maximum overcurrent protection permitted for 14 AWG copper conductors per 240.4(D)?" + question: What is the maximum overcurrent protection permitted for 14 AWG copper conductors per 240.4(D)? options: - - "10 amperes" - - "15 amperes" - - "20 amperes" - - "25 amperes" + - 10 amperes + - 15 amperes + - 20 amperes + - 25 amperes correct: 1 - explanation: "Per 240.4(D)(3), 14 AWG copper conductors must be protected at not more than 15 amperes." + explanation: Per 240.4(D)(3), 14 AWG copper conductors must be protected at not more than 15 amperes. - id: cond-small-p2 type: multiple_choice - question: "What is the maximum overcurrent protection for 12 AWG copper conductors per 240.4(D)?" + question: What is the maximum overcurrent protection for 12 AWG copper conductors per 240.4(D)? options: - - "15 amperes" - - "20 amperes" - - "25 amperes" - - "30 amperes" + - 15 amperes + - 20 amperes + - 25 amperes + - 30 amperes correct: 1 - explanation: "Per 240.4(D)(5), 12 AWG copper conductors must be protected at not more than 20 amperes." + explanation: Per 240.4(D)(5), 12 AWG copper conductors must be protected at not more than 20 amperes. - id: cond-small-p3 type: multiple_choice - question: "Per Table 310.16, what is the ampacity of 4/0 AWG copper at the 75 degrees C column?" + question: Per Table 310.16, what is the ampacity of 4/0 AWG copper at the 75 degrees C column? options: - - "200 amperes" - - "215 amperes" - - "230 amperes" - - "250 amperes" + - 200 amperes + - 215 amperes + - 230 amperes + - 250 amperes correct: 2 - explanation: "Per Table 310.16, 4/0 AWG copper at 75 degrees C has an ampacity of 230 amperes." + explanation: Per Table 310.16, 4/0 AWG copper at 75 degrees C has an ampacity of 230 amperes. - id: cond-small-p4 type: multiple_choice - question: "What minimum size copper conductor (75 degrees C) is needed for a 150A circuit?" + question: What minimum size copper conductor (75 degrees C) is needed for a 150A circuit? options: - - "1 AWG" - - "1/0 AWG" - - "2/0 AWG" - - "3/0 AWG" + - 1 AWG + - 1/0 AWG + - 2/0 AWG + - 3/0 AWG correct: 1 - explanation: "Per Table 310.16, 1/0 AWG copper at 75 degrees C has an ampacity of 150A, which meets the 150A requirement." - + explanation: Per Table 310.16, 1/0 AWG copper at 75 degrees C has an ampacity of 150A, which meets the 150A requirement. + keyPrerequisite: conductor-sizing - id: conductor-types - name: "Conductor Types and Identification" + name: Conductor Types and Identification difficulty: 3 estimatedMinutes: 20 - tags: [conductors, identification] - sourceRef: "NEC 2023 Article 310, Table 310.4(1)" + tags: + - conductors + - identification + sourceRef: NEC 2023 Article 310, Table 310.4(1) prerequisites: - conductor-sizing knowledgePoints: - id: conductor-id - instruction: "Common conductor types and their properties: THHN (Thermoplastic High Heat-resistant Nylon) is rated 90 degrees C dry, used in conduit. THWN (Thermoplastic Heat and Water-resistant Nylon) is rated 75 degrees C wet/dry. THWN-2 is rated 90 degrees C dry and 75 degrees C wet. NM-B (Non-Metallic sheathed cable, aka Romex) contains THHN-rated conductors but the cable assembly is rated at 60 degrees C for ampacity purposes per 334.80. UF-B (Underground Feeder) is rated 60 degrees C and suitable for direct burial. XHHW-2 is rated 90 degrees C wet and dry. Conductor color identification: per 200.6, grounded conductors (neutral) must be white or gray. Per 250.119, equipment grounding conductors must be green, green with yellow stripe, or bare. Ungrounded (hot) conductors can be any other color; convention uses black, red, blue, and orange." + instruction: 'Common conductor types and their properties: THHN (Thermoplastic High Heat-resistant Nylon) is rated 90 degrees C dry, used in conduit. THWN (Thermoplastic Heat and Water-resistant Nylon) is rated 75 degrees C wet/dry. THWN-2 is rated 90 degrees C dry and 75 degrees C wet. NM-B (Non-Metallic sheathed cable, aka Romex) contains THHN-rated conductors but the cable assembly is rated at 60 degrees C for ampacity purposes per 334.80. UF-B (Underground Feeder) is rated 60 degrees C and suitable for direct burial. XHHW-2 is rated 90 degrees C wet and dry. Conductor color identification: per 200.6, grounded conductors (neutral) must be white or gray. Per 250.119, equipment grounding conductors must be green, green with yellow stripe, or bare. Ungrounded (hot) conductors can be any other color; convention uses black, red, blue, and orange.' problems: - id: cond-type-p1 type: multiple_choice - question: "What is the temperature rating of THHN conductor insulation in dry locations?" + question: What is the temperature rating of THHN conductor insulation in dry locations? options: - - "60 degrees C" - - "75 degrees C" - - "90 degrees C" - - "105 degrees C" + - 60 degrees C + - 75 degrees C + - 90 degrees C + - 105 degrees C correct: 2 - explanation: "THHN (Thermoplastic High Heat-resistant Nylon) is rated 90 degrees C in dry locations. This is one of the most common conductor types used in conduit installations." + explanation: THHN (Thermoplastic High Heat-resistant Nylon) is rated 90 degrees C in dry locations. This is one of the most common conductor types used in conduit installations. - id: cond-type-p2 type: multiple_choice - question: "Per NEC 334.80, what temperature rating must be used for ampacity of NM-B cable conductors?" + question: Per NEC 334.80, what temperature rating must be used for ampacity of NM-B cable conductors? options: - - "60 degrees C" - - "75 degrees C" - - "90 degrees C" - - "The rating printed on the cable jacket" + - 60 degrees C + - 75 degrees C + - 90 degrees C + - The rating printed on the cable jacket correct: 0 - explanation: "Per 334.80, the ampacity of NM-B cable is determined using the 60 degrees C conductor temperature rating in Table 310.16, even though the individual conductors inside are rated at 90 degrees C." + explanation: Per 334.80, the ampacity of NM-B cable is determined using the 60 degrees C conductor temperature rating in Table 310.16, even though the individual conductors inside are rated at 90 degrees C. + keyPrerequisite: conductor-sizing - id: conductor-colors - instruction: "NEC conductor color code requirements: Grounded conductor (neutral) must be white or gray, or three continuous white or gray stripes on other than green insulation (200.6). Equipment grounding conductor must be green, green with one or more yellow stripes, or bare (250.119). High-leg delta (the B-phase in a 4-wire delta system) must be identified by an orange color or other effective means (110.15). Ungrounded (hot) conductors have no specific color requirement other than not using white, gray, green, or bare, but common convention is: black (phase A), red (phase B), blue (phase C) for 120/208V systems; brown, orange, yellow for 277/480V systems." + instruction: 'NEC conductor color code requirements: Grounded conductor (neutral) must be white or gray, or three continuous white or gray stripes on other than green insulation (200.6). Equipment grounding conductor must be green, green with one or more yellow stripes, or bare (250.119). High-leg delta (the B-phase in a 4-wire delta system) must be identified by an orange color or other effective means (110.15). Ungrounded (hot) conductors have no specific color requirement other than not using white, gray, green, or bare, but common convention is: black (phase A), red (phase B), blue (phase C) for 120/208V systems; brown, orange, yellow for 277/480V systems.' problems: - id: cond-color-p1 type: multiple_choice - question: "Per NEC 110.15, the high-leg conductor in a 4-wire delta system must be identified by what color?" + question: Per NEC 110.15, the high-leg conductor in a 4-wire delta system must be identified by what color? options: - - "Red" - - "Blue" - - "Orange" - - "Yellow" + - Red + - Blue + - Orange + - Yellow correct: 2 - explanation: "Per 110.15, the high-leg conductor (the phase with higher voltage to ground in a 4-wire delta system) must be durably and permanently marked by an outer finish that is orange in color, or by other effective means." + explanation: Per 110.15, the high-leg conductor (the phase with higher voltage to ground in a 4-wire delta system) must be durably and permanently marked by an outer finish that is orange in color, or by other effective means. - id: cond-type-p3 type: fill_blank - question: "Per 334.80, NM-B cable ampacity is determined using the ___ degrees C column of Table 310.16." - correct: "60" - explanation: "Even though the individual conductors inside NM-B are rated 90 degrees C, the cable assembly ampacity is based on the 60 degrees C column per 334.80." + question: Per 334.80, NM-B cable ampacity is determined using the ___ degrees C column of Table 310.16. + correct: '60' + explanation: Even though the individual conductors inside NM-B are rated 90 degrees C, the cable assembly ampacity is based on the 60 degrees C column per 334.80. - id: cond-type-p4 type: matching - question: "Match each conductor type with its temperature rating in dry locations." - options: - - "THHN|90 degrees C" - - "THWN|75 degrees C" - - "NM-B (cable ampacity)|60 degrees C" - - "XHHW-2|90 degrees C" - correct: "0,1,2,3" - explanation: "THHN is rated 90C dry, THWN is 75C wet/dry, NM-B cable ampacity uses 60C per 334.80, and XHHW-2 is 90C wet and dry." - - # ============================================================ - # BRANCH CIRCUITS & FEEDERS - # ============================================================ - + question: Match each conductor type with its temperature rating in dry locations. + options: + - THHN|90 degrees C + - THWN|75 degrees C + - NM-B (cable ampacity)|60 degrees C + - XHHW-2|90 degrees C + correct: 0,1,2,3 + explanation: THHN is rated 90C dry, THWN is 75C wet/dry, NM-B cable ampacity uses 60C per 334.80, and XHHW-2 is 90C wet and dry. + keyPrerequisite: article-100-definitions - id: branch-circuits - name: "Article 210 — Branch Circuits" + name: Article 210 — Branch Circuits difficulty: 4 estimatedMinutes: 30 - tags: [branch-circuits, article-210] - sourceRef: "NEC 2023 Article 210" + tags: + - branch-circuits + - article-210 + sourceRef: NEC 2023 Article 210 prerequisites: - conductor-sizing knowledgePoints: - id: branch-circuit-ratings - instruction: "Branch circuits are classified by the rating of the overcurrent device. Standard ratings are 15, 20, 30, 40, and 50 amperes (210.3). For continuous loads, the branch circuit overcurrent device and conductors must be sized at 125% of the continuous load plus 100% of the noncontinuous load (210.19(A)(1) and 210.20(A)). A 20-amp branch circuit can supply any combination of outlets, but if it supplies a single appliance, the appliance rating cannot exceed 80% of the branch circuit rating. Multioutlet branch circuits rated 15 and 20A can supply lighting and receptacles. 30A circuits supply fixed cooking and other listed loads. 40 and 50A circuits supply cooking equipment and other specific loads per 210.23." - workedExample: "Example: A 20A branch circuit supplies a 16A continuous load. Is this acceptable? Step 1: For continuous loads, the circuit must be rated at 125% of the load. Step 2: 16A x 1.25 = 20A. Step 3: The 20A circuit exactly meets this requirement. However, this leaves no room for any additional load on this circuit." + instruction: Branch circuits are classified by the rating of the overcurrent device. Standard ratings are 15, 20, 30, 40, and 50 amperes (210.3). For continuous loads, the branch circuit overcurrent device and conductors must be sized at 125% of the continuous load plus 100% of the noncontinuous load (210.19(A)(1) and 210.20(A)). A 20-amp branch circuit can supply any combination of outlets, but if it supplies a single appliance, the appliance rating cannot exceed 80% of the branch circuit rating. Multioutlet branch circuits rated 15 and 20A can supply lighting and receptacles. 30A circuits supply fixed cooking and other listed loads. 40 and 50A circuits supply cooking equipment and other specific loads per 210.23. + workedExample: 'Example: A 20A branch circuit supplies a 16A continuous load. Is this acceptable? Step 1: For continuous loads, the circuit must be rated at 125% of the load. Step 2: 16A x 1.25 = 20A. Step 3: The 20A circuit exactly meets this requirement. However, this leaves no room for any additional load on this circuit.' problems: - id: branch-p1 type: multiple_choice - question: "What is the maximum continuous load permitted on a 20-ampere branch circuit?" + question: What is the maximum continuous load permitted on a 20-ampere branch circuit? options: - - "15 amperes" - - "16 amperes" - - "18 amperes" - - "20 amperes" + - 15 amperes + - 16 amperes + - 18 amperes + - 20 amperes correct: 1 - explanation: "Per 210.20(A), a branch circuit with continuous load must be rated at 125% of the load. 20A / 1.25 = 16A maximum continuous load." + explanation: Per 210.20(A), a branch circuit with continuous load must be rated at 125% of the load. 20A / 1.25 = 16A maximum continuous load. - id: branch-p2 type: multiple_choice - question: "Which of the following is NOT a standard branch circuit rating per 210.3?" + question: Which of the following is NOT a standard branch circuit rating per 210.3? options: - - "15 amperes" - - "25 amperes" - - "30 amperes" - - "50 amperes" + - 15 amperes + - 25 amperes + - 30 amperes + - 50 amperes correct: 1 - explanation: "Per 210.3, branch circuits are rated as 15, 20, 30, 40, and 50 amperes. 25 amperes is not a standard branch circuit rating." + explanation: Per 210.3, branch circuits are rated as 15, 20, 30, 40, and 50 amperes. 25 amperes is not a standard branch circuit rating. + keyPrerequisite: article-100-definitions - id: branch-circuit-conductors - instruction: "Branch circuit conductor sizing: minimum 14 AWG for 15A circuits, 12 AWG for 20A circuits, 10 AWG for 30A circuits (210.3 and Table 210.24). The neutral conductor of a branch circuit that supplies only line-to-neutral loads can be smaller than the ungrounded conductors but not smaller than the maximum unbalanced load (210.11(B)). For multi-wire branch circuits (210.4), all ungrounded conductors must be disconnected simultaneously at the point where the branch circuit originates. This requires a 2-pole or 3-pole breaker, or handle ties." + instruction: 'Branch circuit conductor sizing: minimum 14 AWG for 15A circuits, 12 AWG for 20A circuits, 10 AWG for 30A circuits (210.3 and Table 210.24). The neutral conductor of a branch circuit that supplies only line-to-neutral loads can be smaller than the ungrounded conductors but not smaller than the maximum unbalanced load (210.11(B)). For multi-wire branch circuits (210.4), all ungrounded conductors must be disconnected simultaneously at the point where the branch circuit originates. This requires a 2-pole or 3-pole breaker, or handle ties.' problems: - id: branch-cond-p1 type: multiple_choice - question: "What is the minimum conductor size for a 30-ampere branch circuit?" + question: What is the minimum conductor size for a 30-ampere branch circuit? options: - - "14 AWG" - - "12 AWG" - - "10 AWG" - - "8 AWG" + - 14 AWG + - 12 AWG + - 10 AWG + - 8 AWG correct: 2 - explanation: "Per Table 210.24, a 30-ampere branch circuit requires a minimum conductor size of 10 AWG copper." + explanation: Per Table 210.24, a 30-ampere branch circuit requires a minimum conductor size of 10 AWG copper. - id: branch-cond-p2 type: multiple_choice - question: "A multi-wire branch circuit must have all ungrounded conductors disconnected simultaneously. This requires:" + question: 'A multi-wire branch circuit must have all ungrounded conductors disconnected simultaneously. This requires:' options: - - "Individual single-pole breakers" - - "A 2-pole or 3-pole breaker, or breakers with handle ties" - - "A separate disconnect switch" - - "GFCI protection on each conductor" + - Individual single-pole breakers + - A 2-pole or 3-pole breaker, or breakers with handle ties + - A separate disconnect switch + - GFCI protection on each conductor correct: 1 - explanation: "Per 210.4(B), each multi-wire branch circuit must be provided with a means that will simultaneously disconnect all ungrounded conductors at the point where the branch circuit originates. This is typically achieved with a 2-pole or 3-pole breaker, or handle ties." + explanation: Per 210.4(B), each multi-wire branch circuit must be provided with a means that will simultaneously disconnect all ungrounded conductors at the point where the branch circuit originates. This is typically achieved with a 2-pole or 3-pole breaker, or handle ties. - id: branch-cond-p3 type: multiple_choice - question: "What is the maximum load permitted on a single receptacle connected to a 20A branch circuit?" + question: What is the maximum load permitted on a single receptacle connected to a 20A branch circuit? options: - - "12 amperes" - - "16 amperes" - - "20 amperes" - - "24 amperes" + - 12 amperes + - 16 amperes + - 20 amperes + - 24 amperes correct: 1 - explanation: "Per 210.21(B)(2), a single receptacle on an individual branch circuit must have an ampere rating not less than the branch circuit rating. However, per 210.21(B)(1) and 210.23(A)(1), a single appliance cannot exceed 80% of the branch circuit rating. 20A x 0.80 = 16A maximum." - + explanation: Per 210.21(B)(2), a single receptacle on an individual branch circuit must have an ampere rating not less than the branch circuit rating. However, per 210.21(B)(1) and 210.23(A)(1), a single appliance cannot exceed 80% of the branch circuit rating. 20A x 0.80 = 16A maximum. + keyPrerequisite: branch-circuits - id: feeders - name: "Article 215 — Feeders" + name: Article 215 — Feeders difficulty: 4 estimatedMinutes: 25 - tags: [feeders, article-215] - sourceRef: "NEC 2023 Article 215" + tags: + - feeders + - article-215 + sourceRef: NEC 2023 Article 215 prerequisites: - branch-circuits knowledgePoints: - id: feeder-sizing - instruction: "Feeder conductors must have an ampacity not less than the sum of all branch circuit loads supplied, considering demand factors from Article 220 (215.2(A)(1)). For continuous loads, feeder conductors must be sized at 125% of the continuous load plus 100% of the noncontinuous load. The feeder overcurrent device must also be sized this way. The feeder neutral conductor must be sized to carry the maximum unbalanced load (220.61). For a 3-wire, single-phase dwelling feeder, the maximum unbalanced load is the maximum net load between the neutral and any ungrounded conductor." - workedExample: "Example: A feeder supplies 40A of continuous load and 60A of noncontinuous load. What minimum ampacity is required? Step 1: 40A x 1.25 = 50A (continuous portion). Step 2: 60A x 1.00 = 60A (noncontinuous portion). Step 3: Total = 50A + 60A = 110A. Step 4: From Table 310.16 at 75C: 1 AWG = 130A. Minimum conductor: 1 AWG copper." + instruction: Feeder conductors must have an ampacity not less than the sum of all branch circuit loads supplied, considering demand factors from Article 220 (215.2(A)(1)). For continuous loads, feeder conductors must be sized at 125% of the continuous load plus 100% of the noncontinuous load. The feeder overcurrent device must also be sized this way. The feeder neutral conductor must be sized to carry the maximum unbalanced load (220.61). For a 3-wire, single-phase dwelling feeder, the maximum unbalanced load is the maximum net load between the neutral and any ungrounded conductor. + workedExample: 'Example: A feeder supplies 40A of continuous load and 60A of noncontinuous load. What minimum ampacity is required? Step 1: 40A x 1.25 = 50A (continuous portion). Step 2: 60A x 1.00 = 60A (noncontinuous portion). Step 3: Total = 50A + 60A = 110A. Step 4: From Table 310.16 at 75C: 1 AWG = 130A. Minimum conductor: 1 AWG copper.' problems: - id: feeder-p1 type: multiple_choice - question: "A feeder supplies 80A of continuous load and 20A of noncontinuous load. What is the minimum required ampacity for the feeder conductors?" + question: A feeder supplies 80A of continuous load and 20A of noncontinuous load. What is the minimum required ampacity for the feeder conductors? options: - - "100 amperes" - - "110 amperes" - - "120 amperes" - - "125 amperes" + - 100 amperes + - 110 amperes + - 120 amperes + - 125 amperes correct: 2 - explanation: "Per 215.2(A)(1), feeder conductors must be sized at 125% of continuous load plus 100% of noncontinuous: (80A x 1.25) + (20A x 1.0) = 100A + 20A = 120A." + explanation: 'Per 215.2(A)(1), feeder conductors must be sized at 125% of continuous load plus 100% of noncontinuous: (80A x 1.25) + (20A x 1.0) = 100A + 20A = 120A.' - id: feeder-p2 type: true_false - question: "Feeder conductors must always be sized at 125% of the total connected load." - correct: "false" - explanation: "The 125% factor only applies to the continuous portion of the load. Noncontinuous loads are calculated at 100%. The total required ampacity is (125% x continuous) + (100% x noncontinuous)." + question: Feeder conductors must always be sized at 125% of the total connected load. + correct: 'false' + explanation: The 125% factor only applies to the continuous portion of the load. Noncontinuous loads are calculated at 100%. The total required ampacity is (125% x continuous) + (100% x noncontinuous). - id: feeder-p3 type: multiple_choice - question: "A feeder supplies 50A continuous and 50A noncontinuous load. What minimum ampacity is required?" + question: A feeder supplies 50A continuous and 50A noncontinuous load. What minimum ampacity is required? options: - - "100 amperes" - - "112.5 amperes" - - "125 amperes" - - "150 amperes" + - 100 amperes + - 112.5 amperes + - 125 amperes + - 150 amperes correct: 1 - explanation: "Per 215.2(A)(1), feeder ampacity = (50A x 1.25) + (50A x 1.0) = 62.5 + 50 = 112.5A. The next standard size breaker up from 112.5A would be needed." + explanation: Per 215.2(A)(1), feeder ampacity = (50A x 1.25) + (50A x 1.0) = 62.5 + 50 = 112.5A. The next standard size breaker up from 112.5A would be needed. - id: feeder-p4 type: fill_blank - question: "The feeder neutral conductor must be sized to carry the maximum ___ load per 220.61." - correct: "unbalanced" - explanation: "Per 220.61, the feeder neutral load is the maximum unbalanced load between the neutral and any ungrounded conductor." - + question: The feeder neutral conductor must be sized to carry the maximum ___ load per 220.61. + correct: unbalanced + explanation: Per 220.61, the feeder neutral load is the maximum unbalanced load between the neutral and any ungrounded conductor. + keyPrerequisite: branch-circuits - id: overcurrent-protection - name: "Article 240 — Overcurrent Protection" + name: Article 240 — Overcurrent Protection difficulty: 5 estimatedMinutes: 30 - tags: [overcurrent, fuses, breakers, article-240] - sourceRef: "NEC 2023 Article 240" + tags: + - overcurrent + - fuses + - breakers + - article-240 + sourceRef: NEC 2023 Article 240 prerequisites: - conductor-sizing - branch-circuits knowledgePoints: - id: standard-oc-ratings - instruction: "Section 240.6(A) lists the standard ampere ratings for fuses and inverse time circuit breakers: 15, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100, 110, 125, 150, 175, 200, 225, 250, 300, 350, 400, 450, 500, 600, 700, 800, 1000, 1200, 1600, 2000, 2500, 3000, 4000, 5000, 6000. The next-size-up rule (240.4(B)) allows the next standard overcurrent device rating above the conductor ampacity when the conductor ampacity does not correspond to a standard rating -- but only up to 800A. Above 800A, the conductor ampacity must be equal to or greater than the overcurrent device rating." - workedExample: "Example: A 3/0 AWG copper conductor at 75C has an ampacity of 200A from Table 310.16. Since 200A is a standard rating per 240.6(A), a 200A breaker is used. If the calculated load required 195A protection, you would still use a 200A breaker since it is the next standard size up, and the conductor must have 200A ampacity." + instruction: 'Section 240.6(A) lists the standard ampere ratings for fuses and inverse time circuit breakers: 15, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100, 110, 125, 150, 175, 200, 225, 250, 300, 350, 400, 450, 500, 600, 700, 800, 1000, 1200, 1600, 2000, 2500, 3000, 4000, 5000, 6000. The next-size-up rule (240.4(B)) allows the next standard overcurrent device rating above the conductor ampacity when the conductor ampacity does not correspond to a standard rating -- but only up to 800A. Above 800A, the conductor ampacity must be equal to or greater than the overcurrent device rating.' + workedExample: 'Example: A 3/0 AWG copper conductor at 75C has an ampacity of 200A from Table 310.16. Since 200A is a standard rating per 240.6(A), a 200A breaker is used. If the calculated load required 195A protection, you would still use a 200A breaker since it is the next standard size up, and the conductor must have 200A ampacity.' problems: - id: oc-p1 type: multiple_choice - question: "Per 240.6(A), which of the following is a standard ampere rating for a circuit breaker?" + question: Per 240.6(A), which of the following is a standard ampere rating for a circuit breaker? options: - - "45 amperes" - - "55 amperes" - - "65 amperes" - - "85 amperes" + - 45 amperes + - 55 amperes + - 65 amperes + - 85 amperes correct: 0 - explanation: "Per 240.6(A), 45 amperes is a standard rating. The standard ratings include 15, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100, etc." + explanation: Per 240.6(A), 45 amperes is a standard rating. The standard ratings include 15, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100, etc. - id: oc-p2 type: multiple_choice - question: "Per 240.4(B), when can the next standard size overcurrent device be used above the conductor ampacity?" + question: Per 240.4(B), when can the next standard size overcurrent device be used above the conductor ampacity? options: - - "Always, regardless of ampacity" - - "Only for circuits rated 800 amperes or less" - - "Only for circuits rated 400 amperes or less" - - "Only for motor circuits" + - Always, regardless of ampacity + - Only for circuits rated 800 amperes or less + - Only for circuits rated 400 amperes or less + - Only for motor circuits correct: 1 - explanation: "Per 240.4(B), the next-size-up rule applies when the ampacity of conductors does not correspond to a standard overcurrent device rating, but only up to 800A. Above 800A, the overcurrent device rating must not exceed the conductor ampacity." + explanation: Per 240.4(B), the next-size-up rule applies when the ampacity of conductors does not correspond to a standard overcurrent device rating, but only up to 800A. Above 800A, the overcurrent device rating must not exceed the conductor ampacity. + keyPrerequisite: conductor-sizing - id: tap-rules - instruction: "Section 240.21 allows conductors to be tapped from feeders without individual overcurrent protection at the tap point under specific conditions. The 10-foot tap rule (240.21(B)(1)) allows tap conductors up to 10 feet long if: the tap conductor ampacity is not less than the combined calculated loads it serves, and the tap conductor ampacity is not less than the rating of the device at the termination end, and the tap is enclosed in raceway. The 25-foot tap rule (240.21(B)(2)) allows tap conductors up to 25 feet if: ampacity is not less than 1/3 of the rating of the overcurrent device at the supply end, the tap terminates in a single circuit breaker or set of fuses that limits the load, and the tap is protected from physical damage." + instruction: 'Section 240.21 allows conductors to be tapped from feeders without individual overcurrent protection at the tap point under specific conditions. The 10-foot tap rule (240.21(B)(1)) allows tap conductors up to 10 feet long if: the tap conductor ampacity is not less than the combined calculated loads it serves, and the tap conductor ampacity is not less than the rating of the device at the termination end, and the tap is enclosed in raceway. The 25-foot tap rule (240.21(B)(2)) allows tap conductors up to 25 feet if: ampacity is not less than 1/3 of the rating of the overcurrent device at the supply end, the tap terminates in a single circuit breaker or set of fuses that limits the load, and the tap is protected from physical damage.' problems: - id: oc-tap-p1 type: multiple_choice - question: "Under the 25-foot tap rule (240.21(B)(2)), what is the minimum ampacity of a tap conductor from a 300A feeder?" + question: Under the 25-foot tap rule (240.21(B)(2)), what is the minimum ampacity of a tap conductor from a 300A feeder? options: - - "75 amperes" - - "100 amperes" - - "150 amperes" - - "200 amperes" + - 75 amperes + - 100 amperes + - 150 amperes + - 200 amperes correct: 1 - explanation: "Per 240.21(B)(2), for a 25-foot tap, the conductor ampacity must be not less than 1/3 of the rating of the overcurrent device protecting the feeder. 300A / 3 = 100A minimum." + explanation: Per 240.21(B)(2), for a 25-foot tap, the conductor ampacity must be not less than 1/3 of the rating of the overcurrent device protecting the feeder. 300A / 3 = 100A minimum. - id: oc-p3 type: fill_blank - question: "Per 240.4(B), the next-size-up rule for overcurrent devices applies only to circuits rated ___ amperes or less." - correct: "800" - explanation: "Per 240.4(B), the next standard size overcurrent device above the conductor ampacity may be used, but only up to 800A. Above 800A, the overcurrent device must not exceed the conductor ampacity." + question: Per 240.4(B), the next-size-up rule for overcurrent devices applies only to circuits rated ___ amperes or less. + correct: '800' + explanation: Per 240.4(B), the next standard size overcurrent device above the conductor ampacity may be used, but only up to 800A. Above 800A, the overcurrent device must not exceed the conductor ampacity. - id: oc-p4 type: ordering - question: "Place these standard overcurrent device ratings in ascending order per 240.6(A)." - options: - - "60 amperes" - - "35 amperes" - - "90 amperes" - - "45 amperes" - correct: "1,3,0,2" - explanation: "Per 240.6(A), the standard ratings in ascending order are: 35, 45, 60, 90 amperes." - - # ============================================================ - # GROUNDING & BONDING - # ============================================================ - + question: Place these standard overcurrent device ratings in ascending order per 240.6(A). + options: + - 60 amperes + - 35 amperes + - 90 amperes + - 45 amperes + correct: 1,3,0,2 + explanation: 'Per 240.6(A), the standard ratings in ascending order are: 35, 45, 60, 90 amperes.' + keyPrerequisite: overcurrent-protection - id: grounding-fundamentals - name: "Article 250 — Grounding Fundamentals" + name: Article 250 — Grounding Fundamentals difficulty: 5 estimatedMinutes: 30 - tags: [grounding, bonding, article-250] - sourceRef: "NEC 2023 Article 250, Parts I-III" + tags: + - grounding + - bonding + - article-250 + sourceRef: NEC 2023 Article 250, Parts I-III prerequisites: - article-100-definitions - overcurrent-protection knowledgePoints: - id: grounding-purposes - instruction: "Grounding serves two primary purposes: (1) to stabilize the voltage to ground during normal operation, and (2) to facilitate overcurrent device operation during a ground fault. Systems must be grounded per 250.20 -- AC systems of 50V to 1000V are required to be grounded where the system can be grounded so that the maximum voltage to ground does not exceed 150V. This includes standard 120/240V single-phase and 120/208V three-phase wye systems. The grounding electrode conductor (GEC) connects the system grounded conductor (neutral) to the grounding electrode at the service. The main bonding jumper connects the grounded conductor to the equipment grounding bus in the service equipment." - workedExample: "Example: Why does a 120/208V 3-phase wye system need to be grounded? Per 250.20(B)(1), AC systems of 50-1000V supplying premises wiring must be grounded when the system can be grounded so that the maximum voltage to ground does not exceed 150V. In a 120/208V wye, the maximum voltage to ground is 120V (line to neutral), which is under 150V." + instruction: 'Grounding serves two primary purposes: (1) to stabilize the voltage to ground during normal operation, and (2) to facilitate overcurrent device operation during a ground fault. Systems must be grounded per 250.20 -- AC systems of 50V to 1000V are required to be grounded where the system can be grounded so that the maximum voltage to ground does not exceed 150V. This includes standard 120/240V single-phase and 120/208V three-phase wye systems. The grounding electrode conductor (GEC) connects the system grounded conductor (neutral) to the grounding electrode at the service. The main bonding jumper connects the grounded conductor to the equipment grounding bus in the service equipment.' + workedExample: 'Example: Why does a 120/208V 3-phase wye system need to be grounded? Per 250.20(B)(1), AC systems of 50-1000V supplying premises wiring must be grounded when the system can be grounded so that the maximum voltage to ground does not exceed 150V. In a 120/208V wye, the maximum voltage to ground is 120V (line to neutral), which is under 150V.' problems: - id: gnd-fund-p1 type: multiple_choice - question: "What are the two primary purposes of grounding an electrical system?" + question: What are the two primary purposes of grounding an electrical system? options: - - "To reduce electricity costs and improve power quality" - - "To stabilize voltage to ground and facilitate overcurrent device operation during ground faults" - - "To protect equipment from lightning and prevent static buildup" - - "To reduce electromagnetic interference and meet utility requirements" + - To reduce electricity costs and improve power quality + - To stabilize voltage to ground and facilitate overcurrent device operation during ground faults + - To protect equipment from lightning and prevent static buildup + - To reduce electromagnetic interference and meet utility requirements correct: 1 - explanation: "Grounding stabilizes voltage to ground during normal operation and provides a low-impedance ground-fault current path to facilitate overcurrent device operation, clearing the fault quickly." + explanation: Grounding stabilizes voltage to ground during normal operation and provides a low-impedance ground-fault current path to facilitate overcurrent device operation, clearing the fault quickly. - id: gnd-fund-p2 type: multiple_choice - question: "The main bonding jumper in the service equipment connects:" + question: 'The main bonding jumper in the service equipment connects:' options: - - "The grounding electrode to the water pipe" - - "The grounded conductor (neutral) bus to the equipment grounding bus" - - "The service entrance conductors to the meter base" - - "Two grounding electrodes together" + - The grounding electrode to the water pipe + - The grounded conductor (neutral) bus to the equipment grounding bus + - The service entrance conductors to the meter base + - Two grounding electrodes together correct: 1 - explanation: "The main bonding jumper connects the grounded conductor (neutral) to the equipment grounding conductor bus at the service equipment. This connection is required by 250.24(B) and is what allows fault current to return to the source." + explanation: The main bonding jumper connects the grounded conductor (neutral) to the equipment grounding conductor bus at the service equipment. This connection is required by 250.24(B) and is what allows fault current to return to the source. + keyPrerequisite: article-100-definitions - id: egc-sizing - instruction: "Equipment grounding conductors (EGCs) are sized per Table 250.122 based on the rating of the overcurrent device ahead of the circuit. Key values: 15A circuit = 14 AWG copper, 20A = 12 AWG, 30A = 10 AWG, 40A = 10 AWG, 60A = 10 AWG, 100A = 8 AWG, 200A = 6 AWG, 300A = 4 AWG, 400A = 3 AWG, 500A = 2 AWG, 600A = 1 AWG, 800A = 1/0 AWG, 1000A = 2/0 AWG, 1200A = 3/0 AWG. Note: when conductors are increased in size for voltage drop or other reasons, the EGC must also be proportionally increased per 250.122(B)." + instruction: 'Equipment grounding conductors (EGCs) are sized per Table 250.122 based on the rating of the overcurrent device ahead of the circuit. Key values: 15A circuit = 14 AWG copper, 20A = 12 AWG, 30A = 10 AWG, 40A = 10 AWG, 60A = 10 AWG, 100A = 8 AWG, 200A = 6 AWG, 300A = 4 AWG, 400A = 3 AWG, 500A = 2 AWG, 600A = 1 AWG, 800A = 1/0 AWG, 1000A = 2/0 AWG, 1200A = 3/0 AWG. Note: when conductors are increased in size for voltage drop or other reasons, the EGC must also be proportionally increased per 250.122(B).' problems: - id: egc-p1 type: multiple_choice - question: "Per Table 250.122, what minimum size copper EGC is required for a circuit protected by a 200A breaker?" + question: Per Table 250.122, what minimum size copper EGC is required for a circuit protected by a 200A breaker? options: - - "8 AWG" - - "6 AWG" - - "4 AWG" - - "3 AWG" + - 8 AWG + - 6 AWG + - 4 AWG + - 3 AWG correct: 1 - explanation: "Per Table 250.122, for a circuit with a 200-ampere overcurrent device, the minimum copper equipment grounding conductor size is 6 AWG." + explanation: Per Table 250.122, for a circuit with a 200-ampere overcurrent device, the minimum copper equipment grounding conductor size is 6 AWG. - id: egc-p2 type: multiple_choice - question: "Per Table 250.122, what minimum size copper EGC is required for a 60A circuit?" + question: Per Table 250.122, what minimum size copper EGC is required for a 60A circuit? options: - - "14 AWG" - - "12 AWG" - - "10 AWG" - - "8 AWG" + - 14 AWG + - 12 AWG + - 10 AWG + - 8 AWG correct: 2 - explanation: "Per Table 250.122, for an overcurrent device rated at 60 amperes, the minimum copper EGC size is 10 AWG." + explanation: Per Table 250.122, for an overcurrent device rated at 60 amperes, the minimum copper EGC size is 10 AWG. - id: egc-p3 type: multiple_choice - question: "Per Table 250.122, what minimum size copper EGC is required for a 400A circuit?" + question: Per Table 250.122, what minimum size copper EGC is required for a 400A circuit? options: - - "4 AWG" - - "3 AWG" - - "2 AWG" - - "1 AWG" + - 4 AWG + - 3 AWG + - 2 AWG + - 1 AWG correct: 1 - explanation: "Per Table 250.122, for an overcurrent device rated at 400 amperes, the minimum copper EGC size is 3 AWG." + explanation: Per Table 250.122, for an overcurrent device rated at 400 amperes, the minimum copper EGC size is 3 AWG. - id: egc-p4 type: true_false - question: "When conductors are increased in size for voltage drop, the EGC must also be proportionally increased." - correct: "true" - explanation: "Per 250.122(B), when ungrounded conductors are increased in size for voltage drop or any other reason, the equipment grounding conductor must be proportionally increased in size." - + question: When conductors are increased in size for voltage drop, the EGC must also be proportionally increased. + correct: 'true' + explanation: Per 250.122(B), when ungrounded conductors are increased in size for voltage drop or any other reason, the equipment grounding conductor must be proportionally increased in size. + keyPrerequisite: overcurrent-protection - id: grounding-electrode-system - name: "Article 250 Part III — Grounding Electrode System" + name: Article 250 Part III — Grounding Electrode System difficulty: 5 estimatedMinutes: 25 - tags: [grounding, electrodes, article-250] - sourceRef: "NEC 2023 Article 250, Part III" + tags: + - grounding + - electrodes + - article-250 + sourceRef: NEC 2023 Article 250, Part III prerequisites: - grounding-fundamentals knowledgePoints: - id: electrode-types - instruction: "The grounding electrode system (250.50) requires all electrodes present at the building to be bonded together. Electrodes include: metal underground water pipe in direct contact with earth for at least 10 feet (250.52(A)(1)), metal in-ground support structure (250.52(A)(2)), concrete-encased electrode (Ufer ground) -- at least 20 feet of bare copper 4 AWG or larger encased in at least 2 inches of concrete in contact with earth (250.52(A)(3)), ground ring -- bare copper 2 AWG or larger encircling the building, in contact with earth at a depth of at least 30 inches (250.52(A)(4)), rod and pipe electrodes -- at least 8 feet long, driven into the earth (250.52(A)(5)), and plate electrodes -- at least 2 sq ft of surface exposed to soil (250.52(A)(7))." - workedExample: "Example: A building has a metal water pipe entering the ground, a concrete footing with rebar, and two ground rods. Per 250.50, ALL of these electrodes must be bonded together to form the grounding electrode system. You cannot pick just one." + instruction: 'The grounding electrode system (250.50) requires all electrodes present at the building to be bonded together. Electrodes include: metal underground water pipe in direct contact with earth for at least 10 feet (250.52(A)(1)), metal in-ground support structure (250.52(A)(2)), concrete-encased electrode (Ufer ground) -- at least 20 feet of bare copper 4 AWG or larger encased in at least 2 inches of concrete in contact with earth (250.52(A)(3)), ground ring -- bare copper 2 AWG or larger encircling the building, in contact with earth at a depth of at least 30 inches (250.52(A)(4)), rod and pipe electrodes -- at least 8 feet long, driven into the earth (250.52(A)(5)), and plate electrodes -- at least 2 sq ft of surface exposed to soil (250.52(A)(7)).' + workedExample: 'Example: A building has a metal water pipe entering the ground, a concrete footing with rebar, and two ground rods. Per 250.50, ALL of these electrodes must be bonded together to form the grounding electrode system. You cannot pick just one.' problems: - id: electrode-p1 type: multiple_choice - question: "What is the minimum length of a ground rod electrode per 250.52(A)(5)?" + question: What is the minimum length of a ground rod electrode per 250.52(A)(5)? options: - - "4 feet" - - "6 feet" - - "8 feet" - - "10 feet" + - 4 feet + - 6 feet + - 8 feet + - 10 feet correct: 2 - explanation: "Per 250.52(A)(5), rod-type grounding electrodes must be at least 8 feet (2.44 m) in length and must be driven to a depth of at least 8 feet." + explanation: Per 250.52(A)(5), rod-type grounding electrodes must be at least 8 feet (2.44 m) in length and must be driven to a depth of at least 8 feet. - id: electrode-p2 type: multiple_choice - question: "A concrete-encased electrode (Ufer ground) requires at least how many feet of bare copper conductor?" + question: A concrete-encased electrode (Ufer ground) requires at least how many feet of bare copper conductor? options: - - "10 feet" - - "15 feet" - - "20 feet" - - "25 feet" + - 10 feet + - 15 feet + - 20 feet + - 25 feet correct: 2 - explanation: "Per 250.52(A)(3), a concrete-encased electrode requires at least 20 feet of bare copper conductor not smaller than 4 AWG, encased in at least 2 inches of concrete in direct contact with the earth." + explanation: Per 250.52(A)(3), a concrete-encased electrode requires at least 20 feet of bare copper conductor not smaller than 4 AWG, encased in at least 2 inches of concrete in direct contact with the earth. + keyPrerequisite: grounding-fundamentals - id: gec-sizing - instruction: "The grounding electrode conductor (GEC) connects the grounded conductor (neutral) at the service to the grounding electrode system. It is sized per Table 250.66 based on the size of the largest service-entrance conductor or equivalent area of parallel conductors. Key values: for service conductors up to 2 AWG copper, the GEC is 8 AWG copper. For 1 AWG or 1/0, GEC is 6 AWG. For 2/0 or 3/0, GEC is 4 AWG. For over 3/0 through 350 kcmil, GEC is 2 AWG. For over 350 through 600 kcmil, GEC is 1/0 AWG. For over 600 through 1100 kcmil, GEC is 2/0 AWG. For over 1100 kcmil, GEC is 3/0 AWG copper." + instruction: 'The grounding electrode conductor (GEC) connects the grounded conductor (neutral) at the service to the grounding electrode system. It is sized per Table 250.66 based on the size of the largest service-entrance conductor or equivalent area of parallel conductors. Key values: for service conductors up to 2 AWG copper, the GEC is 8 AWG copper. For 1 AWG or 1/0, GEC is 6 AWG. For 2/0 or 3/0, GEC is 4 AWG. For over 3/0 through 350 kcmil, GEC is 2 AWG. For over 350 through 600 kcmil, GEC is 1/0 AWG. For over 600 through 1100 kcmil, GEC is 2/0 AWG. For over 1100 kcmil, GEC is 3/0 AWG copper.' problems: - id: gec-p1 type: multiple_choice - question: "Per Table 250.66, what size copper GEC is required for 3/0 AWG copper service entrance conductors?" + question: Per Table 250.66, what size copper GEC is required for 3/0 AWG copper service entrance conductors? options: - - "8 AWG" - - "6 AWG" - - "4 AWG" - - "2 AWG" + - 8 AWG + - 6 AWG + - 4 AWG + - 2 AWG correct: 2 - explanation: "Per Table 250.66, for service entrance conductors of 2/0 or 3/0 AWG copper, the grounding electrode conductor must be not smaller than 4 AWG copper." + explanation: Per Table 250.66, for service entrance conductors of 2/0 or 3/0 AWG copper, the grounding electrode conductor must be not smaller than 4 AWG copper. - id: gec-p2 type: multiple_choice - question: "Per Table 250.66, what size copper GEC is required for 500 kcmil copper service entrance conductors?" + question: Per Table 250.66, what size copper GEC is required for 500 kcmil copper service entrance conductors? options: - - "2 AWG" - - "1 AWG" - - "1/0 AWG" - - "2/0 AWG" + - 2 AWG + - 1 AWG + - 1/0 AWG + - 2/0 AWG correct: 2 - explanation: "Per Table 250.66, for service entrance conductors over 350 through 600 kcmil copper, the GEC must be not smaller than 1/0 AWG copper." + explanation: Per Table 250.66, for service entrance conductors over 350 through 600 kcmil copper, the GEC must be not smaller than 1/0 AWG copper. - id: gec-p3 type: true_false - question: "A metal underground water pipe used as a grounding electrode must be in direct contact with the earth for at least 10 feet." - correct: "true" - explanation: "Per 250.52(A)(1), a metal underground water pipe qualifies as a grounding electrode when it is in direct contact with the earth for 10 feet (3.0 m) or more." - + question: A metal underground water pipe used as a grounding electrode must be in direct contact with the earth for at least 10 feet. + correct: 'true' + explanation: Per 250.52(A)(1), a metal underground water pipe qualifies as a grounding electrode when it is in direct contact with the earth for 10 feet (3.0 m) or more. + keyPrerequisite: grounding-electrode-system - id: bonding - name: "Article 250 Part V — Bonding" + name: Article 250 Part V — Bonding difficulty: 5 estimatedMinutes: 20 - tags: [grounding, bonding, article-250] - sourceRef: "NEC 2023 Article 250, Part V" + tags: + - grounding + - bonding + - article-250 + sourceRef: NEC 2023 Article 250, Part V prerequisites: - grounding-fundamentals knowledgePoints: - id: bonding-service - instruction: "Bonding at the service is critical for safety. Per 250.92, the following must be bonded at the service: service raceways, service cable armor, all service equipment enclosures containing service conductors, and any conduit or raceway from the service point to the service disconnecting means. Methods for bonding at the service (250.92(B)) include: bonding to the grounded service conductor, connections using threaded couplings or hubs on threaded entries, bonding-type locknuts, and bonding bushings with bonding jumpers. Standard locknuts alone are NOT permitted for bonding service equipment." + instruction: 'Bonding at the service is critical for safety. Per 250.92, the following must be bonded at the service: service raceways, service cable armor, all service equipment enclosures containing service conductors, and any conduit or raceway from the service point to the service disconnecting means. Methods for bonding at the service (250.92(B)) include: bonding to the grounded service conductor, connections using threaded couplings or hubs on threaded entries, bonding-type locknuts, and bonding bushings with bonding jumpers. Standard locknuts alone are NOT permitted for bonding service equipment.' problems: - id: bond-p1 type: true_false - question: "Standard locknuts are an acceptable means of bonding service equipment enclosures." - correct: "false" - explanation: "Per 250.92(B), standard locknuts are NOT listed as an acceptable bonding method at the service. Bonding at the service requires bonding bushings, bonding-type locknuts, threaded hubs, or connections to the grounded conductor." + question: Standard locknuts are an acceptable means of bonding service equipment enclosures. + correct: 'false' + explanation: Per 250.92(B), standard locknuts are NOT listed as an acceptable bonding method at the service. Bonding at the service requires bonding bushings, bonding-type locknuts, threaded hubs, or connections to the grounded conductor. - id: bond-p2 type: multiple_choice - question: "Which of the following must be bonded at the service per 250.92(A)?" + question: Which of the following must be bonded at the service per 250.92(A)? options: - - "Only the main panel enclosure" - - "All service raceways, cable armor, and enclosures containing service conductors" - - "Only metal water pipes within 5 feet of the panel" - - "Only the meter base" + - Only the main panel enclosure + - All service raceways, cable armor, and enclosures containing service conductors + - Only metal water pipes within 5 feet of the panel + - Only the meter base correct: 1 - explanation: "Per 250.92(A), the non-current-carrying metal parts that must be bonded include: service raceways, service cable armor or sheath, all service equipment enclosures containing service conductors, and any raceway or armor from the service point." + explanation: 'Per 250.92(A), the non-current-carrying metal parts that must be bonded include: service raceways, service cable armor or sheath, all service equipment enclosures containing service conductors, and any raceway or armor from the service point.' - id: bond-p3 type: fill_blank - question: "The ___ bonding jumper connects the grounded conductor (neutral) to the equipment grounding bus in the service equipment." - correct: "main" - explanation: "The main bonding jumper is required by 250.24(B) and establishes the connection between the grounded conductor and the equipment grounding conductor at the service." + question: The ___ bonding jumper connects the grounded conductor (neutral) to the equipment grounding bus in the service equipment. + correct: main + explanation: The main bonding jumper is required by 250.24(B) and establishes the connection between the grounded conductor and the equipment grounding conductor at the service. - id: bond-p4 type: matching - question: "Match each bonding method with whether it is acceptable at the service per 250.92(B)." - options: - - "Bonding bushings with jumpers|Acceptable" - - "Standard locknuts alone|NOT acceptable" - - "Threaded hubs|Acceptable" - - "Bonding-type locknuts|Acceptable" - correct: "0,1,2,3" - explanation: "Per 250.92(B), standard locknuts alone are NOT an acceptable bonding method at the service. Bonding bushings, threaded hubs, and bonding-type locknuts are all acceptable." - - # ============================================================ - # WIRING METHODS - # ============================================================ - + question: Match each bonding method with whether it is acceptable at the service per 250.92(B). + options: + - Bonding bushings with jumpers|Acceptable + - Standard locknuts alone|NOT acceptable + - Threaded hubs|Acceptable + - Bonding-type locknuts|Acceptable + correct: 0,1,2,3 + explanation: Per 250.92(B), standard locknuts alone are NOT an acceptable bonding method at the service. Bonding bushings, threaded hubs, and bonding-type locknuts are all acceptable. + keyPrerequisite: grounding-fundamentals - id: wiring-methods-overview - name: "Article 300 — General Wiring Methods" + name: Article 300 — General Wiring Methods difficulty: 3 estimatedMinutes: 20 - tags: [wiring-methods, article-300] - sourceRef: "NEC 2023 Article 300" + tags: + - wiring-methods + - article-300 + sourceRef: NEC 2023 Article 300 prerequisites: - conductor-types knowledgePoints: - id: wiring-general - instruction: "Article 300 contains general requirements applying to all wiring methods. Section 300.4 requires protection of conductors against physical damage. Cables through wood framing must be set back at least 1-1/4 inches from the edge of the framing member, or protected by a steel plate at least 1/16 inch thick (300.4(A)(1)). Section 300.5 covers underground installations -- minimum burial depths for direct-buried cables and conduits are in Table 300.5. For example, rigid metal conduit requires 6 inches minimum cover, PVC conduit requires 18 inches, and direct-buried UF cable requires 24 inches (residential circuits of 120V or less with GFCI can be 12 inches). All conductors of a circuit must be contained within the same raceway, cable, or trench (300.3(B)) to avoid inductive heating." + instruction: Article 300 contains general requirements applying to all wiring methods. Section 300.4 requires protection of conductors against physical damage. Cables through wood framing must be set back at least 1-1/4 inches from the edge of the framing member, or protected by a steel plate at least 1/16 inch thick (300.4(A)(1)). Section 300.5 covers underground installations -- minimum burial depths for direct-buried cables and conduits are in Table 300.5. For example, rigid metal conduit requires 6 inches minimum cover, PVC conduit requires 18 inches, and direct-buried UF cable requires 24 inches (residential circuits of 120V or less with GFCI can be 12 inches). All conductors of a circuit must be contained within the same raceway, cable, or trench (300.3(B)) to avoid inductive heating. problems: - id: wiring-p1 type: multiple_choice - question: "Per 300.4(A)(1), cables through wood framing must be set back at least how far from the edge of the framing member?" + question: Per 300.4(A)(1), cables through wood framing must be set back at least how far from the edge of the framing member? options: - - "3/4 inch" - - "1 inch" - - "1-1/4 inches" - - "1-1/2 inches" + - 3/4 inch + - 1 inch + - 1-1/4 inches + - 1-1/2 inches correct: 2 - explanation: "Per 300.4(A)(1), cables or raceways through bored holes in wood members must be set back at least 1-1/4 inches from the nearest edge of the wood member. If not, a steel plate at least 1/16 inch thick must be used for protection." + explanation: Per 300.4(A)(1), cables or raceways through bored holes in wood members must be set back at least 1-1/4 inches from the nearest edge of the wood member. If not, a steel plate at least 1/16 inch thick must be used for protection. - id: wiring-p2 type: multiple_choice - question: "Per Table 300.5, what is the minimum cover depth for direct-buried UF cable in a residential yard?" + question: Per Table 300.5, what is the minimum cover depth for direct-buried UF cable in a residential yard? options: - - "6 inches" - - "12 inches" - - "18 inches" - - "24 inches" + - 6 inches + - 12 inches + - 18 inches + - 24 inches correct: 3 - explanation: "Per Table 300.5, direct-buried cables (like UF-B) require a minimum cover of 24 inches. Residential 120V circuits with GFCI protection can be reduced to 12 inches." + explanation: Per Table 300.5, direct-buried cables (like UF-B) require a minimum cover of 24 inches. Residential 120V circuits with GFCI protection can be reduced to 12 inches. - id: wiring-p3 type: ordering - question: "Place these wiring methods in order from shallowest to deepest minimum burial depth per Table 300.5." + question: Place these wiring methods in order from shallowest to deepest minimum burial depth per Table 300.5. options: - - "PVC conduit" - - "Direct-buried UF cable" - - "Rigid metal conduit (RMC)" - correct: "2,0,1" - explanation: "Per Table 300.5: RMC = 6 inches, PVC conduit = 18 inches, direct-buried cable = 24 inches." + - PVC conduit + - Direct-buried UF cable + - Rigid metal conduit (RMC) + correct: 2,0,1 + explanation: 'Per Table 300.5: RMC = 6 inches, PVC conduit = 18 inches, direct-buried cable = 24 inches.' - id: wiring-p4 type: fill_blank - question: "Per 300.4(A)(1), cables through wood framing that cannot be set back 1-1/4 inches from the edge must be protected by a steel plate at least ___ inch thick." - correct: "1/16" - explanation: "Per 300.4(A)(1), a steel plate at least 1/16 inch (1.6 mm) thick must be used to protect cables or raceways where the edge of the bored hole is less than 1-1/4 inches from the framing member edge." - + question: Per 300.4(A)(1), cables through wood framing that cannot be set back 1-1/4 inches from the edge must be protected by a steel plate at least ___ inch thick. + correct: 1/16 + explanation: Per 300.4(A)(1), a steel plate at least 1/16 inch (1.6 mm) thick must be used to protect cables or raceways where the edge of the bored hole is less than 1-1/4 inches from the framing member edge. + keyPrerequisite: conductor-types - id: nm-cable - name: "Article 334 — NM (Romex) Cable" + name: Article 334 — NM (Romex) Cable difficulty: 3 estimatedMinutes: 20 - tags: [wiring-methods, nm-cable, article-334] - sourceRef: "NEC 2023 Article 334" + tags: + - wiring-methods + - nm-cable + - article-334 + sourceRef: NEC 2023 Article 334 prerequisites: - wiring-methods-overview knowledgePoints: - id: nm-uses - instruction: "NM (non-metallic sheathed cable, commonly Romex) cable is covered by Article 334. NM-B cable is permitted in one- and two-family dwellings and multifamily dwellings of Types III, IV, and V construction not exceeding 3 floors above grade (334.10). NM cable is NOT permitted in: commercial garages, theaters, motion picture studios, hazardous locations, embedded in plaster or running in hollows of masonry (where subject to dampness), or in any building exceeding 3 floors above grade. NM cable must be supported within 12 inches of every box or enclosure and at intervals not exceeding 4-1/2 feet (334.30). Per 334.80, the ampacity is based on the 60 degree C column of Table 310.16." + instruction: 'NM (non-metallic sheathed cable, commonly Romex) cable is covered by Article 334. NM-B cable is permitted in one- and two-family dwellings and multifamily dwellings of Types III, IV, and V construction not exceeding 3 floors above grade (334.10). NM cable is NOT permitted in: commercial garages, theaters, motion picture studios, hazardous locations, embedded in plaster or running in hollows of masonry (where subject to dampness), or in any building exceeding 3 floors above grade. NM cable must be supported within 12 inches of every box or enclosure and at intervals not exceeding 4-1/2 feet (334.30). Per 334.80, the ampacity is based on the 60 degree C column of Table 310.16.' problems: - id: nm-p1 type: multiple_choice - question: "How often must NM cable be supported, and how close to boxes?" + question: How often must NM cable be supported, and how close to boxes? options: - - "Every 3 feet, within 6 inches of boxes" - - "Every 4-1/2 feet, within 12 inches of boxes" - - "Every 6 feet, within 18 inches of boxes" - - "Every 8 feet, within 24 inches of boxes" + - Every 3 feet, within 6 inches of boxes + - Every 4-1/2 feet, within 12 inches of boxes + - Every 6 feet, within 18 inches of boxes + - Every 8 feet, within 24 inches of boxes correct: 1 - explanation: "Per 334.30, NM cable must be secured within 12 inches of every box, cabinet, or fitting and at intervals not exceeding 4-1/2 feet (1.4 m)." + explanation: Per 334.30, NM cable must be secured within 12 inches of every box, cabinet, or fitting and at intervals not exceeding 4-1/2 feet (1.4 m). - id: nm-p2 type: true_false - question: "NM cable is permitted in a 5-story multifamily apartment building of Type III construction." - correct: "false" - explanation: "Per 334.10(3), NM cable in multifamily dwellings is limited to Types III, IV, and V construction not exceeding 3 floors above grade. A 5-story building exceeds this limit." + question: NM cable is permitted in a 5-story multifamily apartment building of Type III construction. + correct: 'false' + explanation: Per 334.10(3), NM cable in multifamily dwellings is limited to Types III, IV, and V construction not exceeding 3 floors above grade. A 5-story building exceeds this limit. - id: nm-p3 type: true_false - question: "NM cable is permitted in commercial garages." - correct: "false" - explanation: "Per 334.12, NM cable is not permitted in commercial garages having hazardous locations as defined in 511.3." + question: NM cable is permitted in commercial garages. + correct: 'false' + explanation: Per 334.12, NM cable is not permitted in commercial garages having hazardous locations as defined in 511.3. - id: nm-p4 type: multiple_choice - question: "Through bored holes, NM cable must be at least how far from the nearest edge of a wood framing member?" + question: Through bored holes, NM cable must be at least how far from the nearest edge of a wood framing member? options: - - "3/4 inch" - - "1 inch" - - "1-1/4 inches" - - "1-1/2 inches" + - 3/4 inch + - 1 inch + - 1-1/4 inches + - 1-1/2 inches correct: 2 - explanation: "Per 300.4(A)(1), cables through bored holes in wood members must be 1-1/4 inches from the nearest edge. If closer, a 1/16-inch steel plate must protect the cable." - + explanation: Per 300.4(A)(1), cables through bored holes in wood members must be 1-1/4 inches from the nearest edge. If closer, a 1/16-inch steel plate must protect the cable. + keyPrerequisite: wiring-methods-overview - id: mc-cable - name: "Article 330 — Metal-Clad (MC) Cable" + name: Article 330 — Metal-Clad (MC) Cable difficulty: 3 estimatedMinutes: 15 - tags: [wiring-methods, mc-cable, article-330] - sourceRef: "NEC 2023 Article 330" + tags: + - wiring-methods + - mc-cable + - article-330 + sourceRef: NEC 2023 Article 330 prerequisites: - wiring-methods-overview knowledgePoints: - id: mc-uses - instruction: "MC (Metal-Clad) cable per Article 330 has an interlocking metal armor or a smooth metallic sheath. MC cable is much more versatile than NM cable -- it is permitted in nearly all locations including commercial, industrial, exposed and concealed, wet locations (when listed for wet locations), and in buildings of any height. MC cable must be supported within 12 inches of every box and at intervals not exceeding 6 feet (330.30(B) and (C)). The interlocking armor of standard MC cable is NOT recognized as an equipment grounding conductor -- an internal EGC conductor is required. However, Type MC cable with an interlocking metal armor listed as providing an adequate ground-fault current path may serve as an EGC (250.118(10))." + instruction: MC (Metal-Clad) cable per Article 330 has an interlocking metal armor or a smooth metallic sheath. MC cable is much more versatile than NM cable -- it is permitted in nearly all locations including commercial, industrial, exposed and concealed, wet locations (when listed for wet locations), and in buildings of any height. MC cable must be supported within 12 inches of every box and at intervals not exceeding 6 feet (330.30(B) and (C)). The interlocking armor of standard MC cable is NOT recognized as an equipment grounding conductor -- an internal EGC conductor is required. However, Type MC cable with an interlocking metal armor listed as providing an adequate ground-fault current path may serve as an EGC (250.118(10)). problems: - id: mc-p1 type: multiple_choice - question: "What is the maximum support interval for MC cable per 330.30?" + question: What is the maximum support interval for MC cable per 330.30? options: - - "4-1/2 feet" - - "5 feet" - - "6 feet" - - "8 feet" + - 4-1/2 feet + - 5 feet + - 6 feet + - 8 feet correct: 2 - explanation: "Per 330.30(B), MC cable must be secured at intervals not exceeding 6 feet (1.8 m) and within 12 inches of every box, cabinet, fitting, or other cable termination." + explanation: Per 330.30(B), MC cable must be secured at intervals not exceeding 6 feet (1.8 m) and within 12 inches of every box, cabinet, fitting, or other cable termination. - id: mc-p2 type: true_false - question: "MC cable is permitted in buildings of any height, unlike NM cable." - correct: "true" - explanation: "MC cable (Article 330) has no building height restriction, unlike NM cable which is limited to 3 floors above grade in multifamily dwellings. This makes MC cable the preferred choice in commercial and high-rise construction." + question: MC cable is permitted in buildings of any height, unlike NM cable. + correct: 'true' + explanation: MC cable (Article 330) has no building height restriction, unlike NM cable which is limited to 3 floors above grade in multifamily dwellings. This makes MC cable the preferred choice in commercial and high-rise construction. - id: mc-p3 type: fill_blank - question: "MC cable must be secured within ___ inches of every box, cabinet, or fitting per 330.30." - correct: "12" - explanation: "Per 330.30(C), MC cable must be secured within 12 inches of every box, cabinet, fitting, or other cable termination." + question: MC cable must be secured within ___ inches of every box, cabinet, or fitting per 330.30. + correct: '12' + explanation: Per 330.30(C), MC cable must be secured within 12 inches of every box, cabinet, fitting, or other cable termination. - id: mc-p4 type: true_false - question: "Standard interlocking armor MC cable is always recognized as an equipment grounding conductor without an internal EGC." - correct: "false" - explanation: "Standard interlocking armor MC cable is NOT recognized as an EGC. An internal EGC conductor is required. Only Type MC cable specifically listed as providing an adequate ground-fault current path per 250.118(10) may serve as an EGC." - + question: Standard interlocking armor MC cable is always recognized as an equipment grounding conductor without an internal EGC. + correct: 'false' + explanation: Standard interlocking armor MC cable is NOT recognized as an EGC. An internal EGC conductor is required. Only Type MC cable specifically listed as providing an adequate ground-fault current path per 250.118(10) may serve as an EGC. + keyPrerequisite: wiring-methods-overview - id: emt-conduit - name: "Article 358 — Electrical Metallic Tubing (EMT)" + name: Article 358 — Electrical Metallic Tubing (EMT) difficulty: 3 estimatedMinutes: 20 - tags: [wiring-methods, conduit, emt, article-358] - sourceRef: "NEC 2023 Article 358" + tags: + - wiring-methods + - conduit + - emt + - article-358 + sourceRef: NEC 2023 Article 358 prerequisites: - wiring-methods-overview knowledgePoints: - id: emt-uses - instruction: "EMT (Electrical Metallic Tubing) is a thin-walled, unthreaded steel or aluminum raceway. It uses compression or set-screw fittings (not threaded). EMT is permitted for both exposed and concealed work in most locations. EMT is NOT permitted where subject to severe physical damage (358.12(1)), in cinder concrete unless protected by at least 2 inches of cover (358.12(3)), or in hazardous locations unless specifically permitted. EMT must be supported within 3 feet of every box and at intervals per Table 358.30(A): every 10 feet for 1/2 to 1 inch, every 10 feet for 1-1/4 to 2 inch, every 10 feet for 2-1/2 to 4 inch. EMT is recognized as an equipment grounding conductor per 250.118(4)." + instruction: 'EMT (Electrical Metallic Tubing) is a thin-walled, unthreaded steel or aluminum raceway. It uses compression or set-screw fittings (not threaded). EMT is permitted for both exposed and concealed work in most locations. EMT is NOT permitted where subject to severe physical damage (358.12(1)), in cinder concrete unless protected by at least 2 inches of cover (358.12(3)), or in hazardous locations unless specifically permitted. EMT must be supported within 3 feet of every box and at intervals per Table 358.30(A): every 10 feet for 1/2 to 1 inch, every 10 feet for 1-1/4 to 2 inch, every 10 feet for 2-1/2 to 4 inch. EMT is recognized as an equipment grounding conductor per 250.118(4).' problems: - id: emt-p1 type: multiple_choice - question: "EMT is NOT permitted in which of the following locations?" + question: EMT is NOT permitted in which of the following locations? options: - - "Concealed in walls" - - "Exposed in a dry warehouse" - - "Where subject to severe physical damage" - - "Outdoors with rain-tight fittings" + - Concealed in walls + - Exposed in a dry warehouse + - Where subject to severe physical damage + - Outdoors with rain-tight fittings correct: 2 - explanation: "Per 358.12(1), EMT is not permitted where, during installation or after, it will be subject to severe physical damage. For such locations, rigid metal conduit (RMC) or intermediate metal conduit (IMC) would be used." + explanation: Per 358.12(1), EMT is not permitted where, during installation or after, it will be subject to severe physical damage. For such locations, rigid metal conduit (RMC) or intermediate metal conduit (IMC) would be used. - id: emt-p2 type: true_false - question: "EMT can serve as an equipment grounding conductor." - correct: "true" - explanation: "Per 250.118(4), electrical metallic tubing (EMT) is listed as an acceptable equipment grounding conductor." + question: EMT can serve as an equipment grounding conductor. + correct: 'true' + explanation: Per 250.118(4), electrical metallic tubing (EMT) is listed as an acceptable equipment grounding conductor. - id: emt-p3 type: fill_blank - question: "EMT must be supported within ___ feet of every box, cabinet, or conduit body per 358.30." - correct: "3" - explanation: "Per 358.30(A), EMT must be securely fastened within 3 feet of each outlet box, junction box, device box, cabinet, conduit body, or other conduit termination." + question: EMT must be supported within ___ feet of every box, cabinet, or conduit body per 358.30. + correct: '3' + explanation: Per 358.30(A), EMT must be securely fastened within 3 feet of each outlet box, junction box, device box, cabinet, conduit body, or other conduit termination. - id: emt-p4 type: true_false - question: "EMT uses threaded connections like rigid metal conduit." - correct: "false" - explanation: "EMT is thin-walled and unthreaded. It uses compression or set-screw fittings, not threaded connections. RMC and IMC use threaded connections." - + question: EMT uses threaded connections like rigid metal conduit. + correct: 'false' + explanation: EMT is thin-walled and unthreaded. It uses compression or set-screw fittings, not threaded connections. RMC and IMC use threaded connections. + keyPrerequisite: wiring-methods-overview - id: rigid-conduit - name: "Article 344 — Rigid Metal Conduit (RMC)" + name: Article 344 — Rigid Metal Conduit (RMC) difficulty: 3 estimatedMinutes: 15 - tags: [wiring-methods, conduit, rmc, article-344] - sourceRef: "NEC 2023 Article 344" + tags: + - wiring-methods + - conduit + - rmc + - article-344 + sourceRef: NEC 2023 Article 344 prerequisites: - emt-conduit knowledgePoints: - id: rmc-uses - instruction: "RMC (Rigid Metal Conduit) is the heaviest and most protective metallic raceway. It has threaded connections and provides excellent physical protection. RMC is permitted in all atmospheric conditions and occupancies (344.10). It is specifically required or recommended where severe physical damage is likely. RMC must be supported within 3 feet of each box and at intervals per Table 344.30(B)(2): trade sizes 1/2 to 3/4 every 10 feet, 1 inch every 12 feet, 1-1/4 to 1-1/2 every 14 feet, 2 to 2-1/2 every 16 feet, 3 and larger every 20 feet. RMC is recognized as an EGC per 250.118(2). It requires only 6 inches of burial depth per Table 300.5 -- the shallowest of any raceway." + instruction: 'RMC (Rigid Metal Conduit) is the heaviest and most protective metallic raceway. It has threaded connections and provides excellent physical protection. RMC is permitted in all atmospheric conditions and occupancies (344.10). It is specifically required or recommended where severe physical damage is likely. RMC must be supported within 3 feet of each box and at intervals per Table 344.30(B)(2): trade sizes 1/2 to 3/4 every 10 feet, 1 inch every 12 feet, 1-1/4 to 1-1/2 every 14 feet, 2 to 2-1/2 every 16 feet, 3 and larger every 20 feet. RMC is recognized as an EGC per 250.118(2). It requires only 6 inches of burial depth per Table 300.5 -- the shallowest of any raceway.' problems: - id: rmc-p1 type: multiple_choice - question: "What is the minimum burial depth for rigid metal conduit per Table 300.5?" + question: What is the minimum burial depth for rigid metal conduit per Table 300.5? options: - - "6 inches" - - "12 inches" - - "18 inches" - - "24 inches" + - 6 inches + - 12 inches + - 18 inches + - 24 inches correct: 0 - explanation: "Per Table 300.5, rigid metal conduit requires a minimum cover of only 6 inches (152 mm) when direct buried, which is the shallowest requirement of any raceway or cable type." + explanation: Per Table 300.5, rigid metal conduit requires a minimum cover of only 6 inches (152 mm) when direct buried, which is the shallowest requirement of any raceway or cable type. - id: rmc-p2 type: true_false - question: "RMC is permitted in all atmospheric conditions and occupancies." - correct: "true" - explanation: "Per 344.10, RMC is permitted in all atmospheric conditions and occupancies. Its threaded connections and heavy wall thickness make it suitable for the most demanding installations." + question: RMC is permitted in all atmospheric conditions and occupancies. + correct: 'true' + explanation: Per 344.10, RMC is permitted in all atmospheric conditions and occupancies. Its threaded connections and heavy wall thickness make it suitable for the most demanding installations. - id: rmc-p3 type: fill_blank - question: "Rigid metal conduit uses ___ connections, unlike EMT which uses compression or set-screw fittings." - correct: "threaded" - explanation: "RMC uses threaded connections which provide excellent bonding and physical protection. This is a key distinction from EMT." + question: Rigid metal conduit uses ___ connections, unlike EMT which uses compression or set-screw fittings. + correct: threaded + explanation: RMC uses threaded connections which provide excellent bonding and physical protection. This is a key distinction from EMT. - id: rmc-p4 type: matching - question: "Match each conduit type with its key characteristic." - options: - - "RMC|Threaded, heaviest protection, 6-inch burial depth" - - "EMT|Thin-walled, compression fittings, not for severe damage" - - "PVC|Non-metallic, requires separate EGC, 18-inch burial depth" - - "FMC|Flexible metal, helically wound, for vibrating equipment" - correct: "0,1,2,3" - explanation: "Each conduit type has distinct characteristics that determine where it can be used. RMC offers the most protection, EMT is common in commercial, PVC is non-conductive, and FMC provides flexibility." - + question: Match each conduit type with its key characteristic. + options: + - RMC|Threaded, heaviest protection, 6-inch burial depth + - EMT|Thin-walled, compression fittings, not for severe damage + - PVC|Non-metallic, requires separate EGC, 18-inch burial depth + - FMC|Flexible metal, helically wound, for vibrating equipment + correct: 0,1,2,3 + explanation: Each conduit type has distinct characteristics that determine where it can be used. RMC offers the most protection, EMT is common in commercial, PVC is non-conductive, and FMC provides flexibility. + keyPrerequisite: emt-conduit - id: pvc-conduit - name: "Article 352 — PVC Conduit" + name: Article 352 — PVC Conduit difficulty: 3 estimatedMinutes: 15 - tags: [wiring-methods, conduit, pvc, article-352] - sourceRef: "NEC 2023 Article 352" + tags: + - wiring-methods + - conduit + - pvc + - article-352 + sourceRef: NEC 2023 Article 352 prerequisites: - emt-conduit knowledgePoints: - id: pvc-uses - instruction: "PVC conduit (Schedule 40 and Schedule 80) is a non-metallic raceway. PVC is NOT permitted in hazardous locations (unless specifically permitted), for support of luminaires, where subject to physical damage (unless Schedule 80 or identified for the use), in areas of buildings with ambient temperatures exceeding 50 degrees C unless listed (352.12). PVC requires an equipment grounding conductor to be installed within the raceway since PVC itself is not conductive (250.118). PVC must be supported within 3 feet of every box and at intervals per Table 352.30(B): 1/2 to 1 inch every 3 feet, 1-1/4 to 2 inch every 5 feet, 2-1/2 to 3 inch every 5 feet, 3-1/2 to 5 inch every 6 feet, 6 inch every 8 feet. Expansion fittings may be required for temperature changes exceeding 14 degrees F (352.44)." + instruction: 'PVC conduit (Schedule 40 and Schedule 80) is a non-metallic raceway. PVC is NOT permitted in hazardous locations (unless specifically permitted), for support of luminaires, where subject to physical damage (unless Schedule 80 or identified for the use), in areas of buildings with ambient temperatures exceeding 50 degrees C unless listed (352.12). PVC requires an equipment grounding conductor to be installed within the raceway since PVC itself is not conductive (250.118). PVC must be supported within 3 feet of every box and at intervals per Table 352.30(B): 1/2 to 1 inch every 3 feet, 1-1/4 to 2 inch every 5 feet, 2-1/2 to 3 inch every 5 feet, 3-1/2 to 5 inch every 6 feet, 6 inch every 8 feet. Expansion fittings may be required for temperature changes exceeding 14 degrees F (352.44).' problems: - id: pvc-p1 type: multiple_choice - question: "PVC conduit requires what additional conductor that metallic raceways may not need?" + question: PVC conduit requires what additional conductor that metallic raceways may not need? options: - - "A bonding jumper at each fitting" - - "An equipment grounding conductor within the raceway" - - "A separate neutral conductor" - - "A ground-fault sensor wire" + - A bonding jumper at each fitting + - An equipment grounding conductor within the raceway + - A separate neutral conductor + - A ground-fault sensor wire correct: 1 - explanation: "Since PVC conduit is non-conductive, it cannot serve as an equipment grounding conductor. An EGC must be installed within the raceway per 250.118 and 352.60." + explanation: Since PVC conduit is non-conductive, it cannot serve as an equipment grounding conductor. An EGC must be installed within the raceway per 250.118 and 352.60. - id: pvc-p2 type: multiple_choice - question: "What is the maximum support interval for 1-inch PVC conduit per Table 352.30(B)?" + question: What is the maximum support interval for 1-inch PVC conduit per Table 352.30(B)? options: - - "3 feet" - - "4 feet" - - "5 feet" - - "6 feet" + - 3 feet + - 4 feet + - 5 feet + - 6 feet correct: 0 - explanation: "Per Table 352.30(B), PVC conduit in trade sizes 1/2 through 1 inch must be supported at intervals not exceeding 3 feet." + explanation: Per Table 352.30(B), PVC conduit in trade sizes 1/2 through 1 inch must be supported at intervals not exceeding 3 feet. - id: pvc-p3 type: true_false - question: "PVC conduit is permitted in hazardous locations without restriction." - correct: "false" - explanation: "Per 352.12, PVC conduit is NOT permitted in hazardous locations unless specifically permitted by the relevant article (e.g., 501.10 for Class I locations)." + question: PVC conduit is permitted in hazardous locations without restriction. + correct: 'false' + explanation: Per 352.12, PVC conduit is NOT permitted in hazardous locations unless specifically permitted by the relevant article (e.g., 501.10 for Class I locations). - id: pvc-p4 type: fill_blank - question: "PVC expansion fittings may be required when temperature changes exceed ___ degrees F per 352.44." - correct: "14" - explanation: "Per 352.44, expansion fittings for PVC conduit must be provided where expected temperature change exceeds 14 degrees F (7.8 degrees C) to compensate for thermal expansion." - + question: PVC expansion fittings may be required when temperature changes exceed ___ degrees F per 352.44. + correct: '14' + explanation: Per 352.44, expansion fittings for PVC conduit must be provided where expected temperature change exceeds 14 degrees F (7.8 degrees C) to compensate for thermal expansion. + keyPrerequisite: emt-conduit - id: conduit-fill - name: "Conduit Fill Calculations" + name: Conduit Fill Calculations difficulty: 6 estimatedMinutes: 30 - tags: [conduit, fill-calculations, chapter-9] - sourceRef: "NEC 2023 Chapter 9, Tables 1, 4, 5" + tags: + - conduit + - fill-calculations + - chapter-9 + sourceRef: NEC 2023 Chapter 9, Tables 1, 4, 5 prerequisites: - emt-conduit - conductor-sizing knowledgePoints: - id: fill-percentages - instruction: "Chapter 9, Table 1 sets the maximum percentage of conduit cross-sectional area that can be filled with conductors: 1 conductor = 53%, 2 conductors = 31%, 3 or more conductors = 40%. These apply to all raceway types. To calculate conduit fill: (1) Look up the cross-sectional area of each conductor in Chapter 9, Table 5 (for individual conductors) or Table 5A (for compact conductors). (2) Sum the areas of all conductors. (3) Look up the allowable fill area for the conduit size in Chapter 9, Table 4 for the specific raceway type. (4) Select the smallest conduit whose allowable fill area (at the correct percentage) meets or exceeds the total conductor area." - workedExample: "Example: What size EMT is needed for three 12 AWG THHN and one 12 AWG THHN (ground)? Step 1: From Table 5, 12 AWG THHN area = 0.0133 sq in. Step 2: Total area = 4 x 0.0133 = 0.0532 sq in. Step 3: With 4 conductors, use 40% fill. Step 4: From Table 4 for EMT, 1/2 inch EMT has 40% fill area of 0.122 sq in. Step 5: 0.122 >= 0.0532, so 1/2 inch EMT is adequate." + instruction: 'Chapter 9, Table 1 sets the maximum percentage of conduit cross-sectional area that can be filled with conductors: 1 conductor = 53%, 2 conductors = 31%, 3 or more conductors = 40%. These apply to all raceway types. To calculate conduit fill: (1) Look up the cross-sectional area of each conductor in Chapter 9, Table 5 (for individual conductors) or Table 5A (for compact conductors). (2) Sum the areas of all conductors. (3) Look up the allowable fill area for the conduit size in Chapter 9, Table 4 for the specific raceway type. (4) Select the smallest conduit whose allowable fill area (at the correct percentage) meets or exceeds the total conductor area.' + workedExample: 'Example: What size EMT is needed for three 12 AWG THHN and one 12 AWG THHN (ground)? Step 1: From Table 5, 12 AWG THHN area = 0.0133 sq in. Step 2: Total area = 4 x 0.0133 = 0.0532 sq in. Step 3: With 4 conductors, use 40% fill. Step 4: From Table 4 for EMT, 1/2 inch EMT has 40% fill area of 0.122 sq in. Step 5: 0.122 >= 0.0532, so 1/2 inch EMT is adequate.' problems: - id: fill-p1 type: multiple_choice - question: "Per Chapter 9, Table 1, what is the maximum fill percentage for a conduit containing 3 or more conductors?" + question: Per Chapter 9, Table 1, what is the maximum fill percentage for a conduit containing 3 or more conductors? options: - - "25%" - - "31%" - - "40%" - - "53%" + - 25% + - 31% + - 40% + - 53% correct: 2 - explanation: "Per Chapter 9, Table 1, when a raceway contains 3 or more conductors (over 2), the maximum fill is 40% of the conduit cross-sectional area." + explanation: Per Chapter 9, Table 1, when a raceway contains 3 or more conductors (over 2), the maximum fill is 40% of the conduit cross-sectional area. - id: fill-p2 type: multiple_choice - question: "When only 1 conductor is installed in a conduit, what is the maximum fill percentage?" + question: When only 1 conductor is installed in a conduit, what is the maximum fill percentage? options: - - "31%" - - "40%" - - "53%" - - "60%" + - 31% + - 40% + - 53% + - 60% correct: 2 - explanation: "Per Chapter 9, Table 1, when only 1 conductor is installed in a raceway, the maximum fill is 53% of the conduit cross-sectional area." + explanation: Per Chapter 9, Table 1, when only 1 conductor is installed in a raceway, the maximum fill is 53% of the conduit cross-sectional area. - id: fill-p3 type: multiple_choice - question: "When exactly 2 conductors are installed in a conduit, the maximum fill percentage is:" + question: 'When exactly 2 conductors are installed in a conduit, the maximum fill percentage is:' options: - - "25%" - - "31%" - - "40%" - - "53%" + - 25% + - 31% + - 40% + - 53% correct: 1 - explanation: "Per Chapter 9, Table 1, when exactly 2 conductors are installed in a raceway, the maximum fill is 31% of the conduit cross-sectional area." + explanation: Per Chapter 9, Table 1, when exactly 2 conductors are installed in a raceway, the maximum fill is 31% of the conduit cross-sectional area. - id: fill-p4 type: multiple_choice - question: "Conductor cross-sectional areas for conduit fill calculations are found in:" + question: 'Conductor cross-sectional areas for conduit fill calculations are found in:' options: - - "Table 310.16" - - "Table 250.122" - - "Chapter 9, Table 5" - - "Table 220.42" + - Table 310.16 + - Table 250.122 + - Chapter 9, Table 5 + - Table 220.42 correct: 2 - explanation: "Chapter 9, Table 5 provides the dimensions and cross-sectional areas for individual insulated conductors used in conduit fill calculations." - + explanation: Chapter 9, Table 5 provides the dimensions and cross-sectional areas for individual insulated conductors used in conduit fill calculations. + keyPrerequisite: emt-conduit - id: box-fill-calculations - name: "Article 314 — Box Fill Calculations" + name: Article 314 — Box Fill Calculations difficulty: 6 estimatedMinutes: 25 - tags: [boxes, fill-calculations, article-314] - sourceRef: "NEC 2023 Article 314, Table 314.16(B)" + tags: + - boxes + - fill-calculations + - article-314 + sourceRef: NEC 2023 Article 314, Table 314.16(B) prerequisites: - wiring-methods-overview - conductor-sizing knowledgePoints: - id: box-fill-rules - instruction: "Section 314.16 requires that boxes be sized to provide adequate space. Each conductor that enters the box counts as a volume allowance based on conductor size per Table 314.16(B): 14 AWG = 2.0 cu in, 12 AWG = 2.25 cu in, 10 AWG = 2.5 cu in, 8 AWG = 3.0 cu in, 6 AWG = 5.0 cu in. Additional fill allowances: each clamp counts as one conductor (the largest conductor entering the box), each support fitting (like a fixture stud) counts as one conductor, each device (switch/receptacle) counts as two conductors based on the largest conductor connected to it, all EGCs together count as one conductor (the largest EGC entering the box), and each isolated equipment grounding conductor counts as one additional conductor." - workedExample: "Example: A box has 4 x 12 AWG current-carrying conductors, 2 x 12 AWG EGCs, one cable clamp, and one duplex receptacle. Count: 4 conductors = 4 x 2.25. EGCs (all count as 1) = 1 x 2.25. Clamp (count as 1 largest) = 1 x 2.25. Receptacle (counts as 2) = 2 x 2.25. Total = 8 x 2.25 = 18.0 cu in. A 4x2-1/8 deep device box has 14.5 cu in -- too small. A 4-11/16 square box with 1-1/2 depth has 25.5 cu in -- sufficient." + instruction: 'Section 314.16 requires that boxes be sized to provide adequate space. Each conductor that enters the box counts as a volume allowance based on conductor size per Table 314.16(B): 14 AWG = 2.0 cu in, 12 AWG = 2.25 cu in, 10 AWG = 2.5 cu in, 8 AWG = 3.0 cu in, 6 AWG = 5.0 cu in. Additional fill allowances: each clamp counts as one conductor (the largest conductor entering the box), each support fitting (like a fixture stud) counts as one conductor, each device (switch/receptacle) counts as two conductors based on the largest conductor connected to it, all EGCs together count as one conductor (the largest EGC entering the box), and each isolated equipment grounding conductor counts as one additional conductor.' + workedExample: 'Example: A box has 4 x 12 AWG current-carrying conductors, 2 x 12 AWG EGCs, one cable clamp, and one duplex receptacle. Count: 4 conductors = 4 x 2.25. EGCs (all count as 1) = 1 x 2.25. Clamp (count as 1 largest) = 1 x 2.25. Receptacle (counts as 2) = 2 x 2.25. Total = 8 x 2.25 = 18.0 cu in. A 4x2-1/8 deep device box has 14.5 cu in -- too small. A 4-11/16 square box with 1-1/2 depth has 25.5 cu in -- sufficient.' problems: - id: box-p1 type: multiple_choice - question: "Per Table 314.16(B), what is the volume allowance for a 12 AWG conductor?" + question: Per Table 314.16(B), what is the volume allowance for a 12 AWG conductor? options: - - "2.0 cubic inches" - - "2.25 cubic inches" - - "2.5 cubic inches" - - "3.0 cubic inches" + - 2.0 cubic inches + - 2.25 cubic inches + - 2.5 cubic inches + - 3.0 cubic inches correct: 1 - explanation: "Per Table 314.16(B), each 12 AWG conductor requires a volume allowance of 2.25 cubic inches." + explanation: Per Table 314.16(B), each 12 AWG conductor requires a volume allowance of 2.25 cubic inches. - id: box-p2 type: multiple_choice - question: "When counting box fill, a single duplex receptacle counts as how many conductors?" + question: When counting box fill, a single duplex receptacle counts as how many conductors? options: - - "One" - - "Two" - - "Three" - - "Four" + - One + - Two + - Three + - Four correct: 1 - explanation: "Per 314.16(B)(4), for each yoke or strap containing one or more devices, a double volume allowance (counts as 2 conductors) shall be made based on the largest conductor connected to the device." + explanation: Per 314.16(B)(4), for each yoke or strap containing one or more devices, a double volume allowance (counts as 2 conductors) shall be made based on the largest conductor connected to the device. - id: box-p3 type: multiple_choice - question: "When counting box fill, all equipment grounding conductors together count as:" + question: 'When counting box fill, all equipment grounding conductors together count as:' options: - - "Zero conductors" - - "One conductor (largest EGC size)" - - "Two conductors" - - "One conductor per EGC" + - Zero conductors + - One conductor (largest EGC size) + - Two conductors + - One conductor per EGC correct: 1 - explanation: "Per 314.16(B)(5), a single volume allowance based on the largest equipment grounding conductor entering the box shall be made for all EGCs combined." + explanation: Per 314.16(B)(5), a single volume allowance based on the largest equipment grounding conductor entering the box shall be made for all EGCs combined. - id: box-p4 type: multiple_choice - question: "Per Table 314.16(B), what is the volume allowance for an 8 AWG conductor?" + question: Per Table 314.16(B), what is the volume allowance for an 8 AWG conductor? options: - - "2.25 cubic inches" - - "2.5 cubic inches" - - "3.0 cubic inches" - - "3.5 cubic inches" + - 2.25 cubic inches + - 2.5 cubic inches + - 3.0 cubic inches + - 3.5 cubic inches correct: 2 - explanation: "Per Table 314.16(B), each 8 AWG conductor requires a volume allowance of 3.0 cubic inches." + explanation: Per Table 314.16(B), each 8 AWG conductor requires a volume allowance of 3.0 cubic inches. - id: box-p5 type: multiple_choice - question: "Cable clamps in a box count as how many conductors for box fill calculation?" + question: Cable clamps in a box count as how many conductors for box fill calculation? options: - - "Zero" - - "One conductor total (not per clamp)" - - "One conductor per clamp" - - "Two conductors total" + - Zero + - One conductor total (not per clamp) + - One conductor per clamp + - Two conductors total correct: 1 - explanation: "Per 314.16(B)(2), one or more internal cable clamps count as a single volume allowance based on the largest conductor in the box. It is one total, not one per clamp." - - # ============================================================ - # RECEPTACLES, GFCI, AFCI - # ============================================================ - + explanation: Per 314.16(B)(2), one or more internal cable clamps count as a single volume allowance based on the largest conductor in the box. It is one total, not one per clamp. + keyPrerequisite: conductor-types - id: receptacle-outlets - name: "Article 210.52 + 406 — Receptacle Requirements" + name: Article 210.52 + 406 — Receptacle Requirements difficulty: 4 estimatedMinutes: 25 - tags: [receptacles, dwelling, article-210] - sourceRef: "NEC 2023 Sections 210.52, Article 406" + tags: + - receptacles + - dwelling + - article-210 + sourceRef: NEC 2023 Sections 210.52, Article 406 prerequisites: - branch-circuits knowledgePoints: - id: dwelling-receptacles - instruction: "Section 210.52 specifies receptacle outlet requirements for dwellings. The 6/12 rule (210.52(A)): in every habitable room, receptacle outlets must be placed so that no point along the floor line in any wall space is more than 6 feet from a receptacle. This means receptacles must be no more than 12 feet apart. Wall space is defined as any space 2 feet or more in width. Kitchen countertop receptacles (210.52(C)): receptacles must be installed at each counter space 12 inches or wider, and no point along the counter line can be more than 24 inches (2 feet) from a receptacle. At least two 20A small-appliance circuits must serve the kitchen and dining area (210.52(B)). Bathroom receptacles require at least one 20A circuit, and it can only serve bathroom receptacles (210.11(C)(3))." - workedExample: "Example: A kitchen has a continuous countertop that is 8 feet long. How many receptacles are needed? Per 210.52(C)(1), no point along the wall line behind the counter can be more than 24 inches from a receptacle. Starting from one end: first receptacle within 24 inches of the end, then every 48 inches (4 feet) maximum. For 8 feet: you need at least 3 receptacles (at ~2 feet, ~4 feet, and ~6 feet from the end)." + instruction: 'Section 210.52 specifies receptacle outlet requirements for dwellings. The 6/12 rule (210.52(A)): in every habitable room, receptacle outlets must be placed so that no point along the floor line in any wall space is more than 6 feet from a receptacle. This means receptacles must be no more than 12 feet apart. Wall space is defined as any space 2 feet or more in width. Kitchen countertop receptacles (210.52(C)): receptacles must be installed at each counter space 12 inches or wider, and no point along the counter line can be more than 24 inches (2 feet) from a receptacle. At least two 20A small-appliance circuits must serve the kitchen and dining area (210.52(B)). Bathroom receptacles require at least one 20A circuit, and it can only serve bathroom receptacles (210.11(C)(3)).' + workedExample: 'Example: A kitchen has a continuous countertop that is 8 feet long. How many receptacles are needed? Per 210.52(C)(1), no point along the wall line behind the counter can be more than 24 inches from a receptacle. Starting from one end: first receptacle within 24 inches of the end, then every 48 inches (4 feet) maximum. For 8 feet: you need at least 3 receptacles (at ~2 feet, ~4 feet, and ~6 feet from the end).' problems: - id: recep-p1 type: multiple_choice - question: "Per the 6/12 rule (210.52(A)), what is the maximum distance between receptacles along a wall in a habitable room?" + question: Per the 6/12 rule (210.52(A)), what is the maximum distance between receptacles along a wall in a habitable room? options: - - "6 feet" - - "8 feet" - - "10 feet" - - "12 feet" + - 6 feet + - 8 feet + - 10 feet + - 12 feet correct: 3 - explanation: "Per 210.52(A), no point along the floor line of any wall space can be more than 6 feet from a receptacle outlet. This means receptacles must be spaced no more than 12 feet apart." + explanation: Per 210.52(A), no point along the floor line of any wall space can be more than 6 feet from a receptacle outlet. This means receptacles must be spaced no more than 12 feet apart. - id: recep-p2 type: multiple_choice - question: "How many 20-ampere small-appliance branch circuits are required to serve the kitchen and dining area?" + question: How many 20-ampere small-appliance branch circuits are required to serve the kitchen and dining area? options: - - "One" - - "Two" - - "Three" - - "Four" + - One + - Two + - Three + - Four correct: 1 - explanation: "Per 210.52(B)(1), at least two 20-ampere small-appliance branch circuits are required to serve all wall and floor receptacle outlets in the kitchen, pantry, breakfast room, and dining room." + explanation: Per 210.52(B)(1), at least two 20-ampere small-appliance branch circuits are required to serve all wall and floor receptacle outlets in the kitchen, pantry, breakfast room, and dining room. - id: recep-p3 type: multiple_choice - question: "Per 210.52(C)(1), kitchen countertop receptacles must be placed so that no point along the wall line is more than what distance from a receptacle?" + question: Per 210.52(C)(1), kitchen countertop receptacles must be placed so that no point along the wall line is more than what distance from a receptacle? options: - - "12 inches" - - "24 inches" - - "36 inches" - - "48 inches" + - 12 inches + - 24 inches + - 36 inches + - 48 inches correct: 1 - explanation: "Per 210.52(C)(1), countertop receptacles must be placed so that no point along the wall line behind the counter is more than 24 inches (2 feet) from a receptacle outlet." + explanation: Per 210.52(C)(1), countertop receptacles must be placed so that no point along the wall line behind the counter is more than 24 inches (2 feet) from a receptacle outlet. - id: recep-p4 type: multiple_choice - question: "Per 210.11(C)(3), the bathroom receptacle circuit must be rated at least:" + question: 'Per 210.11(C)(3), the bathroom receptacle circuit must be rated at least:' options: - - "15 amperes" - - "20 amperes" - - "25 amperes" - - "30 amperes" + - 15 amperes + - 20 amperes + - 25 amperes + - 30 amperes correct: 1 - explanation: "Per 210.11(C)(3), at least one 20-ampere branch circuit must be provided to supply the bathroom receptacle outlet(s). This circuit can supply receptacles in one or more bathrooms." + explanation: Per 210.11(C)(3), at least one 20-ampere branch circuit must be provided to supply the bathroom receptacle outlet(s). This circuit can supply receptacles in one or more bathrooms. - id: recep-p5 type: true_false - question: "Per the 6/12 rule, a 2-foot wide wall section requires a receptacle." - correct: "true" - explanation: "Per 210.52(A)(2)(1), a wall space is defined as any space 2 feet or more in width (including space measured around corners). Therefore, a 2-foot wall section qualifies as a wall space and must be included in the 6/12 rule." - + question: Per the 6/12 rule, a 2-foot wide wall section requires a receptacle. + correct: 'true' + explanation: Per 210.52(A)(2)(1), a wall space is defined as any space 2 feet or more in width (including space measured around corners). Therefore, a 2-foot wall section qualifies as a wall space and must be included in the 6/12 rule. + keyPrerequisite: branch-circuits - id: gfci-protection - name: "Article 210.8 — GFCI Protection Requirements" + name: Article 210.8 — GFCI Protection Requirements difficulty: 4 estimatedMinutes: 25 - tags: [gfci, protection, article-210] - sourceRef: "NEC 2023 Section 210.8" + tags: + - gfci + - protection + - article-210 + sourceRef: NEC 2023 Section 210.8 prerequisites: - receptacle-outlets knowledgePoints: - id: gfci-locations-dwelling - instruction: "Section 210.8(A) lists locations requiring GFCI protection in dwelling units (125V, 15 and 20A). These include: bathrooms, garages and accessory buildings at or below grade, outdoors, crawl spaces at or below grade, basements (finished and unfinished), kitchen (all receptacles serving countertop surfaces and within 6 feet of the outside edge of a sink), sinks (within 6 feet of the outside edge), boathouses, bathtubs/shower stalls (within 6 feet), laundry areas, indoor damp/wet locations, and attics (2023 NEC addition). The 2023 NEC significantly expanded GFCI requirements to include all 250V outlets in many of these locations, not just 125V." - workedExample: "Example: Does a receptacle in an attached garage need GFCI protection? Yes. Per 210.8(A)(2), GFCI protection is required for all 125-volt, 15- and 20-ampere receptacles in garages and accessory buildings at or below grade. This includes dedicated circuits for garage door openers and refrigerators." + instruction: 'Section 210.8(A) lists locations requiring GFCI protection in dwelling units (125V, 15 and 20A). These include: bathrooms, garages and accessory buildings at or below grade, outdoors, crawl spaces at or below grade, basements (finished and unfinished), kitchen (all receptacles serving countertop surfaces and within 6 feet of the outside edge of a sink), sinks (within 6 feet of the outside edge), boathouses, bathtubs/shower stalls (within 6 feet), laundry areas, indoor damp/wet locations, and attics (2023 NEC addition). The 2023 NEC significantly expanded GFCI requirements to include all 250V outlets in many of these locations, not just 125V.' + workedExample: 'Example: Does a receptacle in an attached garage need GFCI protection? Yes. Per 210.8(A)(2), GFCI protection is required for all 125-volt, 15- and 20-ampere receptacles in garages and accessory buildings at or below grade. This includes dedicated circuits for garage door openers and refrigerators.' problems: - id: gfci-p1 type: multiple_choice - question: "Per 210.8(A), which of the following dwelling locations does NOT require GFCI protection for 125V, 15/20A receptacles?" + question: Per 210.8(A), which of the following dwelling locations does NOT require GFCI protection for 125V, 15/20A receptacles? options: - - "Bathrooms" - - "Bedrooms" - - "Garages" - - "Unfinished basements" + - Bathrooms + - Bedrooms + - Garages + - Unfinished basements correct: 1 - explanation: "Bedrooms are not listed in 210.8(A) as requiring GFCI protection. However, bedrooms do require AFCI protection per 210.12." + explanation: Bedrooms are not listed in 210.8(A) as requiring GFCI protection. However, bedrooms do require AFCI protection per 210.12. - id: gfci-p2 type: true_false - question: "GFCI protection is required for all kitchen countertop receptacles in dwelling units." - correct: "true" - explanation: "Per 210.8(A)(6), GFCI protection is required for receptacles that serve countertop surfaces in kitchens of dwelling units." + question: GFCI protection is required for all kitchen countertop receptacles in dwelling units. + correct: 'true' + explanation: Per 210.8(A)(6), GFCI protection is required for receptacles that serve countertop surfaces in kitchens of dwelling units. - id: gfci-p3 type: multiple_choice - question: "Per 210.8(A), GFCI protection is required for receptacles within what distance of the outside edge of a sink?" + question: Per 210.8(A), GFCI protection is required for receptacles within what distance of the outside edge of a sink? options: - - "3 feet" - - "4 feet" - - "6 feet" - - "10 feet" + - 3 feet + - 4 feet + - 6 feet + - 10 feet correct: 2 - explanation: "Per 210.8(A)(7), GFCI protection is required for 125V, 15- and 20-ampere receptacles within 6 feet of the outside edge of a sink in dwelling units." + explanation: Per 210.8(A)(7), GFCI protection is required for 125V, 15- and 20-ampere receptacles within 6 feet of the outside edge of a sink in dwelling units. - id: gfci-p4 type: true_false - question: "GFCI protection is required for all receptacles in an unfinished basement of a dwelling unit." - correct: "true" - explanation: "Per 210.8(A)(5), GFCI protection is required for all 125V, 15- and 20-ampere receptacles in unfinished basements. This includes dedicated circuits for sump pumps and freezers." - + question: GFCI protection is required for all receptacles in an unfinished basement of a dwelling unit. + correct: 'true' + explanation: Per 210.8(A)(5), GFCI protection is required for all 125V, 15- and 20-ampere receptacles in unfinished basements. This includes dedicated circuits for sump pumps and freezers. + keyPrerequisite: receptacle-outlets - id: afci-protection - name: "Article 210.12 — AFCI Protection Requirements" + name: Article 210.12 — AFCI Protection Requirements difficulty: 4 estimatedMinutes: 20 - tags: [afci, protection, article-210] - sourceRef: "NEC 2023 Section 210.12" + tags: + - afci + - protection + - article-210 + sourceRef: NEC 2023 Section 210.12 prerequisites: - gfci-protection knowledgePoints: - id: afci-locations - instruction: "Section 210.12(A) requires AFCI protection for all 120-volt, 15- and 20-ampere branch circuits supplying outlets and devices in dwelling unit rooms including: kitchens, family rooms, dining rooms, living rooms, parlors, libraries, dens, bedrooms, sunrooms, recreation rooms, closets, hallways, laundry areas, and similar rooms and areas. The 2023 NEC expanded AFCI requirements to include kitchens and laundry areas. AFCI breakers detect arcing faults (both series and parallel arcs) that can cause fires. AFCI protection can be provided by: an AFCI circuit breaker, an outlet branch-circuit AFCI (installed at the first outlet), or a combination of both." + instruction: 'Section 210.12(A) requires AFCI protection for all 120-volt, 15- and 20-ampere branch circuits supplying outlets and devices in dwelling unit rooms including: kitchens, family rooms, dining rooms, living rooms, parlors, libraries, dens, bedrooms, sunrooms, recreation rooms, closets, hallways, laundry areas, and similar rooms and areas. The 2023 NEC expanded AFCI requirements to include kitchens and laundry areas. AFCI breakers detect arcing faults (both series and parallel arcs) that can cause fires. AFCI protection can be provided by: an AFCI circuit breaker, an outlet branch-circuit AFCI (installed at the first outlet), or a combination of both.' problems: - id: afci-p1 type: multiple_choice - question: "Per 210.12(A), which of the following dwelling unit areas requires AFCI protection?" + question: Per 210.12(A), which of the following dwelling unit areas requires AFCI protection? options: - - "Garage" - - "Bathroom" - - "Bedroom" - - "Outdoor patio" + - Garage + - Bathroom + - Bedroom + - Outdoor patio correct: 2 - explanation: "Per 210.12(A), bedrooms are specifically listed as requiring AFCI protection for 120V, 15- and 20-ampere branch circuits. Garages, bathrooms, and outdoor areas are not listed in 210.12." + explanation: Per 210.12(A), bedrooms are specifically listed as requiring AFCI protection for 120V, 15- and 20-ampere branch circuits. Garages, bathrooms, and outdoor areas are not listed in 210.12. - id: afci-p2 type: true_false - question: "The 2023 NEC requires AFCI protection for kitchen branch circuits in dwelling units." - correct: "true" - explanation: "The 2023 NEC expanded 210.12(A) to include kitchens and laundry areas, which were not previously required to have AFCI protection." + question: The 2023 NEC requires AFCI protection for kitchen branch circuits in dwelling units. + correct: 'true' + explanation: The 2023 NEC expanded 210.12(A) to include kitchens and laundry areas, which were not previously required to have AFCI protection. - id: afci-p3 type: fill_blank - question: "AFCI protection is required for all ___-volt, 15- and 20-ampere branch circuits supplying outlets in dwelling unit habitable rooms." - correct: "120" - explanation: "Per 210.12(A), AFCI protection applies to 120-volt, 15- and 20-ampere branch circuits in dwelling unit rooms. 240V circuits are not covered by this requirement." + question: AFCI protection is required for all ___-volt, 15- and 20-ampere branch circuits supplying outlets in dwelling unit habitable rooms. + correct: '120' + explanation: Per 210.12(A), AFCI protection applies to 120-volt, 15- and 20-ampere branch circuits in dwelling unit rooms. 240V circuits are not covered by this requirement. - id: afci-p4 type: matching - question: "Match each dwelling area with the type of protection required." - options: - - "Bedroom|AFCI required" - - "Bathroom|GFCI required" - - "Garage|GFCI required" - - "Kitchen|Both AFCI and GFCI required" - correct: "0,1,2,3" - explanation: "Bedrooms need AFCI (210.12), bathrooms and garages need GFCI (210.8(A)), and kitchens need both AFCI (210.12) and GFCI for countertop receptacles (210.8(A)(6))." - - # ============================================================ - # LOAD CALCULATIONS & SERVICE - # ============================================================ - + question: Match each dwelling area with the type of protection required. + options: + - Bedroom|AFCI required + - Bathroom|GFCI required + - Garage|GFCI required + - Kitchen|Both AFCI and GFCI required + correct: 0,1,2,3 + explanation: Bedrooms need AFCI (210.12), bathrooms and garages need GFCI (210.8(A)), and kitchens need both AFCI (210.12) and GFCI for countertop receptacles (210.8(A)(6)). + keyPrerequisite: gfci-protection - id: dwelling-load-calculations - name: "Article 220 — Dwelling Unit Load Calculations" + name: Article 220 — Dwelling Unit Load Calculations difficulty: 7 estimatedMinutes: 35 - tags: [load-calculations, dwelling, article-220] - sourceRef: "NEC 2023 Article 220, Parts I-III" + tags: + - load-calculations + - dwelling + - article-220 + sourceRef: NEC 2023 Article 220, Parts I-III prerequisites: - branch-circuits - feeders knowledgePoints: - id: general-lighting - instruction: "Table 220.12 provides unit loads for general lighting by occupancy type. For dwellings, the unit load is 3 VA per square foot. This calculation: (floor area in sq ft) x 3 VA/sq ft = general lighting VA. Small-appliance circuits: per 220.52(A), each 20A small-appliance circuit is 1,500 VA (minimum 2 circuits = 3,000 VA). Laundry circuit: per 220.52(B), one 1,500 VA circuit. Total these and apply Table 220.42 demand factors: first 3,000 VA at 100%, remainder at 35%. Then add: electric range per Table 220.55 (maximum demand for one range up to 12kW rating is 8 kW), dryer at 5,000 VA or nameplate rating whichever is larger (220.54), AC and heating at the larger of the two (220.60), other fixed appliances at 75% if 4 or more (220.53)." - workedExample: "Example: 1,800 sq ft dwelling, electric range (12 kW), dryer (5 kW), AC (5 kW), heat (10 kW), water heater (4.5 kW). General lighting: 1800 x 3 = 5,400 VA. Small appliance: 3,000 VA. Laundry: 1,500 VA. Total general = 9,900 VA. Demand: first 3,000 at 100% = 3,000. Remaining 6,900 at 35% = 2,415. Subtotal = 5,415 VA. Range: 8,000 VA (Table 220.55). Dryer: 5,000 VA. Water heater: 4,500 VA. AC vs Heat: use larger = 10,000 VA. Total = 5,415 + 8,000 + 5,000 + 4,500 + 10,000 = 32,915 VA. Service amps at 240V: 32,915 / 240 = 137A. Minimum 150A service." + instruction: 'Table 220.12 provides unit loads for general lighting by occupancy type. For dwellings, the unit load is 3 VA per square foot. This calculation: (floor area in sq ft) x 3 VA/sq ft = general lighting VA. Small-appliance circuits: per 220.52(A), each 20A small-appliance circuit is 1,500 VA (minimum 2 circuits = 3,000 VA). Laundry circuit: per 220.52(B), one 1,500 VA circuit. Total these and apply Table 220.42 demand factors: first 3,000 VA at 100%, remainder at 35%. Then add: electric range per Table 220.55 (maximum demand for one range up to 12kW rating is 8 kW), dryer at 5,000 VA or nameplate rating whichever is larger (220.54), AC and heating at the larger of the two (220.60), other fixed appliances at 75% if 4 or more (220.53).' + workedExample: 'Example: 1,800 sq ft dwelling, electric range (12 kW), dryer (5 kW), AC (5 kW), heat (10 kW), water heater (4.5 kW). General lighting: 1800 x 3 = 5,400 VA. Small appliance: 3,000 VA. Laundry: 1,500 VA. Total general = 9,900 VA. Demand: first 3,000 at 100% = 3,000. Remaining 6,900 at 35% = 2,415. Subtotal = 5,415 VA. Range: 8,000 VA (Table 220.55). Dryer: 5,000 VA. Water heater: 4,500 VA. AC vs Heat: use larger = 10,000 VA. Total = 5,415 + 8,000 + 5,000 + 4,500 + 10,000 = 32,915 VA. Service amps at 240V: 32,915 / 240 = 137A. Minimum 150A service.' problems: - id: load-p1 type: multiple_choice - question: "Per Table 220.12, what is the unit load for general lighting in a dwelling unit?" + question: Per Table 220.12, what is the unit load for general lighting in a dwelling unit? options: - - "1 VA per square foot" - - "2 VA per square foot" - - "3 VA per square foot" - - "5 VA per square foot" + - 1 VA per square foot + - 2 VA per square foot + - 3 VA per square foot + - 5 VA per square foot correct: 2 - explanation: "Per Table 220.12, the unit load for general lighting in dwelling units is 3 VA per square foot." + explanation: Per Table 220.12, the unit load for general lighting in dwelling units is 3 VA per square foot. - id: load-p2 type: multiple_choice - question: "Per Table 220.42, what demand factor applies to the first 3,000 VA of general lighting load in a dwelling?" + question: Per Table 220.42, what demand factor applies to the first 3,000 VA of general lighting load in a dwelling? options: - - "35%" - - "50%" - - "75%" - - "100%" + - 35% + - 50% + - 75% + - 100% correct: 3 - explanation: "Per Table 220.42, for dwelling units, the first 3,000 VA is calculated at 100% demand factor. The portion from 3,001 to 120,000 VA is at 35%." + explanation: Per Table 220.42, for dwelling units, the first 3,000 VA is calculated at 100% demand factor. The portion from 3,001 to 120,000 VA is at 35%. + keyPrerequisite: feeders - id: range-demand - instruction: "Table 220.55 provides demand factors for household electric ranges, wall-mounted ovens, and counter-mounted cooking units. For a single range rated not more than 12 kW, the maximum demand is 8 kW. For ranges rated more than 12 kW but not more than 27 kW, add 5% to the 8 kW demand for each additional kW over 12 kW. Note 1 to Table 220.55: over 1-3/4 kW through 8-3/4 kW, the nameplate rating can be used for column C. Note 2: if the rating exceeds 12 kW, the maximum demand in Column C must be increased by 5% for each additional kW of rating over 12 kW." + instruction: 'Table 220.55 provides demand factors for household electric ranges, wall-mounted ovens, and counter-mounted cooking units. For a single range rated not more than 12 kW, the maximum demand is 8 kW. For ranges rated more than 12 kW but not more than 27 kW, add 5% to the 8 kW demand for each additional kW over 12 kW. Note 1 to Table 220.55: over 1-3/4 kW through 8-3/4 kW, the nameplate rating can be used for column C. Note 2: if the rating exceeds 12 kW, the maximum demand in Column C must be increased by 5% for each additional kW of rating over 12 kW.' problems: - id: range-p1 type: multiple_choice - question: "Per Table 220.55, what is the maximum demand for a single 12 kW household electric range?" + question: Per Table 220.55, what is the maximum demand for a single 12 kW household electric range? options: - - "6 kW" - - "8 kW" - - "10 kW" - - "12 kW" + - 6 kW + - 8 kW + - 10 kW + - 12 kW correct: 1 - explanation: "Per Table 220.55, Column C, the maximum demand for one household electric range rated not more than 12 kW is 8 kW." + explanation: Per Table 220.55, Column C, the maximum demand for one household electric range rated not more than 12 kW is 8 kW. - id: range-p2 type: multiple_choice - question: "Per 220.54, what is the minimum demand load for a dwelling unit electric dryer?" + question: Per 220.54, what is the minimum demand load for a dwelling unit electric dryer? options: - - "3,000 VA" - - "4,000 VA" - - "5,000 VA" - - "6,000 VA" + - 3,000 VA + - 4,000 VA + - 5,000 VA + - 6,000 VA correct: 2 - explanation: "Per 220.54, a dwelling unit dryer load must be not less than 5,000 VA or the nameplate rating, whichever is larger." + explanation: Per 220.54, a dwelling unit dryer load must be not less than 5,000 VA or the nameplate rating, whichever is larger. - id: range-p3 type: multiple_choice - question: "Per 220.60, when calculating service load for a dwelling with both AC and heating, you use:" + question: 'Per 220.60, when calculating service load for a dwelling with both AC and heating, you use:' options: - - "Both loads at 100%" - - "The larger of the two loads" - - "Both loads at 50%" - - "The smaller of the two loads" + - Both loads at 100% + - The larger of the two loads + - Both loads at 50% + - The smaller of the two loads correct: 1 - explanation: "Per 220.60, it is not likely that both heating and cooling loads will be on at the same time, so only the larger of the two loads need be included in the service calculation." + explanation: Per 220.60, it is not likely that both heating and cooling loads will be on at the same time, so only the larger of the two loads need be included in the service calculation. - id: range-p4 type: multiple_choice - question: "A 1,500 sq ft dwelling. What is the general lighting load before applying demand factors?" + question: A 1,500 sq ft dwelling. What is the general lighting load before applying demand factors? options: - - "3,000 VA" - - "3,750 VA" - - "4,500 VA" - - "5,250 VA" + - 3,000 VA + - 3,750 VA + - 4,500 VA + - 5,250 VA correct: 2 - explanation: "Per Table 220.12, dwelling unit general lighting is 3 VA per square foot. 1,500 sq ft x 3 VA/sq ft = 4,500 VA." - + explanation: Per Table 220.12, dwelling unit general lighting is 3 VA per square foot. 1,500 sq ft x 3 VA/sq ft = 4,500 VA. + keyPrerequisite: dwelling-load-calculations - id: service-entrance - name: "Article 230 — Service Entrance" + name: Article 230 — Service Entrance difficulty: 5 estimatedMinutes: 25 - tags: [service, article-230, disconnects] - sourceRef: "NEC 2023 Article 230" + tags: + - service + - article-230 + - disconnects + sourceRef: NEC 2023 Article 230 prerequisites: - dwelling-load-calculations - overcurrent-protection knowledgePoints: - id: service-conductors - instruction: "Article 230 covers services -- the conductors and equipment for delivering electric energy from the utility. Service entrance conductors must have an ampacity not less than the maximum load to be served per 230.42(A). For a one-family dwelling, the minimum service is 100 amperes, 3-wire (230.79(C)). For all other installations, the minimum is 60 amperes (230.79(B)). Each service must have a means of disconnect that simultaneously disconnects all ungrounded service conductors (230.71). There can be up to six service disconnects per 230.71(A), grouped at one location. Service entrance conductors must be protected from physical damage (230.50) and must have overcurrent protection per 230.90." - workedExample: "Example: A 200A residential service has 2/0 copper service entrance conductors. Is this adequate? Per Table 310.16, 2/0 copper at 75C = 175A. This is less than 200A, so 2/0 is NOT adequate. You need at least 3/0 copper (200A at 75C) for a 200A service." + instruction: Article 230 covers services -- the conductors and equipment for delivering electric energy from the utility. Service entrance conductors must have an ampacity not less than the maximum load to be served per 230.42(A). For a one-family dwelling, the minimum service is 100 amperes, 3-wire (230.79(C)). For all other installations, the minimum is 60 amperes (230.79(B)). Each service must have a means of disconnect that simultaneously disconnects all ungrounded service conductors (230.71). There can be up to six service disconnects per 230.71(A), grouped at one location. Service entrance conductors must be protected from physical damage (230.50) and must have overcurrent protection per 230.90. + workedExample: 'Example: A 200A residential service has 2/0 copper service entrance conductors. Is this adequate? Per Table 310.16, 2/0 copper at 75C = 175A. This is less than 200A, so 2/0 is NOT adequate. You need at least 3/0 copper (200A at 75C) for a 200A service.' problems: - id: service-p1 type: multiple_choice - question: "What is the minimum service size for a one-family dwelling per 230.79(C)?" + question: What is the minimum service size for a one-family dwelling per 230.79(C)? options: - - "60 amperes" - - "100 amperes" - - "150 amperes" - - "200 amperes" + - 60 amperes + - 100 amperes + - 150 amperes + - 200 amperes correct: 1 - explanation: "Per 230.79(C), for a one-family dwelling, the service disconnecting means must have a rating of not less than 100 amperes, 3-wire." + explanation: Per 230.79(C), for a one-family dwelling, the service disconnecting means must have a rating of not less than 100 amperes, 3-wire. - id: service-p2 type: multiple_choice - question: "Per 230.71(A), what is the maximum number of service disconnects permitted?" + question: Per 230.71(A), what is the maximum number of service disconnects permitted? options: - - "Two" - - "Four" - - "Six" - - "Eight" + - Two + - Four + - Six + - Eight correct: 2 - explanation: "Per 230.71(A), the service disconnecting means can consist of not more than six switches or six circuit breakers, grouped at one location." + explanation: Per 230.71(A), the service disconnecting means can consist of not more than six switches or six circuit breakers, grouped at one location. - id: service-p3 type: multiple_choice - question: "What minimum size copper service entrance conductors are needed for a 200A service (75C terminals)?" + question: What minimum size copper service entrance conductors are needed for a 200A service (75C terminals)? options: - - "2/0 AWG" - - "3/0 AWG" - - "4/0 AWG" - - "250 kcmil" + - 2/0 AWG + - 3/0 AWG + - 4/0 AWG + - 250 kcmil correct: 1 - explanation: "Per Table 310.16, 3/0 AWG copper at 75 degrees C has an ampacity of 200A, meeting the 200A service requirement." + explanation: Per Table 310.16, 3/0 AWG copper at 75 degrees C has an ampacity of 200A, meeting the 200A service requirement. - id: service-p4 type: true_false - question: "Service entrance conductors must be protected from physical damage per 230.50." - correct: "true" - explanation: "Per 230.50, service entrance conductors installed as open conductors or in cable trays must be protected from physical damage." - + question: Service entrance conductors must be protected from physical damage per 230.50. + correct: 'true' + explanation: Per 230.50, service entrance conductors installed as open conductors or in cable trays must be protected from physical damage. + keyPrerequisite: dwelling-load-calculations - id: switches-controls - name: "Article 404 — Switches and Controls" + name: Article 404 — Switches and Controls difficulty: 3 estimatedMinutes: 15 - tags: [switches, article-404] - sourceRef: "NEC 2023 Article 404" + tags: + - switches + - article-404 + sourceRef: NEC 2023 Article 404 prerequisites: - branch-circuits knowledgePoints: - id: switch-installation - instruction: "Article 404 covers the installation of switches, including snap switches, dimmers, and motor controllers. Switches must be installed to be accessible (404.8(A)) -- mounted with the center of the grip no more than 6 feet 7 inches above the floor or working platform. AC general-use snap switches must be rated for the voltage and current of the circuit. When controlling an inductive load (like a motor), the switch must be rated for the type of load. Three-way and four-way switches must be wired so that switching occurs only in the ungrounded conductor(s) (404.2(A)). A neutral conductor is now required at most switch locations per 404.2(C) to accommodate future smart switches and occupancy sensors, with some exceptions (switch loops in existing conduit, where impracticable, etc.)." + instruction: Article 404 covers the installation of switches, including snap switches, dimmers, and motor controllers. Switches must be installed to be accessible (404.8(A)) -- mounted with the center of the grip no more than 6 feet 7 inches above the floor or working platform. AC general-use snap switches must be rated for the voltage and current of the circuit. When controlling an inductive load (like a motor), the switch must be rated for the type of load. Three-way and four-way switches must be wired so that switching occurs only in the ungrounded conductor(s) (404.2(A)). A neutral conductor is now required at most switch locations per 404.2(C) to accommodate future smart switches and occupancy sensors, with some exceptions (switch loops in existing conduit, where impracticable, etc.). problems: - id: switch-p1 type: multiple_choice - question: "Per 404.8(A), what is the maximum mounting height for a switch (center of grip) above the floor?" + question: Per 404.8(A), what is the maximum mounting height for a switch (center of grip) above the floor? options: - - "5 feet 6 inches" - - "6 feet 0 inches" - - "6 feet 7 inches" - - "7 feet 0 inches" + - 5 feet 6 inches + - 6 feet 0 inches + - 6 feet 7 inches + - 7 feet 0 inches correct: 2 - explanation: "Per 404.8(A), snap switches and dimmers must be installed so that they can be operated from a readily accessible place, with the center of the grip not more than 6 feet 7 inches (2.0 m) above the floor or working platform." + explanation: Per 404.8(A), snap switches and dimmers must be installed so that they can be operated from a readily accessible place, with the center of the grip not more than 6 feet 7 inches (2.0 m) above the floor or working platform. - id: switch-p2 type: true_false - question: "A neutral conductor is required at most switch locations in new construction per 404.2(C)." - correct: "true" - explanation: "Per 404.2(C), a grounded conductor (neutral) must be installed at the locations specified for lighting switches. This accommodates occupancy sensors, dimmers, and other devices that require a neutral for operation." + question: A neutral conductor is required at most switch locations in new construction per 404.2(C). + correct: 'true' + explanation: Per 404.2(C), a grounded conductor (neutral) must be installed at the locations specified for lighting switches. This accommodates occupancy sensors, dimmers, and other devices that require a neutral for operation. - id: switch-p3 type: fill_blank - question: "Per 404.8(A), the center of the switch grip must be mounted no more than ___ feet ___ inches above the floor." - correct: "6 feet 7 inches" - explanation: "Per 404.8(A), switches must be installed with the center of the grip not more than 6 feet 7 inches (2.0 m) above the floor or working platform." + question: Per 404.8(A), the center of the switch grip must be mounted no more than ___ feet ___ inches above the floor. + correct: 6 feet 7 inches + explanation: Per 404.8(A), switches must be installed with the center of the grip not more than 6 feet 7 inches (2.0 m) above the floor or working platform. - id: switch-p4 type: true_false - question: "Three-way and four-way switches may switch the grounded (neutral) conductor." - correct: "false" - explanation: "Per 404.2(A), switches must only be installed in the ungrounded conductor(s). Switching must never occur in the neutral (grounded conductor)." - - # ============================================================ - # MOTORS & TRANSFORMERS - # ============================================================ - + question: Three-way and four-way switches may switch the grounded (neutral) conductor. + correct: 'false' + explanation: Per 404.2(A), switches must only be installed in the ungrounded conductor(s). Switching must never occur in the neutral (grounded conductor). + keyPrerequisite: article-100-definitions - id: motors-article-430 - name: "Article 430 — Motor Circuits" + name: Article 430 — Motor Circuits difficulty: 6 estimatedMinutes: 30 - tags: [motors, article-430] - sourceRef: "NEC 2023 Article 430" + tags: + - motors + - article-430 + sourceRef: NEC 2023 Article 430 prerequisites: - overcurrent-protection - conductor-sizing knowledgePoints: - id: motor-branch-circuit - instruction: "Motor branch circuit conductors must have an ampacity not less than 125% of the motor full-load current (FLC) per 430.22. Motor FLC is taken from Tables 430.247-430.250, NOT from the motor nameplate. For a single motor, the branch circuit short-circuit and ground-fault protective device (BCSCGFPD) is sized per Table 430.52. For an inverse time breaker protecting a standard AC motor, the maximum rating is 250% of the FLC. If 250% does not correspond to a standard size, the next standard size up is permitted. Motor overload protection is separate and is sized at 115% of the motor nameplate current for motors with a service factor of 1.15 or greater, or 125% for other motors (430.32)." - workedExample: "Example: Size the branch circuit for a 10 HP, 230V, 3-phase motor. Step 1: Table 430.248 gives FLC = 28A. Step 2: Conductor ampacity = 28A x 1.25 = 35A minimum. From Table 310.16 at 75C, 8 AWG = 50A. Step 3: BCSCGFPD = 28A x 2.50 = 70A. Standard size: 70A breaker. Step 4: Overload = nameplate current x 1.15 (assuming SF >= 1.15)." + instruction: Motor branch circuit conductors must have an ampacity not less than 125% of the motor full-load current (FLC) per 430.22. Motor FLC is taken from Tables 430.247-430.250, NOT from the motor nameplate. For a single motor, the branch circuit short-circuit and ground-fault protective device (BCSCGFPD) is sized per Table 430.52. For an inverse time breaker protecting a standard AC motor, the maximum rating is 250% of the FLC. If 250% does not correspond to a standard size, the next standard size up is permitted. Motor overload protection is separate and is sized at 115% of the motor nameplate current for motors with a service factor of 1.15 or greater, or 125% for other motors (430.32). + workedExample: 'Example: Size the branch circuit for a 10 HP, 230V, 3-phase motor. Step 1: Table 430.248 gives FLC = 28A. Step 2: Conductor ampacity = 28A x 1.25 = 35A minimum. From Table 310.16 at 75C, 8 AWG = 50A. Step 3: BCSCGFPD = 28A x 2.50 = 70A. Standard size: 70A breaker. Step 4: Overload = nameplate current x 1.15 (assuming SF >= 1.15).' problems: - id: motor-p1 type: multiple_choice - question: "Motor branch circuit conductors must be sized at what percentage of the motor full-load current?" + question: Motor branch circuit conductors must be sized at what percentage of the motor full-load current? options: - - "100%" - - "115%" - - "125%" - - "150%" + - 100% + - 115% + - 125% + - 150% correct: 2 - explanation: "Per 430.22, branch circuit conductors supplying a single motor must have an ampacity not less than 125% of the motor full-load current rating from Tables 430.247-430.250." + explanation: Per 430.22, branch circuit conductors supplying a single motor must have an ampacity not less than 125% of the motor full-load current rating from Tables 430.247-430.250. - id: motor-p2 type: multiple_choice - question: "Motor full-load current for branch circuit sizing must be taken from:" + question: 'Motor full-load current for branch circuit sizing must be taken from:' options: - - "The motor nameplate" - - "Tables 430.247-430.250 in the NEC" - - "The manufacturer's catalog" - - "The utility provider's specifications" + - The motor nameplate + - Tables 430.247-430.250 in the NEC + - The manufacturer's catalog + - The utility provider's specifications correct: 1 - explanation: "Per 430.6(A), motor full-load current values for sizing branch circuit conductors, short-circuit protection, and ampacity must be taken from Tables 430.247-430.250, NOT from the motor nameplate." + explanation: Per 430.6(A), motor full-load current values for sizing branch circuit conductors, short-circuit protection, and ampacity must be taken from Tables 430.247-430.250, NOT from the motor nameplate. - id: motor-p3 type: multiple_choice - question: "Per Table 430.52, the maximum BCSCGFPD rating for an inverse time breaker protecting a standard AC motor is:" + question: 'Per Table 430.52, the maximum BCSCGFPD rating for an inverse time breaker protecting a standard AC motor is:' options: - - "150% of FLC" - - "200% of FLC" - - "250% of FLC" - - "300% of FLC" + - 150% of FLC + - 200% of FLC + - 250% of FLC + - 300% of FLC correct: 2 - explanation: "Per Table 430.52, for a single-voltage, non-time-delay (inverse time) circuit breaker protecting a standard Design B motor, the maximum setting is 250% of the full-load current." + explanation: Per Table 430.52, for a single-voltage, non-time-delay (inverse time) circuit breaker protecting a standard Design B motor, the maximum setting is 250% of the full-load current. - id: motor-p4 type: multiple_choice - question: "Motor overload protection for a motor with a service factor of 1.15 or greater is sized at:" + question: 'Motor overload protection for a motor with a service factor of 1.15 or greater is sized at:' options: - - "100% of nameplate current" - - "115% of nameplate current" - - "125% of nameplate current" - - "150% of nameplate current" + - 100% of nameplate current + - 115% of nameplate current + - 125% of nameplate current + - 150% of nameplate current correct: 1 - explanation: "Per 430.32(A)(1), for a motor with a marked service factor of 1.15 or greater, the overload protective device is sized at not more than 115% of the motor nameplate full-load current." - + explanation: Per 430.32(A)(1), for a motor with a marked service factor of 1.15 or greater, the overload protective device is sized at not more than 115% of the motor nameplate full-load current. + keyPrerequisite: overcurrent-protection - id: transformers - name: "Article 450 — Transformer Protection" + name: Article 450 — Transformer Protection difficulty: 5 estimatedMinutes: 20 - tags: [transformers, article-450] - sourceRef: "NEC 2023 Article 450" + tags: + - transformers + - article-450 + sourceRef: NEC 2023 Article 450 prerequisites: - overcurrent-protection knowledgePoints: - id: transformer-oc-protection - instruction: "Table 450.3(B) provides overcurrent protection requirements for transformers rated 1000V or less. For transformers with primary current of 9A or more: primary protection max is 125% of rated primary current. If 125% does not correspond to a standard rating, the next standard size up is permitted. Secondary protection may not be required if primary protection is within limits. For transformers with primary current less than 9A: primary protection max is 167% of primary current. For transformers less than 2A primary: maximum is 300%. When secondary protection is provided at 125% of secondary current, primary protection may be increased to 250%." + instruction: 'Table 450.3(B) provides overcurrent protection requirements for transformers rated 1000V or less. For transformers with primary current of 9A or more: primary protection max is 125% of rated primary current. If 125% does not correspond to a standard rating, the next standard size up is permitted. Secondary protection may not be required if primary protection is within limits. For transformers with primary current less than 9A: primary protection max is 167% of primary current. For transformers less than 2A primary: maximum is 300%. When secondary protection is provided at 125% of secondary current, primary protection may be increased to 250%.' problems: - id: xformer-p1 type: multiple_choice - question: "Per Table 450.3(B), what is the maximum primary overcurrent protection for a transformer with a primary current of 9A or more (primary only protection)?" + question: Per Table 450.3(B), what is the maximum primary overcurrent protection for a transformer with a primary current of 9A or more (primary only protection)? options: - - "100% of primary current" - - "125% of primary current" - - "150% of primary current" - - "200% of primary current" + - 100% of primary current + - 125% of primary current + - 150% of primary current + - 200% of primary current correct: 1 - explanation: "Per Table 450.3(B), for transformers rated 1000V or less with primary current of 9A or more, the maximum primary overcurrent protection is 125% of rated primary current." + explanation: Per Table 450.3(B), for transformers rated 1000V or less with primary current of 9A or more, the maximum primary overcurrent protection is 125% of rated primary current. - id: xformer-p2 type: multiple_choice - question: "When secondary protection is provided at 125% of secondary current, the primary overcurrent protection for a transformer (9A or more primary) can be increased to:" + question: 'When secondary protection is provided at 125% of secondary current, the primary overcurrent protection for a transformer (9A or more primary) can be increased to:' options: - - "150%" - - "200%" - - "250%" - - "300%" + - 150% + - 200% + - 250% + - 300% correct: 2 - explanation: "Per Table 450.3(B), when both primary and secondary protection are provided, the primary can be set at up to 250% (next standard size up permitted) and the secondary at not more than 125%." + explanation: Per Table 450.3(B), when both primary and secondary protection are provided, the primary can be set at up to 250% (next standard size up permitted) and the secondary at not more than 125%. - id: xformer-p3 type: fill_blank - question: "Per Table 450.3(B), for transformers with primary current less than 9A, the maximum primary overcurrent protection is ___% of primary current." - correct: "167" - explanation: "Per Table 450.3(B), for transformers with primary current less than 9 amperes, the maximum primary-only overcurrent protection is 167% of the rated primary current." + question: Per Table 450.3(B), for transformers with primary current less than 9A, the maximum primary overcurrent protection is ___% of primary current. + correct: '167' + explanation: Per Table 450.3(B), for transformers with primary current less than 9 amperes, the maximum primary-only overcurrent protection is 167% of the rated primary current. - id: xformer-p4 type: ordering - question: "Place these transformer primary current ranges in order from lowest to highest maximum primary OCP percentage." - options: - - "Less than 2A primary — 300%" - - "Less than 9A primary — 167%" - - "9A or more primary — 125%" - correct: "2,1,0" - explanation: "Per Table 450.3(B): 9A or more = 125% max, less than 9A = 167% max, less than 2A = 300% max. Smaller primary currents get higher protection percentages." - - # ============================================================ - # SPECIAL OCCUPANCIES & EQUIPMENT - # ============================================================ - + question: Place these transformer primary current ranges in order from lowest to highest maximum primary OCP percentage. + options: + - Less than 2A primary — 300% + - Less than 9A primary — 167% + - 9A or more primary — 125% + correct: 2,1,0 + explanation: 'Per Table 450.3(B): 9A or more = 125% max, less than 9A = 167% max, less than 2A = 300% max. Smaller primary currents get higher protection percentages.' + keyPrerequisite: overcurrent-protection - id: swimming-pools - name: "Article 680 — Swimming Pools and Hot Tubs" + name: Article 680 — Swimming Pools and Hot Tubs difficulty: 6 estimatedMinutes: 25 - tags: [special-equipment, pools, article-680] - sourceRef: "NEC 2023 Article 680" + tags: + - special-equipment + - pools + - article-680 + sourceRef: NEC 2023 Article 680 prerequisites: - grounding-fundamentals - gfci-protection knowledgePoints: - id: pool-bonding - instruction: "Article 680 requires extensive bonding and GFCI protection for pools, spas, and hot tubs. The equipotential bonding grid (680.26) must bond together: all metallic parts of the pool structure, metal fittings within or attached to the pool, metal parts of electric equipment associated with the pool, metal parts within 5 feet horizontally of the inside walls of the pool, and metal parts within 12 feet above the maximum water level. All 125V receptacles within 20 feet of the inside walls of a pool must be GFCI protected (680.22(A)(1)). Receptacles between 6 and 20 feet from the pool edge must be GFCI protected. No receptacles are permitted within 6 feet of the inside walls. Luminaires over 12 feet above the pool need not be GFCI protected." + instruction: 'Article 680 requires extensive bonding and GFCI protection for pools, spas, and hot tubs. The equipotential bonding grid (680.26) must bond together: all metallic parts of the pool structure, metal fittings within or attached to the pool, metal parts of electric equipment associated with the pool, metal parts within 5 feet horizontally of the inside walls of the pool, and metal parts within 12 feet above the maximum water level. All 125V receptacles within 20 feet of the inside walls of a pool must be GFCI protected (680.22(A)(1)). Receptacles between 6 and 20 feet from the pool edge must be GFCI protected. No receptacles are permitted within 6 feet of the inside walls. Luminaires over 12 feet above the pool need not be GFCI protected.' problems: - id: pool-p1 type: multiple_choice - question: "Per 680.22(A)(1), what is the minimum distance from the inside wall of a pool where receptacles may be located?" + question: Per 680.22(A)(1), what is the minimum distance from the inside wall of a pool where receptacles may be located? options: - - "3 feet" - - "5 feet" - - "6 feet" - - "10 feet" + - 3 feet + - 5 feet + - 6 feet + - 10 feet correct: 2 - explanation: "Per 680.22(A)(1), receptacles must not be located less than 6 feet from the inside walls of an indoor or outdoor pool." + explanation: Per 680.22(A)(1), receptacles must not be located less than 6 feet from the inside walls of an indoor or outdoor pool. - id: pool-p2 type: multiple_choice - question: "All receptacles within how many feet of a pool's inside walls must be GFCI protected?" + question: All receptacles within how many feet of a pool's inside walls must be GFCI protected? options: - - "6 feet" - - "10 feet" - - "15 feet" - - "20 feet" + - 6 feet + - 10 feet + - 15 feet + - 20 feet correct: 3 - explanation: "Per 680.22(A)(1) and (A)(4), all 125V, 15- and 20-ampere receptacles located within 20 feet of the inside wall of a pool must have GFCI protection." + explanation: Per 680.22(A)(1) and (A)(4), all 125V, 15- and 20-ampere receptacles located within 20 feet of the inside wall of a pool must have GFCI protection. - id: pool-p3 type: fill_blank - question: "Per 680.26, the equipotential bonding grid must bond metal parts within ___ feet horizontally of the inside walls of the pool." - correct: "5" - explanation: "Per 680.26(B)(2), all metal parts within 5 feet horizontally of the inside walls of the pool must be bonded to the equipotential bonding grid." + question: Per 680.26, the equipotential bonding grid must bond metal parts within ___ feet horizontally of the inside walls of the pool. + correct: '5' + explanation: Per 680.26(B)(2), all metal parts within 5 feet horizontally of the inside walls of the pool must be bonded to the equipotential bonding grid. - id: pool-p4 type: ordering - question: "Place these pool-related distances from shortest to longest." - options: - - "Minimum distance for receptacles from pool wall" - - "GFCI required distance from pool wall" - - "Equipotential bonding horizontal distance" - correct: "2,0,1" - explanation: "Bonding = 5 feet horizontal, receptacle minimum = 6 feet from inside wall, GFCI required = 20 feet from inside wall." - + question: Place these pool-related distances from shortest to longest. + options: + - Minimum distance for receptacles from pool wall + - GFCI required distance from pool wall + - Equipotential bonding horizontal distance + correct: 2,0,1 + explanation: Bonding = 5 feet horizontal, receptacle minimum = 6 feet from inside wall, GFCI required = 20 feet from inside wall. + keyPrerequisite: gfci-protection - id: hazardous-locations - name: "Articles 500-516 — Hazardous (Classified) Locations" + name: Articles 500-516 — Hazardous (Classified) Locations difficulty: 7 estimatedMinutes: 25 - tags: [hazardous, special-occupancies, articles-500-516] - sourceRef: "NEC 2023 Articles 500-516" + tags: + - hazardous + - special-occupancies + - articles-500-516 + sourceRef: NEC 2023 Articles 500-516 prerequisites: - wiring-methods-overview - bonding knowledgePoints: - id: hazloc-classification - instruction: "Hazardous locations are classified by the type of hazard and the probability of the hazard being present. Class I = flammable gases or vapors. Class II = combustible dust. Class III = ignitable fibers or flyings. Each class has two Divisions: Division 1 = hazard present under normal operating conditions. Division 2 = hazard present only under abnormal conditions. The alternative Zone system (Articles 505/506) uses Zone 0 (continuous hazard), Zone 1 (likely under normal conditions), and Zone 2 (not likely under normal conditions) for Class I. Wiring methods in Division 1 locations are severely restricted -- typically threaded rigid conduit (RMC) or Type MI cable. Division 2 locations allow more wiring methods including MC cable and certain sealed raceways." + instruction: 'Hazardous locations are classified by the type of hazard and the probability of the hazard being present. Class I = flammable gases or vapors. Class II = combustible dust. Class III = ignitable fibers or flyings. Each class has two Divisions: Division 1 = hazard present under normal operating conditions. Division 2 = hazard present only under abnormal conditions. The alternative Zone system (Articles 505/506) uses Zone 0 (continuous hazard), Zone 1 (likely under normal conditions), and Zone 2 (not likely under normal conditions) for Class I. Wiring methods in Division 1 locations are severely restricted -- typically threaded rigid conduit (RMC) or Type MI cable. Division 2 locations allow more wiring methods including MC cable and certain sealed raceways.' problems: - id: hazloc-p1 type: multiple_choice - question: "A Class I, Division 1 location contains:" + question: 'A Class I, Division 1 location contains:' options: - - "Combustible dust under normal conditions" - - "Ignitable fibers under normal conditions" - - "Flammable gases or vapors under normal conditions" - - "Flammable gases or vapors only under abnormal conditions" + - Combustible dust under normal conditions + - Ignitable fibers under normal conditions + - Flammable gases or vapors under normal conditions + - Flammable gases or vapors only under abnormal conditions correct: 2 - explanation: "Class I locations involve flammable gases or vapors. Division 1 means the hazard exists under normal operating conditions or frequently during maintenance/repair. Class I, Division 2 would be the abnormal-conditions-only scenario." + explanation: Class I locations involve flammable gases or vapors. Division 1 means the hazard exists under normal operating conditions or frequently during maintenance/repair. Class I, Division 2 would be the abnormal-conditions-only scenario. - id: hazloc-p2 type: multiple_choice - question: "Which wiring method is typically required in Class I, Division 1 locations?" + question: Which wiring method is typically required in Class I, Division 1 locations? options: - - "NM cable" - - "EMT with compression fittings" - - "Threaded rigid metal conduit (RMC)" - - "PVC conduit" + - NM cable + - EMT with compression fittings + - Threaded rigid metal conduit (RMC) + - PVC conduit correct: 2 - explanation: "In Class I, Division 1 locations, threaded rigid metal conduit (RMC) or Type MI cable is typically required per 501.10(A). EMT, NM cable, and PVC conduit are not permitted in these hazardous locations." + explanation: In Class I, Division 1 locations, threaded rigid metal conduit (RMC) or Type MI cable is typically required per 501.10(A). EMT, NM cable, and PVC conduit are not permitted in these hazardous locations. - id: hazloc-p3 type: matching - question: "Match each hazardous location class with the type of hazard present." + question: Match each hazardous location class with the type of hazard present. options: - - "Class I|Flammable gases or vapors" - - "Class II|Combustible dust" - - "Class III|Ignitable fibers or flyings" - correct: "0,1,2" - explanation: "Class I = flammable gases/vapors (Articles 500-501), Class II = combustible dust (Articles 500, 502), Class III = ignitable fibers/flyings (Articles 500, 503)." + - Class I|Flammable gases or vapors + - Class II|Combustible dust + - Class III|Ignitable fibers or flyings + correct: 0,1,2 + explanation: Class I = flammable gases/vapors (Articles 500-501), Class II = combustible dust (Articles 500, 502), Class III = ignitable fibers/flyings (Articles 500, 503). - id: hazloc-p4 type: fill_blank - question: "In the hazardous location classification system, Division ___ means the hazard exists under normal operating conditions." - correct: "1" - explanation: "Division 1 locations have the hazard present under normal operating conditions or frequently during maintenance. Division 2 locations have the hazard only under abnormal or fault conditions." - + question: In the hazardous location classification system, Division ___ means the hazard exists under normal operating conditions. + correct: '1' + explanation: Division 1 locations have the hazard present under normal operating conditions or frequently during maintenance. Division 2 locations have the hazard only under abnormal or fault conditions. + keyPrerequisite: rigid-conduit - id: emergency-systems - name: "Article 700 — Emergency Systems" + name: Article 700 — Emergency Systems difficulty: 5 estimatedMinutes: 20 - tags: [emergency, article-700] - sourceRef: "NEC 2023 Article 700" + tags: + - emergency + - article-700 + sourceRef: NEC 2023 Article 700 prerequisites: - service-entrance knowledgePoints: - id: emergency-requirements - instruction: "Article 700 covers emergency systems that are legally required and classified as emergency by the authority having jurisdiction. Emergency systems must restore power within 10 seconds of failure of the normal supply (700.12). Wiring for emergency systems must be kept entirely independent of all other wiring (700.10(B)(5)) -- in separate raceways, cables, boxes, and cabinets. Emergency system wiring cannot enter the same raceway, box, or cabinet as normal wiring. Transfer equipment must be automatic and identified for emergency use (700.5). Emergency power sources include: storage batteries, generator sets, uninterruptible power supplies, separate utility service, or fuel cell systems." + instruction: 'Article 700 covers emergency systems that are legally required and classified as emergency by the authority having jurisdiction. Emergency systems must restore power within 10 seconds of failure of the normal supply (700.12). Wiring for emergency systems must be kept entirely independent of all other wiring (700.10(B)(5)) -- in separate raceways, cables, boxes, and cabinets. Emergency system wiring cannot enter the same raceway, box, or cabinet as normal wiring. Transfer equipment must be automatic and identified for emergency use (700.5). Emergency power sources include: storage batteries, generator sets, uninterruptible power supplies, separate utility service, or fuel cell systems.' problems: - id: emerg-p1 type: multiple_choice - question: "Per 700.12, emergency systems must restore power within how many seconds?" + question: Per 700.12, emergency systems must restore power within how many seconds? options: - - "5 seconds" - - "10 seconds" - - "30 seconds" - - "60 seconds" + - 5 seconds + - 10 seconds + - 30 seconds + - 60 seconds correct: 1 - explanation: "Per 700.12, emergency systems must be capable of supplying emergency lighting and power within 10 seconds of failure of the normal supply." + explanation: Per 700.12, emergency systems must be capable of supplying emergency lighting and power within 10 seconds of failure of the normal supply. - id: emerg-p2 type: true_false - question: "Emergency system wiring can share a raceway with normal power wiring if the conductors are properly labeled." - correct: "false" - explanation: "Per 700.10(B)(5), wiring for emergency systems must be kept entirely independent of all other wiring. Emergency and normal wiring cannot occupy the same raceway, cable, box, or cabinet." + question: Emergency system wiring can share a raceway with normal power wiring if the conductors are properly labeled. + correct: 'false' + explanation: Per 700.10(B)(5), wiring for emergency systems must be kept entirely independent of all other wiring. Emergency and normal wiring cannot occupy the same raceway, cable, box, or cabinet. - id: emerg-p3 type: fill_blank - question: "Per 700.12, emergency systems must restore power within ___ seconds of failure of the normal supply." - correct: "10" - explanation: "Per 700.12, the emergency system must be capable of supplying emergency lighting and power within 10 seconds of failure of the normal supply." + question: Per 700.12, emergency systems must restore power within ___ seconds of failure of the normal supply. + correct: '10' + explanation: Per 700.12, the emergency system must be capable of supplying emergency lighting and power within 10 seconds of failure of the normal supply. - id: emerg-p4 type: matching - question: "Match each system type with its NEC article." - options: - - "Emergency systems|Article 700" - - "Legally required standby|Article 701" - - "Optional standby|Article 702" - correct: "0,1,2" - explanation: "Article 700 covers emergency systems (life safety), Article 701 covers legally required standby systems, and Article 702 covers optional standby systems. Each has different requirements for transfer time and wiring methods." - + question: Match each system type with its NEC article. + options: + - Emergency systems|Article 700 + - Legally required standby|Article 701 + - Optional standby|Article 702 + correct: 0,1,2 + explanation: Article 700 covers emergency systems (life safety), Article 701 covers legally required standby systems, and Article 702 covers optional standby systems. Each has different requirements for transfer time and wiring methods. + keyPrerequisite: service-entrance - id: fire-alarm-systems - name: "Article 760 — Fire Alarm Systems" + name: Article 760 — Fire Alarm Systems difficulty: 4 estimatedMinutes: 15 - tags: [fire-alarm, article-760] - sourceRef: "NEC 2023 Article 760" + tags: + - fire-alarm + - article-760 + sourceRef: NEC 2023 Article 760 prerequisites: - wiring-methods-overview knowledgePoints: - id: fire-alarm-wiring - instruction: "Article 760 covers fire alarm systems including fire detection, notification, guard tour, sprinkler waterflow, and sprinkler supervisory systems. Fire alarm circuits are classified as either non-power-limited (NPLFA) or power-limited (PLFA). NPLFA circuits (760.46-760.53) must be installed using wiring methods from Chapter 3 (same as power wiring). PLFA circuits (760.130-760.176) can use listed power-limited fire alarm cable. PLFA cables come in types FPLP (plenum), FPLR (riser), and FPL (general purpose). Fire alarm cables must not be run in the same cable, raceway, or enclosure with power conductors unless specifically permitted (760.136(A)). Fire alarm system conductors must be a minimum of 26 AWG for PLFA circuits." + instruction: Article 760 covers fire alarm systems including fire detection, notification, guard tour, sprinkler waterflow, and sprinkler supervisory systems. Fire alarm circuits are classified as either non-power-limited (NPLFA) or power-limited (PLFA). NPLFA circuits (760.46-760.53) must be installed using wiring methods from Chapter 3 (same as power wiring). PLFA circuits (760.130-760.176) can use listed power-limited fire alarm cable. PLFA cables come in types FPLP (plenum), FPLR (riser), and FPL (general purpose). Fire alarm cables must not be run in the same cable, raceway, or enclosure with power conductors unless specifically permitted (760.136(A)). Fire alarm system conductors must be a minimum of 26 AWG for PLFA circuits. problems: - id: fire-p1 type: multiple_choice - question: "Power-limited fire alarm (PLFA) cable rated for plenum use is designated as:" + question: 'Power-limited fire alarm (PLFA) cable rated for plenum use is designated as:' options: - - "FPL" - - "FPLR" - - "FPLP" - - "FPLS" + - FPL + - FPLR + - FPLP + - FPLS correct: 2 - explanation: "FPLP designates power-limited fire alarm cable rated for use in ducts, plenums, and other spaces used for environmental air. FPLR is riser-rated, and FPL is general-purpose." + explanation: FPLP designates power-limited fire alarm cable rated for use in ducts, plenums, and other spaces used for environmental air. FPLR is riser-rated, and FPL is general-purpose. - id: fire-p2 type: true_false - question: "Fire alarm cables can be placed in the same raceway as power conductors without restriction." - correct: "false" - explanation: "Per 760.136(A), fire alarm cables must not be run in the same cable, raceway, or enclosure with power conductors unless specifically permitted." + question: Fire alarm cables can be placed in the same raceway as power conductors without restriction. + correct: 'false' + explanation: Per 760.136(A), fire alarm cables must not be run in the same cable, raceway, or enclosure with power conductors unless specifically permitted. - id: fire-p3 type: matching - question: "Match each fire alarm cable type with its use." + question: Match each fire alarm cable type with its use. options: - - "FPLP|Plenum spaces" - - "FPLR|Riser applications" - - "FPL|General purpose" - correct: "0,1,2" - explanation: "FPLP is for plenums (highest rating), FPLR is for vertical riser runs between floors, and FPL is for general-purpose use." + - FPLP|Plenum spaces + - FPLR|Riser applications + - FPL|General purpose + correct: 0,1,2 + explanation: FPLP is for plenums (highest rating), FPLR is for vertical riser runs between floors, and FPL is for general-purpose use. - id: fire-p4 type: fill_blank - question: "Fire alarm system conductors in power-limited circuits must be a minimum of ___ AWG." - correct: "26" - explanation: "Per Article 760, the minimum conductor size for power-limited fire alarm (PLFA) circuits is 26 AWG." - + question: Fire alarm system conductors in power-limited circuits must be a minimum of ___ AWG. + correct: '26' + explanation: Per Article 760, the minimum conductor size for power-limited fire alarm (PLFA) circuits is 26 AWG. + keyPrerequisite: wiring-methods-overview - id: low-voltage-systems - name: "Article 725 — Class 1, 2, and 3 Circuits" + name: Article 725 — Class 1, 2, and 3 Circuits difficulty: 4 estimatedMinutes: 15 - tags: [low-voltage, article-725] - sourceRef: "NEC 2023 Article 725" + tags: + - low-voltage + - article-725 + sourceRef: NEC 2023 Article 725 prerequisites: - wiring-methods-overview knowledgePoints: - id: class-circuits - instruction: "Article 725 covers Class 1, 2, and 3 remote-control, signaling, and power-limited circuits. Class 1 circuits are power-limited to 30V and 1000 VA, and must follow Chapter 3 wiring methods. Class 2 circuits are limited to 150 VA and typically 30V (some up to 100V), and use listed Class 2 cable (CL2, CL2R, CL2P). Class 3 circuits allow higher power levels up to 100 VA. Class 2 and Class 3 cables must not be placed in the same raceway with power, lighting, or Class 1 conductors (725.136(A)), except in certain permitted configurations. Common Class 2 applications include thermostat wiring, doorbells, and security system sensors." + instruction: Article 725 covers Class 1, 2, and 3 remote-control, signaling, and power-limited circuits. Class 1 circuits are power-limited to 30V and 1000 VA, and must follow Chapter 3 wiring methods. Class 2 circuits are limited to 150 VA and typically 30V (some up to 100V), and use listed Class 2 cable (CL2, CL2R, CL2P). Class 3 circuits allow higher power levels up to 100 VA. Class 2 and Class 3 cables must not be placed in the same raceway with power, lighting, or Class 1 conductors (725.136(A)), except in certain permitted configurations. Common Class 2 applications include thermostat wiring, doorbells, and security system sensors. problems: - id: lv-p1 type: multiple_choice - question: "Which of the following is a common application of Class 2 circuits?" + question: Which of the following is a common application of Class 2 circuits? options: - - "Motor power wiring" - - "Lighting branch circuits" - - "Thermostat wiring" - - "Service entrance conductors" + - Motor power wiring + - Lighting branch circuits + - Thermostat wiring + - Service entrance conductors correct: 2 - explanation: "Class 2 circuits under Article 725 are commonly used for low-voltage applications such as thermostat wiring, doorbell circuits, and security system sensors." + explanation: Class 2 circuits under Article 725 are commonly used for low-voltage applications such as thermostat wiring, doorbell circuits, and security system sensors. - id: lv-p2 type: true_false - question: "Class 2 cables can be placed in the same raceway as power conductors." - correct: "false" - explanation: "Per 725.136(A), Class 2 and Class 3 cables must not be placed in any raceway, compartment, outlet box, or similar enclosure with power, lighting, or Class 1 conductors." + question: Class 2 cables can be placed in the same raceway as power conductors. + correct: 'false' + explanation: Per 725.136(A), Class 2 and Class 3 cables must not be placed in any raceway, compartment, outlet box, or similar enclosure with power, lighting, or Class 1 conductors. - id: lv-p3 type: fill_blank - question: "Class 2 circuits are limited to ___ VA of power per Article 725." - correct: "150" - explanation: "Class 2 circuits are power-limited to 150 VA, which makes them inherently safer and allows less restrictive wiring methods than Class 1 circuits." + question: Class 2 circuits are limited to ___ VA of power per Article 725. + correct: '150' + explanation: Class 2 circuits are power-limited to 150 VA, which makes them inherently safer and allows less restrictive wiring methods than Class 1 circuits. - id: lv-p4 type: matching - question: "Match each circuit class with its wiring method requirement." - options: - - "Class 1|Must follow Chapter 3 wiring methods" - - "Class 2|Can use listed CL2 cable" - - "Class 3|Can use listed CL3 cable" - correct: "0,1,2" - explanation: "Class 1 circuits must be installed using standard Chapter 3 wiring methods. Class 2 and Class 3 circuits can use their respective listed cables, which are less expensive and easier to install." - + question: Match each circuit class with its wiring method requirement. + options: + - Class 1|Must follow Chapter 3 wiring methods + - Class 2|Can use listed CL2 cable + - Class 3|Can use listed CL3 cable + correct: 0,1,2 + explanation: Class 1 circuits must be installed using standard Chapter 3 wiring methods. Class 2 and Class 3 circuits can use their respective listed cables, which are less expensive and easier to install. + keyPrerequisite: wiring-methods-overview - id: communication-circuits - name: "Article 800 — Communications Circuits" + name: Article 800 — Communications Circuits difficulty: 3 estimatedMinutes: 15 - tags: [communications, article-800] - sourceRef: "NEC 2023 Article 800" + tags: + - communications + - article-800 + sourceRef: NEC 2023 Article 800 prerequisites: - nec-overview knowledgePoints: - id: comms-wiring - instruction: "Article 800 covers telephone, data, and other communications circuits. Per NEC 90.3, Chapter 8 (Articles 800-840) is independent of Chapters 1-7 unless specifically referenced. Communications cables include: CMG/CM (general), CMR (riser), CMP (plenum), and CMX (limited use). Communications cables cannot occupy the same raceway or enclosure with power conductors except: where separated by a permanent barrier, or where the power conductors are 0-150V to ground and the communications cables are specifically listed for the purpose. Grounding of communications systems is covered in 800.100 -- the primary protector must be grounded to the building grounding electrode system." + instruction: 'Article 800 covers telephone, data, and other communications circuits. Per NEC 90.3, Chapter 8 (Articles 800-840) is independent of Chapters 1-7 unless specifically referenced. Communications cables include: CMG/CM (general), CMR (riser), CMP (plenum), and CMX (limited use). Communications cables cannot occupy the same raceway or enclosure with power conductors except: where separated by a permanent barrier, or where the power conductors are 0-150V to ground and the communications cables are specifically listed for the purpose. Grounding of communications systems is covered in 800.100 -- the primary protector must be grounded to the building grounding electrode system.' problems: - id: comms-p1 type: true_false - question: "Chapter 8 of the NEC (Communications) must comply with all requirements of Chapters 1-4." - correct: "false" - explanation: "Per 90.3, Chapter 8 covers communications systems and is not subject to the requirements of Chapters 1-7 except where the requirements are specifically referenced in Chapter 8." + question: Chapter 8 of the NEC (Communications) must comply with all requirements of Chapters 1-4. + correct: 'false' + explanation: Per 90.3, Chapter 8 covers communications systems and is not subject to the requirements of Chapters 1-7 except where the requirements are specifically referenced in Chapter 8. - id: comms-p2 type: multiple_choice - question: "Communications cable rated for plenum use is designated as:" + question: 'Communications cable rated for plenum use is designated as:' options: - - "CM" - - "CMR" - - "CMP" - - "CMX" + - CM + - CMR + - CMP + - CMX correct: 2 - explanation: "CMP designates communications cable rated for use in ducts, plenums, and other spaces used for environmental air. CMR is riser-rated, CM is general-purpose, and CMX is limited-use." + explanation: CMP designates communications cable rated for use in ducts, plenums, and other spaces used for environmental air. CMR is riser-rated, CM is general-purpose, and CMX is limited-use. - id: comms-p3 type: fill_blank - question: "Per 800.100, the primary protector of a communications system must be grounded to the building ___ electrode system." - correct: "grounding" - explanation: "Per 800.100, the primary protector must be grounded to the building grounding electrode system to provide a path for lightning and power cross surges." + question: Per 800.100, the primary protector of a communications system must be grounded to the building ___ electrode system. + correct: grounding + explanation: Per 800.100, the primary protector must be grounded to the building grounding electrode system to provide a path for lightning and power cross surges. - id: comms-p4 type: ordering - question: "Place these communications cable types from highest to lowest fire rating." - options: - - "CM (general purpose)" - - "CMP (plenum)" - - "CMR (riser)" - correct: "1,2,0" - explanation: "CMP (plenum) has the highest fire rating for use in air-handling spaces, CMR (riser) is next for vertical runs between floors, and CM (general purpose) has the lowest rating." - - # ============================================================ - # RENEWABLE ENERGY & SPECIAL EQUIPMENT - # ============================================================ - + question: Place these communications cable types from highest to lowest fire rating. + options: + - CM (general purpose) + - CMP (plenum) + - CMR (riser) + correct: 1,2,0 + explanation: CMP (plenum) has the highest fire rating for use in air-handling spaces, CMR (riser) is next for vertical runs between floors, and CM (general purpose) has the lowest rating. + keyPrerequisite: nec-overview - id: solar-pv - name: "Article 690 — Solar Photovoltaic Systems" + name: Article 690 — Solar Photovoltaic Systems difficulty: 6 estimatedMinutes: 25 - tags: [solar, renewable, article-690] - sourceRef: "NEC 2023 Article 690" + tags: + - solar + - renewable + - article-690 + sourceRef: NEC 2023 Article 690 prerequisites: - overcurrent-protection - grounding-fundamentals knowledgePoints: - id: pv-circuits - instruction: "Article 690 covers solar PV systems. PV source circuits (from modules to combiner box or inverter) must have conductor ampacity not less than the greater of: 125% of the PV source circuit current (Isc x 1.25) per 690.8(A). The maximum voltage of a PV system is determined by the sum of the rated open-circuit voltage of the series-connected modules, corrected for the lowest expected ambient temperature per 690.7. Rapid shutdown is required per 690.12 -- conductors more than 1 foot from the array or more than 3 feet from the point of entry to a building must be reduced to 80V or less within 30 seconds of rapid shutdown initiation. PV systems must be grounded per 690.41-690.47." + instruction: 'Article 690 covers solar PV systems. PV source circuits (from modules to combiner box or inverter) must have conductor ampacity not less than the greater of: 125% of the PV source circuit current (Isc x 1.25) per 690.8(A). The maximum voltage of a PV system is determined by the sum of the rated open-circuit voltage of the series-connected modules, corrected for the lowest expected ambient temperature per 690.7. Rapid shutdown is required per 690.12 -- conductors more than 1 foot from the array or more than 3 feet from the point of entry to a building must be reduced to 80V or less within 30 seconds of rapid shutdown initiation. PV systems must be grounded per 690.41-690.47.' problems: - id: solar-p1 type: multiple_choice - question: "PV source circuit conductors must be sized at a minimum of what percentage of the short-circuit current (Isc)?" + question: PV source circuit conductors must be sized at a minimum of what percentage of the short-circuit current (Isc)? options: - - "100%" - - "115%" - - "125%" - - "150%" + - 100% + - 115% + - 125% + - 150% correct: 2 - explanation: "Per 690.8(A), PV source circuit conductors must have an ampacity not less than 125% of the maximum current as calculated in 690.8(A)(1)." + explanation: Per 690.8(A), PV source circuit conductors must have an ampacity not less than 125% of the maximum current as calculated in 690.8(A)(1). - id: solar-p2 type: multiple_choice - question: "Per 690.12, the rapid shutdown requirement mandates that PV conductors outside the array boundary must be reduced to what voltage within 30 seconds?" + question: Per 690.12, the rapid shutdown requirement mandates that PV conductors outside the array boundary must be reduced to what voltage within 30 seconds? options: - - "30V or less" - - "50V or less" - - "80V or less" - - "120V or less" + - 30V or less + - 50V or less + - 80V or less + - 120V or less correct: 2 - explanation: "Per 690.12, conductors more than 1 foot from the array or 3 feet from the point of entry to a building must be limited to not more than 80V within 30 seconds of rapid shutdown initiation." + explanation: Per 690.12, conductors more than 1 foot from the array or 3 feet from the point of entry to a building must be limited to not more than 80V within 30 seconds of rapid shutdown initiation. - id: solar-p3 type: fill_blank - question: "PV source circuit conductors must have ampacity not less than ___% of the short-circuit current per 690.8(A)." - correct: "125" - explanation: "Per 690.8(A), PV source circuit conductors must be sized at a minimum of 125% of the maximum current (Isc) to account for continuous duty." + question: PV source circuit conductors must have ampacity not less than ___% of the short-circuit current per 690.8(A). + correct: '125' + explanation: Per 690.8(A), PV source circuit conductors must be sized at a minimum of 125% of the maximum current (Isc) to account for continuous duty. - id: solar-p4 type: true_false - question: "The maximum voltage of a PV system is determined using the open-circuit voltage corrected for the highest expected ambient temperature." - correct: "false" - explanation: "Per 690.7, the maximum voltage is corrected for the LOWEST expected ambient temperature, because PV voltage increases as temperature decreases." - + question: The maximum voltage of a PV system is determined using the open-circuit voltage corrected for the highest expected ambient temperature. + correct: 'false' + explanation: Per 690.7, the maximum voltage is corrected for the LOWEST expected ambient temperature, because PV voltage increases as temperature decreases. + keyPrerequisite: overcurrent-protection - id: battery-storage - name: "Article 706 — Energy Storage Systems" + name: Article 706 — Energy Storage Systems difficulty: 5 estimatedMinutes: 20 - tags: [battery, storage, article-706] - sourceRef: "NEC 2023 Article 706" + tags: + - battery + - storage + - article-706 + sourceRef: NEC 2023 Article 706 prerequisites: - solar-pv knowledgePoints: - id: ess-requirements - instruction: "Article 706 covers energy storage systems (ESS) including batteries, capacitors, and other technologies. ESS circuit conductors must be sized to carry not less than the maximum current for the specific application (706.20). Overcurrent protection must be provided for ESS circuits (706.21). Disconnecting means must be provided to disconnect the ESS from all conductors, and must be lockable in the open position (706.15). Ventilation is required for battery rooms where hydrogen gas may accumulate (706.30). ESS over 1 kWh must have a listed or field-labeled means to disconnect (706.15(A)). The 2023 NEC significantly expanded Article 706 to address the growing adoption of residential and commercial battery storage." + instruction: Article 706 covers energy storage systems (ESS) including batteries, capacitors, and other technologies. ESS circuit conductors must be sized to carry not less than the maximum current for the specific application (706.20). Overcurrent protection must be provided for ESS circuits (706.21). Disconnecting means must be provided to disconnect the ESS from all conductors, and must be lockable in the open position (706.15). Ventilation is required for battery rooms where hydrogen gas may accumulate (706.30). ESS over 1 kWh must have a listed or field-labeled means to disconnect (706.15(A)). The 2023 NEC significantly expanded Article 706 to address the growing adoption of residential and commercial battery storage. problems: - id: battery-p1 type: multiple_choice - question: "Per Article 706, the disconnecting means for an energy storage system must be:" + question: 'Per Article 706, the disconnecting means for an energy storage system must be:' options: - - "Accessible but not necessarily lockable" - - "Lockable in the open position" - - "Located within 6 feet of the ESS" - - "Rated for 200% of the ESS current" + - Accessible but not necessarily lockable + - Lockable in the open position + - Located within 6 feet of the ESS + - Rated for 200% of the ESS current correct: 1 - explanation: "Per 706.15, the disconnecting means for an energy storage system must be lockable in the open (off) position to ensure safety during maintenance." + explanation: Per 706.15, the disconnecting means for an energy storage system must be lockable in the open (off) position to ensure safety during maintenance. - id: battery-p2 type: true_false - question: "Ventilation is required for battery rooms where hydrogen gas may accumulate." - correct: "true" - explanation: "Per 706.30, ventilation must be provided for battery storage locations to prevent accumulation of potentially explosive hydrogen gas produced during charging." + question: Ventilation is required for battery rooms where hydrogen gas may accumulate. + correct: 'true' + explanation: Per 706.30, ventilation must be provided for battery storage locations to prevent accumulation of potentially explosive hydrogen gas produced during charging. - id: battery-p3 type: fill_blank - question: "ESS over ___ kWh must have a listed or field-labeled means to disconnect per 706.15(A)." - correct: "1" - explanation: "Per 706.15(A), energy storage systems over 1 kWh must have a listed or field-labeled disconnecting means." + question: ESS over ___ kWh must have a listed or field-labeled means to disconnect per 706.15(A). + correct: '1' + explanation: Per 706.15(A), energy storage systems over 1 kWh must have a listed or field-labeled disconnecting means. - id: battery-p4 type: multiple_choice - question: "Article 706 covers which of the following?" + question: Article 706 covers which of the following? options: - - "Only lithium-ion batteries" - - "Only lead-acid batteries" - - "All energy storage systems including batteries, capacitors, and other technologies" - - "Only residential battery systems" + - Only lithium-ion batteries + - Only lead-acid batteries + - All energy storage systems including batteries, capacitors, and other technologies + - Only residential battery systems correct: 2 - explanation: "Article 706 covers all energy storage systems regardless of technology, including batteries, capacitors, and other storage technologies for both residential and commercial applications." - + explanation: Article 706 covers all energy storage systems regardless of technology, including batteries, capacitors, and other storage technologies for both residential and commercial applications. + keyPrerequisite: solar-pv - id: ev-charging - name: "Article 625 — Electric Vehicle Charging" + name: Article 625 — Electric Vehicle Charging difficulty: 4 estimatedMinutes: 20 - tags: [ev-charging, article-625] - sourceRef: "NEC 2023 Article 625" + tags: + - ev-charging + - article-625 + sourceRef: NEC 2023 Article 625 prerequisites: - branch-circuits - gfci-protection knowledgePoints: - id: ev-circuit-sizing - instruction: "Article 625 covers electric vehicle supply equipment (EVSE). EV branch circuits must be sized for continuous duty -- the circuit conductors and overcurrent protection must be rated at not less than 125% of the maximum load of the EVSE (625.41). Level 1 EVSE uses a standard 120V, 15 or 20A receptacle. Level 2 EVSE typically operates at 240V, 30-50A. For a 40A EVSE, the circuit must be: 40A x 1.25 = 50A minimum. Conductor: 6 AWG copper at 75C = 65A (adequate). Breaker: 50A. Outlet boxes for EVSE must be mounted at a height of not less than 18 inches and not more than 4 feet above the floor or grade (625.26). GFCI protection for personnel is required for all EVSE (625.54)." + instruction: 'Article 625 covers electric vehicle supply equipment (EVSE). EV branch circuits must be sized for continuous duty -- the circuit conductors and overcurrent protection must be rated at not less than 125% of the maximum load of the EVSE (625.41). Level 1 EVSE uses a standard 120V, 15 or 20A receptacle. Level 2 EVSE typically operates at 240V, 30-50A. For a 40A EVSE, the circuit must be: 40A x 1.25 = 50A minimum. Conductor: 6 AWG copper at 75C = 65A (adequate). Breaker: 50A. Outlet boxes for EVSE must be mounted at a height of not less than 18 inches and not more than 4 feet above the floor or grade (625.26). GFCI protection for personnel is required for all EVSE (625.54).' problems: - id: ev-p1 type: multiple_choice - question: "A 40A Level 2 EVSE requires what minimum circuit breaker size?" + question: A 40A Level 2 EVSE requires what minimum circuit breaker size? options: - - "40 amperes" - - "45 amperes" - - "50 amperes" - - "60 amperes" + - 40 amperes + - 45 amperes + - 50 amperes + - 60 amperes correct: 2 - explanation: "Per 625.41, EV circuits are considered continuous loads and must be sized at 125%. 40A x 1.25 = 50A minimum breaker. 50A is a standard rating per 240.6(A)." + explanation: Per 625.41, EV circuits are considered continuous loads and must be sized at 125%. 40A x 1.25 = 50A minimum breaker. 50A is a standard rating per 240.6(A). - id: ev-p2 type: true_false - question: "GFCI protection is required for all electric vehicle supply equipment (EVSE)." - correct: "true" - explanation: "Per 625.54, all EVSE must have listed ground-fault circuit-interrupter protection for personnel." + question: GFCI protection is required for all electric vehicle supply equipment (EVSE). + correct: 'true' + explanation: Per 625.54, all EVSE must have listed ground-fault circuit-interrupter protection for personnel. - id: ev-p3 type: fill_blank - question: "Per 625.41, EV circuits are considered ___ loads and conductors must be sized at 125% of the EVSE maximum load." - correct: "continuous" - explanation: "Per 625.41, EV branch circuits are treated as continuous duty loads, requiring conductors and overcurrent protection rated at 125% of the maximum load." + question: Per 625.41, EV circuits are considered ___ loads and conductors must be sized at 125% of the EVSE maximum load. + correct: continuous + explanation: Per 625.41, EV branch circuits are treated as continuous duty loads, requiring conductors and overcurrent protection rated at 125% of the maximum load. - id: ev-p4 type: ordering - question: "Place these EV charging levels in order from lowest to highest power." - options: - - "Level 2 — typically 240V, 30-50A" - - "Level 1 — standard 120V, 15-20A receptacle" - - "DC Fast Charging — 200-1000V DC" - correct: "1,0,2" - explanation: "Level 1 uses a standard 120V outlet (1.4-1.9 kW), Level 2 uses 240V at 30-50A (7.2-12 kW), and DC Fast Charging operates at 200-1000V DC (50-350+ kW)." - + question: Place these EV charging levels in order from lowest to highest power. + options: + - Level 2 — typically 240V, 30-50A + - Level 1 — standard 120V, 15-20A receptacle + - DC Fast Charging — 200-1000V DC + correct: 1,0,2 + explanation: Level 1 uses a standard 120V outlet (1.4-1.9 kW), Level 2 uses 240V at 30-50A (7.2-12 kW), and DC Fast Charging operates at 200-1000V DC (50-350+ kW). + keyPrerequisite: branch-circuits - id: temporary-wiring - name: "Article 590 — Temporary Wiring" + name: Article 590 — Temporary Wiring difficulty: 3 estimatedMinutes: 15 - tags: [temporary, construction, article-590] - sourceRef: "NEC 2023 Article 590" + tags: + - temporary + - construction + - article-590 + sourceRef: NEC 2023 Article 590 prerequisites: - branch-circuits - gfci-protection knowledgePoints: - id: temp-wiring-rules - instruction: "Article 590 covers temporary electrical power and lighting during construction, renovation, maintenance, and similar activities. Temporary wiring is permitted during construction of buildings for up to 90 days for holiday displays and similar purposes. GFCI protection is required for all 125V, 15- and 20-ampere receptacle outlets used for temporary wiring on construction sites (590.6(A)). Temporary wiring can use NM cable, MC cable, or approved cord connectors. Lamp holders must be equipped with guards (590.4(F)). All temporary wiring must be removed immediately upon completion of construction or purpose." + instruction: Article 590 covers temporary electrical power and lighting during construction, renovation, maintenance, and similar activities. Temporary wiring is permitted during construction of buildings for up to 90 days for holiday displays and similar purposes. GFCI protection is required for all 125V, 15- and 20-ampere receptacle outlets used for temporary wiring on construction sites (590.6(A)). Temporary wiring can use NM cable, MC cable, or approved cord connectors. Lamp holders must be equipped with guards (590.4(F)). All temporary wiring must be removed immediately upon completion of construction or purpose. problems: - id: temp-p1 type: true_false - question: "GFCI protection is required for all 125V, 15 and 20A receptacles on construction sites." - correct: "true" - explanation: "Per 590.6(A), all 125-volt, single-phase, 15- and 20-ampere receptacle outlets used for temporary wiring on construction sites must have GFCI protection." + question: GFCI protection is required for all 125V, 15 and 20A receptacles on construction sites. + correct: 'true' + explanation: Per 590.6(A), all 125-volt, single-phase, 15- and 20-ampere receptacle outlets used for temporary wiring on construction sites must have GFCI protection. - id: temp-p2 type: true_false - question: "Temporary wiring must be removed immediately upon completion of construction or purpose." - correct: "true" - explanation: "Per 590.3(D), temporary wiring must be removed immediately upon completion of construction or purpose for which the wiring was installed." + question: Temporary wiring must be removed immediately upon completion of construction or purpose. + correct: 'true' + explanation: Per 590.3(D), temporary wiring must be removed immediately upon completion of construction or purpose for which the wiring was installed. - id: temp-p3 type: fill_blank - question: "Temporary wiring for holiday displays is permitted for up to ___ days per 590.3(B)." - correct: "90" - explanation: "Per 590.3(B), temporary electrical power and lighting is permitted for up to 90 days for holiday decorative lighting and similar purposes." + question: Temporary wiring for holiday displays is permitted for up to ___ days per 590.3(B). + correct: '90' + explanation: Per 590.3(B), temporary electrical power and lighting is permitted for up to 90 days for holiday decorative lighting and similar purposes. - id: temp-p4 type: multiple_choice - question: "Per 590.4(F), temporary lampholders on construction sites must be equipped with:" + question: 'Per 590.4(F), temporary lampholders on construction sites must be equipped with:' options: - - "GFCI protection only" - - "Guards" - - "Dimmer switches" - - "Motion sensors" + - GFCI protection only + - Guards + - Dimmer switches + - Motion sensors correct: 1 - explanation: "Per 590.4(F), all lamps for general illumination in temporary installations must be protected from accidental contact or breakage by a suitable luminaire or lampholder with a guard." - + explanation: Per 590.4(F), all lamps for general illumination in temporary installations must be protected from accidental contact or breakage by a suitable luminaire or lampholder with a guard. + keyPrerequisite: gfci-protection - id: manufactured-homes - name: "Article 550 — Manufactured (Mobile) Homes" + name: Article 550 — Manufactured (Mobile) Homes difficulty: 4 estimatedMinutes: 15 - tags: [manufactured-homes, article-550] - sourceRef: "NEC 2023 Article 550" + tags: + - manufactured-homes + - article-550 + sourceRef: NEC 2023 Article 550 prerequisites: - service-entrance - dwelling-load-calculations knowledgePoints: - id: manufactured-service - instruction: "Article 550 covers manufactured homes (mobile homes). The power supply to a manufactured home must be a single feeder from a distribution panelboard or from the service equipment to the manufactured home disconnecting means (550.10). The feeder conductors must be sized per Article 220 load calculations. The manufactured home must have a permanently installed disconnect that is readily accessible and located in sight from the home (550.11). The minimum supply conductor size is based on the calculated load but not less than 100A for a manufactured home (550.10(A)). A grounding electrode must be installed at each manufactured home site (550.16)." + instruction: Article 550 covers manufactured homes (mobile homes). The power supply to a manufactured home must be a single feeder from a distribution panelboard or from the service equipment to the manufactured home disconnecting means (550.10). The feeder conductors must be sized per Article 220 load calculations. The manufactured home must have a permanently installed disconnect that is readily accessible and located in sight from the home (550.11). The minimum supply conductor size is based on the calculated load but not less than 100A for a manufactured home (550.10(A)). A grounding electrode must be installed at each manufactured home site (550.16). problems: - id: mfg-p1 type: multiple_choice - question: "What is the minimum supply conductor rating for a manufactured home?" + question: What is the minimum supply conductor rating for a manufactured home? options: - - "60 amperes" - - "80 amperes" - - "100 amperes" - - "125 amperes" + - 60 amperes + - 80 amperes + - 100 amperes + - 125 amperes correct: 2 - explanation: "Per 550.10(A), the power supply to a manufactured home must have a rating of not less than 100 amperes." + explanation: Per 550.10(A), the power supply to a manufactured home must have a rating of not less than 100 amperes. - id: mfg-p2 type: true_false - question: "A grounding electrode must be installed at each manufactured home site." - correct: "true" - explanation: "Per 550.16, a grounding electrode must be installed at each manufactured home site and connected to the equipment grounding bus in the manufactured home." + question: A grounding electrode must be installed at each manufactured home site. + correct: 'true' + explanation: Per 550.16, a grounding electrode must be installed at each manufactured home site and connected to the equipment grounding bus in the manufactured home. - id: mfg-p3 type: fill_blank - question: "The minimum supply conductor rating for a manufactured home is ___ amperes per 550.10(A)." - correct: "100" - explanation: "Per 550.10(A), the power supply to a manufactured home must have a rating of not less than 100 amperes." + question: The minimum supply conductor rating for a manufactured home is ___ amperes per 550.10(A). + correct: '100' + explanation: Per 550.10(A), the power supply to a manufactured home must have a rating of not less than 100 amperes. - id: mfg-p4 type: true_false - question: "The manufactured home disconnect must be located in sight from and readily accessible to the home per 550.11." - correct: "true" - explanation: "Per 550.11, the manufactured home must have a permanently installed disconnect that is readily accessible and located in sight from the home." - - # ============================================================ - # ADVANCED CALCULATIONS & SIZING - # ============================================================ - + question: The manufactured home disconnect must be located in sight from and readily accessible to the home per 550.11. + correct: 'true' + explanation: Per 550.11, the manufactured home must have a permanently installed disconnect that is readily accessible and located in sight from the home. + keyPrerequisite: service-entrance - id: commercial-load-calc - name: "Article 220 Part IV — Commercial Load Calculations" + name: Article 220 Part IV — Commercial Load Calculations difficulty: 7 estimatedMinutes: 30 - tags: [load-calculations, commercial, article-220] - sourceRef: "NEC 2023 Article 220, Parts I-IV" + tags: + - load-calculations + - commercial + - article-220 + sourceRef: NEC 2023 Article 220, Parts I-IV prerequisites: - dwelling-load-calculations knowledgePoints: - id: commercial-lighting - instruction: "Commercial lighting loads use Table 220.12 with different unit loads by occupancy: office buildings = 3.5 VA/sq ft, retail stores = 1.5 VA/sq ft, restaurants = 2 VA/sq ft, warehouses = 0.5 VA/sq ft, schools = 3 VA/sq ft, hospitals = 2 VA/sq ft. Table 220.42 demand factors for lighting: for hospitals, hotels, and motels, the first 50,000 VA at 40% and remainder at 20%. For all others (not dwellings), the first 12,500 VA at 100% and remainder at 50%. Receptacle loads in commercial buildings: per 220.44, the first 10 kVA at 100% and the remainder at 50%. Show-window lighting is calculated at 200 VA per linear foot (220.43(A))." + instruction: 'Commercial lighting loads use Table 220.12 with different unit loads by occupancy: office buildings = 3.5 VA/sq ft, retail stores = 1.5 VA/sq ft, restaurants = 2 VA/sq ft, warehouses = 0.5 VA/sq ft, schools = 3 VA/sq ft, hospitals = 2 VA/sq ft. Table 220.42 demand factors for lighting: for hospitals, hotels, and motels, the first 50,000 VA at 40% and remainder at 20%. For all others (not dwellings), the first 12,500 VA at 100% and remainder at 50%. Receptacle loads in commercial buildings: per 220.44, the first 10 kVA at 100% and the remainder at 50%. Show-window lighting is calculated at 200 VA per linear foot (220.43(A)).' problems: - id: comm-load-p1 type: multiple_choice - question: "Per Table 220.12, what is the unit load for general lighting in an office building?" + question: Per Table 220.12, what is the unit load for general lighting in an office building? options: - - "1.5 VA per square foot" - - "2 VA per square foot" - - "3 VA per square foot" - - "3.5 VA per square foot" + - 1.5 VA per square foot + - 2 VA per square foot + - 3 VA per square foot + - 3.5 VA per square foot correct: 3 - explanation: "Per Table 220.12, the unit load for general lighting in office buildings is 3.5 VA per square foot." + explanation: Per Table 220.12, the unit load for general lighting in office buildings is 3.5 VA per square foot. - id: comm-load-p2 type: multiple_choice - question: "Per 220.44, what demand factor applies to the first 10 kVA of receptacle load in a commercial building?" + question: Per 220.44, what demand factor applies to the first 10 kVA of receptacle load in a commercial building? options: - - "50%" - - "75%" - - "80%" - - "100%" + - 50% + - 75% + - 80% + - 100% correct: 3 - explanation: "Per 220.44, for multioutlet receptacle loads in other than dwelling units, the first 10 kVA is calculated at 100% demand factor, with the remainder at 50%." + explanation: Per 220.44, for multioutlet receptacle loads in other than dwelling units, the first 10 kVA is calculated at 100% demand factor, with the remainder at 50%. - id: comm-load-p3 type: fill_blank - question: "Per 220.43(A), show-window lighting is calculated at ___ VA per linear foot." - correct: "200" - explanation: "Per 220.43(A), show-window lighting loads must be calculated at a minimum of 200 VA per linear foot of show window." + question: Per 220.43(A), show-window lighting is calculated at ___ VA per linear foot. + correct: '200' + explanation: Per 220.43(A), show-window lighting loads must be calculated at a minimum of 200 VA per linear foot of show window. - id: comm-load-p4 type: matching - question: "Match each commercial occupancy with its lighting unit load per Table 220.12." - options: - - "Office building|3.5 VA/sq ft" - - "Retail store|1.5 VA/sq ft" - - "Warehouse|0.5 VA/sq ft" - - "Restaurant|2 VA/sq ft" - correct: "0,1,2,3" - explanation: "Table 220.12 assigns different unit loads based on occupancy type. Offices are highest at 3.5, restaurants at 2, retail at 1.5, and warehouses lowest at 0.5 VA per square foot." - + question: Match each commercial occupancy with its lighting unit load per Table 220.12. + options: + - Office building|3.5 VA/sq ft + - Retail store|1.5 VA/sq ft + - Warehouse|0.5 VA/sq ft + - Restaurant|2 VA/sq ft + correct: 0,1,2,3 + explanation: Table 220.12 assigns different unit loads based on occupancy type. Offices are highest at 3.5, restaurants at 2, retail at 1.5, and warehouses lowest at 0.5 VA per square foot. + keyPrerequisite: dwelling-load-calculations - id: demand-factors - name: "Article 220 Tables — Demand Factors" + name: Article 220 Tables — Demand Factors difficulty: 6 estimatedMinutes: 20 - tags: [demand-factors, load-calculations, article-220] - sourceRef: "NEC 2023 Article 220" + tags: + - demand-factors + - load-calculations + - article-220 + sourceRef: NEC 2023 Article 220 prerequisites: - commercial-load-calc knowledgePoints: - id: demand-factor-tables - instruction: "Key demand factor tables: Table 220.42 (Lighting) -- dwelling: first 3,000 VA at 100%, remainder at 35%. Table 220.54 (Dryers) -- dwelling: minimum 5,000 VA or nameplate, whichever is larger; demand factors for multiple dryers. Table 220.55 (Ranges) -- single range up to 12 kW = 8 kW demand; for multiple ranges, Column A gives demand percentage of nameplate. Table 220.56 (Kitchen Equipment, non-dwelling) -- 3 units at 90%, 4 at 80%, 5 at 70%, 6+ at 65%. Table 220.84 (Optional calculation for multifamily dwellings) allows significant load reduction for buildings with 3+ units: first 3 VA/sq ft at 100% for lighting, plus nameplate for appliances, then total gets demand factor based on number of units." + instruction: 'Key demand factor tables: Table 220.42 (Lighting) -- dwelling: first 3,000 VA at 100%, remainder at 35%. Table 220.54 (Dryers) -- dwelling: minimum 5,000 VA or nameplate, whichever is larger; demand factors for multiple dryers. Table 220.55 (Ranges) -- single range up to 12 kW = 8 kW demand; for multiple ranges, Column A gives demand percentage of nameplate. Table 220.56 (Kitchen Equipment, non-dwelling) -- 3 units at 90%, 4 at 80%, 5 at 70%, 6+ at 65%. Table 220.84 (Optional calculation for multifamily dwellings) allows significant load reduction for buildings with 3+ units: first 3 VA/sq ft at 100% for lighting, plus nameplate for appliances, then total gets demand factor based on number of units.' problems: - id: demand-p1 type: multiple_choice - question: "Per Table 220.56, the demand factor for 6 or more pieces of commercial kitchen equipment is:" + question: 'Per Table 220.56, the demand factor for 6 or more pieces of commercial kitchen equipment is:' options: - - "50%" - - "65%" - - "75%" - - "80%" + - 50% + - 65% + - 75% + - 80% correct: 1 - explanation: "Per Table 220.56, for 6 or more pieces of commercial kitchen equipment, the demand factor is 65% of the nameplate rating." + explanation: Per Table 220.56, for 6 or more pieces of commercial kitchen equipment, the demand factor is 65% of the nameplate rating. - id: demand-p2 type: multiple_choice - question: "Per Table 220.56, the demand factor for 3 pieces of commercial kitchen equipment is:" + question: 'Per Table 220.56, the demand factor for 3 pieces of commercial kitchen equipment is:' options: - - "75%" - - "80%" - - "90%" - - "100%" + - 75% + - 80% + - 90% + - 100% correct: 2 - explanation: "Per Table 220.56, for 3 pieces of commercial kitchen equipment, the demand factor is 90%." + explanation: Per Table 220.56, for 3 pieces of commercial kitchen equipment, the demand factor is 90%. - id: demand-p3 type: multiple_choice - question: "Per Table 220.42, for commercial buildings (other than dwellings/hotels), the lighting demand factor for loads above 12,500 VA is:" + question: 'Per Table 220.42, for commercial buildings (other than dwellings/hotels), the lighting demand factor for loads above 12,500 VA is:' options: - - "35%" - - "40%" - - "50%" - - "75%" + - 35% + - 40% + - 50% + - 75% correct: 2 - explanation: "Per Table 220.42, for all occupancies except dwelling units and hotels/motels, the first 12,500 VA is at 100% demand, and the remainder over 12,500 VA is at 50%." + explanation: Per Table 220.42, for all occupancies except dwelling units and hotels/motels, the first 12,500 VA is at 100% demand, and the remainder over 12,500 VA is at 50%. - id: demand-p4 type: fill_blank - question: "Per Table 220.55, the maximum demand for a single household range rated not more than 12 kW is ___ kW." - correct: "8" - explanation: "Per Table 220.55 Column C, a single household electric range rated not more than 12 kW has a maximum demand of 8 kW." - + question: Per Table 220.55, the maximum demand for a single household range rated not more than 12 kW is ___ kW. + correct: '8' + explanation: Per Table 220.55 Column C, a single household electric range rated not more than 12 kW has a maximum demand of 8 kW. + keyPrerequisite: commercial-load-calc - id: voltage-drop - name: "Voltage Drop Calculations" + name: Voltage Drop Calculations difficulty: 6 estimatedMinutes: 25 - tags: [voltage-drop, calculations, chapter-9] - sourceRef: "NEC 2023 Informational Notes 210.19(A)(1), 215.2(A)(4)" + tags: + - voltage-drop + - calculations + - chapter-9 + sourceRef: NEC 2023 Informational Notes 210.19(A)(1), 215.2(A)(4) prerequisites: - conductor-sizing - feeders knowledgePoints: - id: vd-calculations - instruction: "While not a mandatory code requirement, the NEC recommends (Informational Notes to 210.19(A)(1) and 215.2(A)(4)) that voltage drop not exceed 3% for branch circuits and 5% total for feeder plus branch circuit combined. The voltage drop formula for single-phase circuits: VD = (2 x K x I x D) / CM, where K = resistivity constant (12.9 for copper, 21.2 for aluminum), I = current in amps, D = one-way distance in feet, CM = circular mil area of conductor. For three-phase: VD = (1.732 x K x I x D) / CM. Alternatively, use Chapter 9, Table 9 for conductor resistance per 1000 feet and calculate: VD = I x R x L (with appropriate multiplier for single-phase or three-phase)." - workedExample: "Example: What is the voltage drop for a 120V, 20A, single-phase circuit using 12 AWG copper (6530 CM) with a 100-foot one-way run? VD = (2 x 12.9 x 20 x 100) / 6530 = 51,600 / 6530 = 7.9V. Percent VD = 7.9/120 = 6.6%. This exceeds the recommended 3%, so upsizing to 10 AWG (10380 CM) gives: VD = 51,600 / 10380 = 4.97V = 4.1%. Still above 3%. Use 8 AWG (16510 CM): VD = 51,600 / 16510 = 3.13V = 2.6%. This meets the 3% recommendation." + instruction: 'While not a mandatory code requirement, the NEC recommends (Informational Notes to 210.19(A)(1) and 215.2(A)(4)) that voltage drop not exceed 3% for branch circuits and 5% total for feeder plus branch circuit combined. The voltage drop formula for single-phase circuits: VD = (2 x K x I x D) / CM, where K = resistivity constant (12.9 for copper, 21.2 for aluminum), I = current in amps, D = one-way distance in feet, CM = circular mil area of conductor. For three-phase: VD = (1.732 x K x I x D) / CM. Alternatively, use Chapter 9, Table 9 for conductor resistance per 1000 feet and calculate: VD = I x R x L (with appropriate multiplier for single-phase or three-phase).' + workedExample: 'Example: What is the voltage drop for a 120V, 20A, single-phase circuit using 12 AWG copper (6530 CM) with a 100-foot one-way run? VD = (2 x 12.9 x 20 x 100) / 6530 = 51,600 / 6530 = 7.9V. Percent VD = 7.9/120 = 6.6%. This exceeds the recommended 3%, so upsizing to 10 AWG (10380 CM) gives: VD = 51,600 / 10380 = 4.97V = 4.1%. Still above 3%. Use 8 AWG (16510 CM): VD = 51,600 / 16510 = 3.13V = 2.6%. This meets the 3% recommendation.' problems: - id: vd-p1 type: multiple_choice - question: "The NEC recommends that total voltage drop for a feeder and branch circuit combined should not exceed:" + question: 'The NEC recommends that total voltage drop for a feeder and branch circuit combined should not exceed:' options: - - "2%" - - "3%" - - "5%" - - "10%" + - 2% + - 3% + - 5% + - 10% correct: 2 - explanation: "Per the Informational Notes to 210.19(A)(1) and 215.2(A)(4), the NEC recommends no more than 3% voltage drop for the branch circuit and no more than 5% total for the feeder plus branch circuit combined." + explanation: Per the Informational Notes to 210.19(A)(1) and 215.2(A)(4), the NEC recommends no more than 3% voltage drop for the branch circuit and no more than 5% total for the feeder plus branch circuit combined. - id: vd-p2 type: multiple_choice - question: "In the voltage drop formula VD = (2 x K x I x D) / CM, what does K represent for copper conductors?" + question: In the voltage drop formula VD = (2 x K x I x D) / CM, what does K represent for copper conductors? options: - - "10.8" - - "12.9" - - "17.0" - - "21.2" + - '10.8' + - '12.9' + - '17.0' + - '21.2' correct: 1 - explanation: "K is the resistivity constant. For copper conductors, K = 12.9 ohms per mil-foot. For aluminum, K = 21.2." + explanation: K is the resistivity constant. For copper conductors, K = 12.9 ohms per mil-foot. For aluminum, K = 21.2. - id: vd-p3 type: fill_blank - question: "The NEC recommends that voltage drop for a branch circuit alone should not exceed ___% per the Informational Note to 210.19(A)(1)." - correct: "3" - explanation: "Per the Informational Note to 210.19(A)(1), branch circuit voltage drop should not exceed 3%, and the total of feeder plus branch circuit should not exceed 5%." + question: The NEC recommends that voltage drop for a branch circuit alone should not exceed ___% per the Informational Note to 210.19(A)(1). + correct: '3' + explanation: Per the Informational Note to 210.19(A)(1), branch circuit voltage drop should not exceed 3%, and the total of feeder plus branch circuit should not exceed 5%. - id: vd-p4 type: true_false - question: "The NEC voltage drop recommendations of 3% branch circuit and 5% total are mandatory code requirements." - correct: "false" - explanation: "Voltage drop recommendations are contained in Informational Notes to 210.19(A)(1) and 215.2(A)(4). Informational Notes are not enforceable code requirements -- they are recommendations for a reasonably efficient installation." - + question: The NEC voltage drop recommendations of 3% branch circuit and 5% total are mandatory code requirements. + correct: 'false' + explanation: Voltage drop recommendations are contained in Informational Notes to 210.19(A)(1) and 215.2(A)(4). Informational Notes are not enforceable code requirements -- they are recommendations for a reasonably efficient installation. + keyPrerequisite: conductor-sizing - id: panelboard-requirements - name: "Article 408 — Panelboards and Switchboards" + name: Article 408 — Panelboards and Switchboards difficulty: 4 estimatedMinutes: 20 - tags: [panelboards, article-408] - sourceRef: "NEC 2023 Article 408" + tags: + - panelboards + - article-408 + sourceRef: NEC 2023 Article 408 prerequisites: - overcurrent-protection - service-entrance knowledgePoints: - id: panelboard-rules - instruction: "Article 408 covers switchboards, switchgear, and panelboards. A panelboard must have a rating not less than the minimum feeder capacity required for the calculated load (408.36). All panelboards must have overcurrent protection with a rating not more than the panelboard rating (408.36(A)). Panelboards in dwelling units must have overcurrent protection not more than 200A per individual panelboard (408.36(B) exception). The number of overcurrent devices on a panelboard is limited by the panelboard listing. Phase arrangement must be such that the load is balanced between phases (408.40). In a 3-phase panel, breaker numbering follows: odd numbers on the left (1, 3, 5...) and even on the right (2, 4, 6...). Phases rotate: A-B-C down the left side." + instruction: 'Article 408 covers switchboards, switchgear, and panelboards. A panelboard must have a rating not less than the minimum feeder capacity required for the calculated load (408.36). All panelboards must have overcurrent protection with a rating not more than the panelboard rating (408.36(A)). Panelboards in dwelling units must have overcurrent protection not more than 200A per individual panelboard (408.36(B) exception). The number of overcurrent devices on a panelboard is limited by the panelboard listing. Phase arrangement must be such that the load is balanced between phases (408.40). In a 3-phase panel, breaker numbering follows: odd numbers on the left (1, 3, 5...) and even on the right (2, 4, 6...). Phases rotate: A-B-C down the left side.' problems: - id: panel-p1 type: multiple_choice - question: "Per 408.36, a panelboard must have overcurrent protection rated at:" + question: 'Per 408.36, a panelboard must have overcurrent protection rated at:' options: - - "Not more than the panelboard rating" - - "125% of the largest circuit in the panel" - - "At least twice the main breaker rating" - - "Not more than 400 amperes" + - Not more than the panelboard rating + - 125% of the largest circuit in the panel + - At least twice the main breaker rating + - Not more than 400 amperes correct: 0 - explanation: "Per 408.36(A), a panelboard must be protected by an overcurrent protective device having a rating not greater than that of the panelboard." + explanation: Per 408.36(A), a panelboard must be protected by an overcurrent protective device having a rating not greater than that of the panelboard. - id: panel-p2 type: multiple_choice - question: "In a 3-phase panel, which phase is on positions 1, 3, and 5?" + question: In a 3-phase panel, which phase is on positions 1, 3, and 5? options: - - "Phase A" - - "Phase B" - - "Phase C" - - "It varies by manufacturer" + - Phase A + - Phase B + - Phase C + - It varies by manufacturer correct: 0 - explanation: "In a standard 3-phase panel, Phase A occupies the first position on each side (positions 1, 3, 5 on the left), Phase B occupies positions 2, 4, 6, and Phase C occupies positions 3, 5, 7 (rotating A-B-C pattern)." + explanation: In a standard 3-phase panel, Phase A occupies the first position on each side (positions 1, 3, 5 on the left), Phase B occupies positions 2, 4, 6, and Phase C occupies positions 3, 5, 7 (rotating A-B-C pattern). - id: panel-p3 type: fill_blank - question: "Per 408.40, panelboard loads must be balanced between ___." - correct: "phases" - explanation: "Per 408.40, the phase arrangement on 3-phase buses must be such that the load is balanced between phases as closely as practicable." + question: Per 408.40, panelboard loads must be balanced between ___. + correct: phases + explanation: Per 408.40, the phase arrangement on 3-phase buses must be such that the load is balanced between phases as closely as practicable. - id: panel-p4 type: true_false - question: "A panelboard's overcurrent protection can exceed the panelboard's rating." - correct: "false" - explanation: "Per 408.36(A), a panelboard must be protected by an overcurrent protective device having a rating not greater than that of the panelboard." - + question: A panelboard's overcurrent protection can exceed the panelboard's rating. + correct: 'false' + explanation: Per 408.36(A), a panelboard must be protected by an overcurrent protective device having a rating not greater than that of the panelboard. + keyPrerequisite: overcurrent-protection - id: disconnect-requirements - name: "Article 404/430 — Disconnect Rules" + name: Article 404/430 — Disconnect Rules difficulty: 4 estimatedMinutes: 15 - tags: [disconnects, article-404, article-430] - sourceRef: "NEC 2023 Articles 404, 430" + tags: + - disconnects + - article-404 + - article-430 + sourceRef: NEC 2023 Articles 404, 430 prerequisites: - switches-controls - motors-article-430 knowledgePoints: - id: disconnect-rules - instruction: "Every building or structure must have a means of disconnecting all ungrounded conductors from the service equipment (230.70). Disconnects must be installed at a readily accessible location nearest the point of entrance of the service conductors (230.70(A)). For motor circuits, a disconnecting means must be located in sight from the motor location and the controller (430.102). 'In sight' means visible and not more than 50 feet away (Article 100 definition). The motor disconnect must be rated at least 115% of the motor nameplate full-load current (430.110(A)). A disconnect is also required for all permanently connected appliances (422.31-422.34)." + instruction: Every building or structure must have a means of disconnecting all ungrounded conductors from the service equipment (230.70). Disconnects must be installed at a readily accessible location nearest the point of entrance of the service conductors (230.70(A)). For motor circuits, a disconnecting means must be located in sight from the motor location and the controller (430.102). 'In sight' means visible and not more than 50 feet away (Article 100 definition). The motor disconnect must be rated at least 115% of the motor nameplate full-load current (430.110(A)). A disconnect is also required for all permanently connected appliances (422.31-422.34). problems: - id: disc-p1 type: multiple_choice - question: "Per Article 100, 'in sight from' means visible and not more than what distance?" + question: Per Article 100, 'in sight from' means visible and not more than what distance? options: - - "25 feet" - - "35 feet" - - "50 feet" - - "75 feet" + - 25 feet + - 35 feet + - 50 feet + - 75 feet correct: 2 - explanation: "Per Article 100, 'In Sight From' (within sight from, within sight) means that the item is visible and not more than 50 feet (15 m) distant from the other." + explanation: Per Article 100, 'In Sight From' (within sight from, within sight) means that the item is visible and not more than 50 feet (15 m) distant from the other. - id: disc-p2 type: multiple_choice - question: "A motor disconnect must be rated at least what percentage of the motor nameplate full-load current?" + question: A motor disconnect must be rated at least what percentage of the motor nameplate full-load current? options: - - "100%" - - "110%" - - "115%" - - "125%" + - 100% + - 110% + - 115% + - 125% correct: 2 - explanation: "Per 430.110(A), the motor disconnecting means must have an ampere rating of not less than 115% of the full-load current rating of the motor." + explanation: Per 430.110(A), the motor disconnecting means must have an ampere rating of not less than 115% of the full-load current rating of the motor. - id: disc-p3 type: fill_blank - question: "Per Article 100, 'in sight from' means visible and not more than ___ feet distant." - correct: "50" - explanation: "Per Article 100, 'In Sight From' means the equipment is visible and not more than 50 feet (15 m) distant from the other equipment." + question: Per Article 100, 'in sight from' means visible and not more than ___ feet distant. + correct: '50' + explanation: Per Article 100, 'In Sight From' means the equipment is visible and not more than 50 feet (15 m) distant from the other equipment. - id: disc-p4 type: true_false - question: "A disconnect is required for all permanently connected appliances per Articles 422.31-422.34." - correct: "true" - explanation: "Per 422.31-422.34, each permanently connected appliance must have a means of disconnection. The specific requirements depend on the appliance rating and whether it is in sight from the appliance." - + question: A disconnect is required for all permanently connected appliances per Articles 422.31-422.34. + correct: 'true' + explanation: Per 422.31-422.34, each permanently connected appliance must have a means of disconnection. The specific requirements depend on the appliance rating and whether it is in sight from the appliance. + keyPrerequisite: motors-article-430 - id: luminaire-installation - name: "Article 410 — Luminaires (Lighting Fixtures)" + name: Article 410 — Luminaires (Lighting Fixtures) difficulty: 3 estimatedMinutes: 15 - tags: [luminaires, article-410] - sourceRef: "NEC 2023 Article 410" + tags: + - luminaires + - article-410 + sourceRef: NEC 2023 Article 410 prerequisites: - branch-circuits knowledgePoints: - id: luminaire-rules - instruction: "Article 410 covers luminaire (lighting fixture) installation. Luminaires in clothes closets must be surface-mounted or recessed incandescent or LED, completely enclosed, and must maintain clearances: 12 inches from the nearest point of storage for surface-mounted or recessed (410.16(C)). Pendant luminaires and open or partially enclosed incandescent luminaires are NOT permitted in clothes closets. In bathrooms, luminaires must be identified for damp/wet locations as applicable (410.10(D)). Recessed luminaires must have clearance from combustible materials of at least 1/2 inch (410.116(A)) and thermal protection (410.115(C)). Track lighting is covered in 410.151-160, with a limit of one track-lighting system per branch circuit." + instruction: 'Article 410 covers luminaire (lighting fixture) installation. Luminaires in clothes closets must be surface-mounted or recessed incandescent or LED, completely enclosed, and must maintain clearances: 12 inches from the nearest point of storage for surface-mounted or recessed (410.16(C)). Pendant luminaires and open or partially enclosed incandescent luminaires are NOT permitted in clothes closets. In bathrooms, luminaires must be identified for damp/wet locations as applicable (410.10(D)). Recessed luminaires must have clearance from combustible materials of at least 1/2 inch (410.116(A)) and thermal protection (410.115(C)). Track lighting is covered in 410.151-160, with a limit of one track-lighting system per branch circuit.' problems: - id: lum-p1 type: multiple_choice - question: "What is the minimum clearance from storage for a surface-mounted luminaire in a clothes closet?" + question: What is the minimum clearance from storage for a surface-mounted luminaire in a clothes closet? options: - - "6 inches" - - "12 inches" - - "18 inches" - - "24 inches" + - 6 inches + - 12 inches + - 18 inches + - 24 inches correct: 1 - explanation: "Per 410.16(C)(3), surface-mounted fluorescent or LED luminaires in clothes closets must maintain a clearance of at least 12 inches from the nearest point of a storage space." + explanation: Per 410.16(C)(3), surface-mounted fluorescent or LED luminaires in clothes closets must maintain a clearance of at least 12 inches from the nearest point of a storage space. - id: lum-p2 type: true_false - question: "Pendant luminaires are permitted in clothes closets." - correct: "false" - explanation: "Per 410.16(B), pendant luminaires and open or partially enclosed incandescent luminaires are not permitted in clothes closets." + question: Pendant luminaires are permitted in clothes closets. + correct: 'false' + explanation: Per 410.16(B), pendant luminaires and open or partially enclosed incandescent luminaires are not permitted in clothes closets. - id: lum-p3 type: fill_blank - question: "Per 410.116(A), recessed luminaires must maintain a clearance from combustible materials of at least ___ inch." - correct: "1/2" - explanation: "Per 410.116(A), recessed luminaires installed in combustible materials must have a clearance of at least 1/2 inch from the combustible material." + question: Per 410.116(A), recessed luminaires must maintain a clearance from combustible materials of at least ___ inch. + correct: 1/2 + explanation: Per 410.116(A), recessed luminaires installed in combustible materials must have a clearance of at least 1/2 inch from the combustible material. - id: lum-p4 type: multiple_choice - question: "In a bathroom, luminaires must be identified for which type of location?" + question: In a bathroom, luminaires must be identified for which type of location? options: - - "Dry location only" - - "Damp or wet location as applicable" - - "Hazardous location" - - "No special identification required" + - Dry location only + - Damp or wet location as applicable + - Hazardous location + - No special identification required correct: 1 - explanation: "Per 410.10(D), luminaires in bathrooms must be identified for damp locations, or wet locations if subject to shower spray or similar wetting." - + explanation: Per 410.10(D), luminaires in bathrooms must be identified for damp locations, or wet locations if subject to shower spray or similar wetting. + keyPrerequisite: branch-circuits - id: outdoor-wiring - name: "Article 225 — Outside Branch Circuits and Feeders" + name: Article 225 — Outside Branch Circuits and Feeders difficulty: 4 estimatedMinutes: 15 - tags: [outdoor, article-225] - sourceRef: "NEC 2023 Article 225" + tags: + - outdoor + - article-225 + sourceRef: NEC 2023 Article 225 prerequisites: - feeders - wiring-methods-overview knowledgePoints: - id: outdoor-rules - instruction: "Article 225 covers outside branch circuits and feeders. Overhead conductor clearances per 225.18: above finished grade (sidewalks, platforms) not less than 10 feet; above residential driveways not less than 12 feet; above commercial driveways, parking areas, and agricultural areas not less than 18 feet. Above rooftop: not less than 8 feet from the roof surface (225.19(A)), with a reduction to 3 feet if the voltage is 300V or less and the roof slope is 4/12 or greater. Each building or structure served by outside branch circuits or feeders must have a disconnecting means (225.31) installed at a readily accessible location, nearest the point of entrance, on the exterior or interior of the building (225.32)." + instruction: 'Article 225 covers outside branch circuits and feeders. Overhead conductor clearances per 225.18: above finished grade (sidewalks, platforms) not less than 10 feet; above residential driveways not less than 12 feet; above commercial driveways, parking areas, and agricultural areas not less than 18 feet. Above rooftop: not less than 8 feet from the roof surface (225.19(A)), with a reduction to 3 feet if the voltage is 300V or less and the roof slope is 4/12 or greater. Each building or structure served by outside branch circuits or feeders must have a disconnecting means (225.31) installed at a readily accessible location, nearest the point of entrance, on the exterior or interior of the building (225.32).' problems: - id: outdoor-p1 type: multiple_choice - question: "Per 225.18, what is the minimum clearance for overhead conductors above a residential driveway?" + question: Per 225.18, what is the minimum clearance for overhead conductors above a residential driveway? options: - - "8 feet" - - "10 feet" - - "12 feet" - - "18 feet" + - 8 feet + - 10 feet + - 12 feet + - 18 feet correct: 2 - explanation: "Per 225.18(3), overhead conductors must maintain a clearance of not less than 12 feet above residential property and driveways." + explanation: Per 225.18(3), overhead conductors must maintain a clearance of not less than 12 feet above residential property and driveways. - id: outdoor-p2 type: multiple_choice - question: "Per 225.18, what is the minimum clearance for overhead conductors above a commercial parking area?" + question: Per 225.18, what is the minimum clearance for overhead conductors above a commercial parking area? options: - - "10 feet" - - "12 feet" - - "15 feet" - - "18 feet" + - 10 feet + - 12 feet + - 15 feet + - 18 feet correct: 3 - explanation: "Per 225.18(4), overhead conductors above public streets, alleys, roads, parking areas subject to truck traffic, driveways on other than residential property, and similar areas must have a minimum clearance of 18 feet." + explanation: Per 225.18(4), overhead conductors above public streets, alleys, roads, parking areas subject to truck traffic, driveways on other than residential property, and similar areas must have a minimum clearance of 18 feet. - id: outdoor-p3 type: multiple_choice - question: "Per 225.18, what is the minimum clearance for overhead conductors above finished grade (pedestrian areas)?" + question: Per 225.18, what is the minimum clearance for overhead conductors above finished grade (pedestrian areas)? options: - - "8 feet" - - "10 feet" - - "12 feet" - - "15 feet" + - 8 feet + - 10 feet + - 12 feet + - 15 feet correct: 1 - explanation: "Per 225.18(1), the minimum clearance above finished grade, sidewalks, or from any platform or projection from which the conductors might be reached is 10 feet." + explanation: Per 225.18(1), the minimum clearance above finished grade, sidewalks, or from any platform or projection from which the conductors might be reached is 10 feet. - id: outdoor-p4 type: ordering - question: "Place these overhead conductor clearance requirements from lowest to highest per 225.18." - options: - - "Above commercial driveways/parking — 18 feet" - - "Above finished grade/sidewalks — 10 feet" - - "Above residential driveways — 12 feet" - correct: "1,2,0" - explanation: "Per 225.18: pedestrian areas = 10 feet, residential driveways = 12 feet, commercial driveways/parking = 18 feet." - + question: Place these overhead conductor clearance requirements from lowest to highest per 225.18. + options: + - Above commercial driveways/parking — 18 feet + - Above finished grade/sidewalks — 10 feet + - Above residential driveways — 12 feet + correct: 1,2,0 + explanation: 'Per 225.18: pedestrian areas = 10 feet, residential driveways = 12 feet, commercial driveways/parking = 18 feet.' + keyPrerequisite: feeders - id: cable-tray - name: "Article 392 — Cable Tray Systems" + name: Article 392 — Cable Tray Systems difficulty: 4 estimatedMinutes: 15 - tags: [cable-tray, article-392] - sourceRef: "NEC 2023 Article 392" + tags: + - cable-tray + - article-392 + sourceRef: NEC 2023 Article 392 prerequisites: - wiring-methods-overview knowledgePoints: - id: cable-tray-rules - instruction: "Article 392 covers cable tray systems. Cable trays are permitted as a support system for cables, raceways, and conductors. Cable tray fill is determined by the cross-sectional area of the tray and conductor types. For multiconductor cables (392.22(A)): if all cables are 4/0 or larger, the sum of the diameters of all cables cannot exceed the cable tray width. If all are smaller than 4/0, the sum of cross-sectional areas cannot exceed the maximum fill area for the tray. Single conductor cables rated 1/0 and larger are permitted in cable trays per 392.10. Cable trays must be supported at intervals per the manufacturer's instructions but not exceeding the span ratings for the tray type. Cable trays can serve as the equipment grounding conductor where they meet the requirements of 392.60." + instruction: 'Article 392 covers cable tray systems. Cable trays are permitted as a support system for cables, raceways, and conductors. Cable tray fill is determined by the cross-sectional area of the tray and conductor types. For multiconductor cables (392.22(A)): if all cables are 4/0 or larger, the sum of the diameters of all cables cannot exceed the cable tray width. If all are smaller than 4/0, the sum of cross-sectional areas cannot exceed the maximum fill area for the tray. Single conductor cables rated 1/0 and larger are permitted in cable trays per 392.10. Cable trays must be supported at intervals per the manufacturer''s instructions but not exceeding the span ratings for the tray type. Cable trays can serve as the equipment grounding conductor where they meet the requirements of 392.60.' problems: - id: tray-p1 type: true_false - question: "Cable tray can serve as an equipment grounding conductor." - correct: "true" - explanation: "Per 392.60, metallic cable trays can serve as equipment grounding conductors when they meet specific requirements including adequate cross-sectional area and properly bonded connections." + question: Cable tray can serve as an equipment grounding conductor. + correct: 'true' + explanation: Per 392.60, metallic cable trays can serve as equipment grounding conductors when they meet specific requirements including adequate cross-sectional area and properly bonded connections. - id: tray-p2 type: multiple_choice - question: "Per 392.10, single conductor cables in cable trays must be rated at least:" + question: 'Per 392.10, single conductor cables in cable trays must be rated at least:' options: - - "8 AWG" - - "4 AWG" - - "1/0 AWG" - - "4/0 AWG" + - 8 AWG + - 4 AWG + - 1/0 AWG + - 4/0 AWG correct: 2 - explanation: "Per 392.10, single conductor cables used in cable trays must be 1/0 AWG or larger. Multiconductor cables in cable trays have no minimum size restriction." + explanation: Per 392.10, single conductor cables used in cable trays must be 1/0 AWG or larger. Multiconductor cables in cable trays have no minimum size restriction. - id: tray-p3 type: fill_blank - question: "Per 392.22(A), when all multiconductor cables in a cable tray are 4/0 or larger, the sum of cable ___ cannot exceed the tray width." - correct: "diameters" - explanation: "Per 392.22(A)(1), for multiconductor cables 4/0 and larger, the sum of the diameters of all cables must not exceed the cable tray width." + question: Per 392.22(A), when all multiconductor cables in a cable tray are 4/0 or larger, the sum of cable ___ cannot exceed the tray width. + correct: diameters + explanation: Per 392.22(A)(1), for multiconductor cables 4/0 and larger, the sum of the diameters of all cables must not exceed the cable tray width. - id: tray-p4 type: true_false - question: "Cable trays are permitted as a support system for both cables and raceways." - correct: "true" - explanation: "Per 392.10, cable trays are permitted as a support system for cables, raceways, and conductors in various installation scenarios." - + question: Cable trays are permitted as a support system for both cables and raceways. + correct: 'true' + explanation: Per 392.10, cable trays are permitted as a support system for cables, raceways, and conductors in various installation scenarios. + keyPrerequisite: wiring-methods-overview - id: flexible-conduit - name: "Articles 348/350 — Flexible Metal Conduit" + name: Articles 348/350 — Flexible Metal Conduit difficulty: 3 estimatedMinutes: 15 - tags: [conduit, flexible, article-348, article-350] - sourceRef: "NEC 2023 Articles 348, 350" + tags: + - conduit + - flexible + - article-348 + - article-350 + sourceRef: NEC 2023 Articles 348, 350 prerequisites: - emt-conduit knowledgePoints: - id: fmc-lfmc - instruction: "FMC (Flexible Metal Conduit, Article 348) is a helically wound interlocking metal strip raceway. Common uses include connections to motors, vibrating equipment, and where flexibility is needed. FMC must be supported within 12 inches of every box and at intervals not exceeding 4-1/2 feet (348.30(A)). FMC in lengths of 6 feet or less can serve as an EGC if the circuit is 20A or less, the combined ground-fault return path is not more than 6 feet, and fittings are listed for grounding (250.118(5)). LFMC (Liquidtight Flexible Metal Conduit, Article 350) adds a plastic jacket over the metal, making it suitable for wet locations, direct burial, and outdoor use. LFMC support: within 12 inches of boxes, every 4-1/2 feet (350.30)." + instruction: 'FMC (Flexible Metal Conduit, Article 348) is a helically wound interlocking metal strip raceway. Common uses include connections to motors, vibrating equipment, and where flexibility is needed. FMC must be supported within 12 inches of every box and at intervals not exceeding 4-1/2 feet (348.30(A)). FMC in lengths of 6 feet or less can serve as an EGC if the circuit is 20A or less, the combined ground-fault return path is not more than 6 feet, and fittings are listed for grounding (250.118(5)). LFMC (Liquidtight Flexible Metal Conduit, Article 350) adds a plastic jacket over the metal, making it suitable for wet locations, direct burial, and outdoor use. LFMC support: within 12 inches of boxes, every 4-1/2 feet (350.30).' problems: - id: flex-p1 type: multiple_choice - question: "FMC can serve as an equipment grounding conductor when the length does not exceed:" + question: 'FMC can serve as an equipment grounding conductor when the length does not exceed:' options: - - "3 feet" - - "4 feet" - - "6 feet" - - "10 feet" + - 3 feet + - 4 feet + - 6 feet + - 10 feet correct: 2 - explanation: "Per 250.118(5), FMC can serve as an EGC if the combined length of the ground return path is 6 feet or less, the circuit overcurrent protection is 20A or less, and the fittings are listed for grounding." + explanation: Per 250.118(5), FMC can serve as an EGC if the combined length of the ground return path is 6 feet or less, the circuit overcurrent protection is 20A or less, and the fittings are listed for grounding. - id: flex-p2 type: fill_blank - question: "FMC must be supported within 12 inches of every box and at intervals not exceeding ___-1/2 feet per 348.30(A)." - correct: "4" - explanation: "Per 348.30(A), FMC must be secured within 12 inches of every box, cabinet, or fitting and at intervals not exceeding 4-1/2 feet (1.4 m)." + question: FMC must be supported within 12 inches of every box and at intervals not exceeding ___-1/2 feet per 348.30(A). + correct: '4' + explanation: Per 348.30(A), FMC must be secured within 12 inches of every box, cabinet, or fitting and at intervals not exceeding 4-1/2 feet (1.4 m). - id: flex-p3 type: true_false - question: "LFMC (Liquidtight Flexible Metal Conduit) adds a plastic jacket and is suitable for wet locations." - correct: "true" - explanation: "LFMC (Article 350) adds a liquid-tight plastic jacket over the metal armor, making it suitable for wet locations, direct burial (where listed), and outdoor use." + question: LFMC (Liquidtight Flexible Metal Conduit) adds a plastic jacket and is suitable for wet locations. + correct: 'true' + explanation: LFMC (Article 350) adds a liquid-tight plastic jacket over the metal armor, making it suitable for wet locations, direct burial (where listed), and outdoor use. - id: flex-p4 type: matching - question: "Match each flexible conduit type with its key distinction." + question: Match each flexible conduit type with its key distinction. options: - - "FMC (Article 348)|Helically wound metal, no outer jacket, dry locations" - - "LFMC (Article 350)|Metal with plastic jacket, wet locations, outdoor use" - correct: "0,1" - explanation: "FMC is bare flexible metal conduit for dry locations. LFMC adds a liquidtight plastic jacket, making it suitable for wet, damp, and outdoor environments." - + - FMC (Article 348)|Helically wound metal, no outer jacket, dry locations + - LFMC (Article 350)|Metal with plastic jacket, wet locations, outdoor use + correct: 0,1 + explanation: FMC is bare flexible metal conduit for dry locations. LFMC adds a liquidtight plastic jacket, making it suitable for wet, damp, and outdoor environments. + keyPrerequisite: emt-conduit - id: ground-fault-equipment - name: "Article 230.95 — Ground-Fault Protection of Equipment (GFPE)" + name: Article 230.95 — Ground-Fault Protection of Equipment (GFPE) difficulty: 5 estimatedMinutes: 15 - tags: [gfpe, ground-fault, article-230] - sourceRef: "NEC 2023 Section 230.95" + tags: + - gfpe + - ground-fault + - article-230 + sourceRef: NEC 2023 Section 230.95 prerequisites: - service-entrance - grounding-fundamentals knowledgePoints: - id: gfpe-requirements - instruction: "Section 230.95 requires ground-fault protection of equipment (GFPE) for solidly grounded wye electric services of more than 150V to ground but not exceeding 1000V phase-to-phase, for each service disconnect rated 1000A or more. This primarily applies to 277/480V, 3-phase, 4-wire wye services with disconnects of 1000A or more. GFPE is NOT the same as GFCI -- GFPE protects equipment, not people. The maximum setting is 1200A ground-fault current with a maximum delay of 1 second for ground-fault currents of 3000A or more (230.95(A)). GFPE is also required for health care facilities (Article 517) at both the normal and alternate power source disconnect levels." + instruction: Section 230.95 requires ground-fault protection of equipment (GFPE) for solidly grounded wye electric services of more than 150V to ground but not exceeding 1000V phase-to-phase, for each service disconnect rated 1000A or more. This primarily applies to 277/480V, 3-phase, 4-wire wye services with disconnects of 1000A or more. GFPE is NOT the same as GFCI -- GFPE protects equipment, not people. The maximum setting is 1200A ground-fault current with a maximum delay of 1 second for ground-fault currents of 3000A or more (230.95(A)). GFPE is also required for health care facilities (Article 517) at both the normal and alternate power source disconnect levels. problems: - id: gfpe-p1 type: multiple_choice - question: "GFPE is required for solidly grounded wye services rated 1000A or more at what voltage?" + question: GFPE is required for solidly grounded wye services rated 1000A or more at what voltage? options: - - "120/208V" - - "120/240V" - - "277/480V" - - "Any voltage" + - 120/208V + - 120/240V + - 277/480V + - Any voltage correct: 2 - explanation: "Per 230.95, GFPE is required for solidly grounded wye services of more than 150V to ground. A 277/480V wye system has 277V to ground, triggering this requirement. 120/208V and 120/240V systems have 120V to ground, which is less than 150V." + explanation: Per 230.95, GFPE is required for solidly grounded wye services of more than 150V to ground. A 277/480V wye system has 277V to ground, triggering this requirement. 120/208V and 120/240V systems have 120V to ground, which is less than 150V. - id: gfpe-p2 type: true_false - question: "GFPE and GFCI provide the same level of protection." - correct: "false" - explanation: "GFPE (Ground-Fault Protection of Equipment) protects equipment from damaging ground-fault currents and trips at much higher levels (up to 1200A). GFCI (Ground-Fault Circuit Interrupter) protects people and trips at 4-6 milliamps." + question: GFPE and GFCI provide the same level of protection. + correct: 'false' + explanation: GFPE (Ground-Fault Protection of Equipment) protects equipment from damaging ground-fault currents and trips at much higher levels (up to 1200A). GFCI (Ground-Fault Circuit Interrupter) protects people and trips at 4-6 milliamps. - id: gfpe-p3 type: fill_blank - question: "Per 230.95(A), the maximum GFPE setting is ___ amperes of ground-fault current." - correct: "1200" - explanation: "Per 230.95(A), the maximum setting of the ground-fault protection device is 1200 amperes, with a maximum time delay of 1 second for ground-fault currents of 3000 amperes or more." + question: Per 230.95(A), the maximum GFPE setting is ___ amperes of ground-fault current. + correct: '1200' + explanation: Per 230.95(A), the maximum setting of the ground-fault protection device is 1200 amperes, with a maximum time delay of 1 second for ground-fault currents of 3000 amperes or more. - id: gfpe-p4 type: multiple_choice - question: "GFPE is required for solidly grounded wye services when the disconnect is rated at:" + question: 'GFPE is required for solidly grounded wye services when the disconnect is rated at:' options: - - "400A or more" - - "600A or more" - - "800A or more" - - "1000A or more" + - 400A or more + - 600A or more + - 800A or more + - 1000A or more correct: 3 - explanation: "Per 230.95, GFPE is required for solidly grounded wye services of more than 150V to ground with each service disconnect rated 1000 amperes or more." - + explanation: Per 230.95, GFPE is required for solidly grounded wye services of more than 150V to ground with each service disconnect rated 1000 amperes or more. + keyPrerequisite: service-entrance - id: conductor-ampacity-correction - name: "Conductor Ampacity Correction Factors" + name: Conductor Ampacity Correction Factors difficulty: 7 estimatedMinutes: 25 - tags: [ampacity, correction, derating, article-310] - sourceRef: "NEC 2023 Article 310, Tables 310.15(C)(1) and 310.15(C)(1)" + tags: + - ampacity + - correction + - derating + - article-310 + sourceRef: NEC 2023 Article 310, Tables 310.15(C)(1) and 310.15(C)(1) prerequisites: - conductor-sizing - conduit-fill knowledgePoints: - id: temperature-correction - instruction: "When ambient temperature differs from the 30 degrees C base of Table 310.16, ampacity must be corrected using the factors in Table 310.15(B)(1). For example, at 40 degrees C ambient, the correction factor for 75C-rated conductors is 0.88. Apply this by multiplying: ampacity = table value x correction factor. For conductor fill adjustment (Table 310.15(C)(1)), when more than 3 current-carrying conductors are in a raceway or cable: 4-6 conductors = 80%, 7-9 = 70%, 10-20 = 50%, 21-30 = 45%, 31-40 = 40%, 41+ = 35%. When both corrections apply, multiply both factors: adjusted ampacity = table ampacity x temp factor x fill factor. Neutral conductors carrying only unbalanced current are not counted as current-carrying conductors (310.15(E))." - workedExample: "Example: Six 10 AWG THWN copper conductors in a conduit, ambient temperature 40 degrees C. Step 1: Table 310.16 at 75C: 10 AWG = 35A. Step 2: Temperature correction at 40C for 75C conductor = 0.88 (Table 310.15(B)(1)). Step 3: Fill adjustment for 6 conductors = 80% (Table 310.15(C)(1)). Step 4: Adjusted ampacity = 35 x 0.88 x 0.80 = 24.64A." + instruction: 'When ambient temperature differs from the 30 degrees C base of Table 310.16, ampacity must be corrected using the factors in Table 310.15(B)(1). For example, at 40 degrees C ambient, the correction factor for 75C-rated conductors is 0.88. Apply this by multiplying: ampacity = table value x correction factor. For conductor fill adjustment (Table 310.15(C)(1)), when more than 3 current-carrying conductors are in a raceway or cable: 4-6 conductors = 80%, 7-9 = 70%, 10-20 = 50%, 21-30 = 45%, 31-40 = 40%, 41+ = 35%. When both corrections apply, multiply both factors: adjusted ampacity = table ampacity x temp factor x fill factor. Neutral conductors carrying only unbalanced current are not counted as current-carrying conductors (310.15(E)).' + workedExample: 'Example: Six 10 AWG THWN copper conductors in a conduit, ambient temperature 40 degrees C. Step 1: Table 310.16 at 75C: 10 AWG = 35A. Step 2: Temperature correction at 40C for 75C conductor = 0.88 (Table 310.15(B)(1)). Step 3: Fill adjustment for 6 conductors = 80% (Table 310.15(C)(1)). Step 4: Adjusted ampacity = 35 x 0.88 x 0.80 = 24.64A.' problems: - id: derating-p1 type: multiple_choice - question: "Per Table 310.15(C)(1), what is the ampacity adjustment factor for 7-9 current-carrying conductors in a raceway?" + question: Per Table 310.15(C)(1), what is the ampacity adjustment factor for 7-9 current-carrying conductors in a raceway? options: - - "80%" - - "70%" - - "60%" - - "50%" + - 80% + - 70% + - 60% + - 50% correct: 1 - explanation: "Per Table 310.15(C)(1), for 7-9 current-carrying conductors in a raceway, the ampacity adjustment factor is 70%." + explanation: Per Table 310.15(C)(1), for 7-9 current-carrying conductors in a raceway, the ampacity adjustment factor is 70%. - id: derating-p2 type: multiple_choice - question: "When calculating conductor fill for ampacity adjustment, a neutral conductor that carries only unbalanced load:" + question: 'When calculating conductor fill for ampacity adjustment, a neutral conductor that carries only unbalanced load:' options: - - "Always counts as a current-carrying conductor" - - "Counts as half a current-carrying conductor" - - "Is not counted as a current-carrying conductor" - - "Counts only if the circuit exceeds 20A" + - Always counts as a current-carrying conductor + - Counts as half a current-carrying conductor + - Is not counted as a current-carrying conductor + - Counts only if the circuit exceeds 20A correct: 2 - explanation: "Per 310.15(E), a neutral conductor that carries only the unbalanced current from other conductors of the same circuit is not required to be counted as a current-carrying conductor for fill adjustment purposes." + explanation: Per 310.15(E), a neutral conductor that carries only the unbalanced current from other conductors of the same circuit is not required to be counted as a current-carrying conductor for fill adjustment purposes. - id: derating-p3 type: fill_blank - question: "Table 310.16 ampacities are based on an ambient temperature of ___ degrees C." - correct: "30" - explanation: "Table 310.16 provides ampacities based on an ambient temperature of 30 degrees C (86 degrees F). When ambient temperature exceeds 30C, correction factors from Table 310.15(B)(1) must be applied." + question: Table 310.16 ampacities are based on an ambient temperature of ___ degrees C. + correct: '30' + explanation: Table 310.16 provides ampacities based on an ambient temperature of 30 degrees C (86 degrees F). When ambient temperature exceeds 30C, correction factors from Table 310.15(B)(1) must be applied. - id: derating-p4 type: ordering - question: "Place these conductor fill adjustment factors in order from highest to lowest percentage per Table 310.15(C)(1)." - options: - - "10-20 current-carrying conductors — 50%" - - "4-6 current-carrying conductors — 80%" - - "7-9 current-carrying conductors — 70%" - correct: "1,2,0" - explanation: "Per Table 310.15(C)(1): 4-6 conductors = 80%, 7-9 conductors = 70%, 10-20 conductors = 50%. More conductors in a raceway means more derating." - - # ============================================================ - # CAPSTONE - # ============================================================ - + question: Place these conductor fill adjustment factors in order from highest to lowest percentage per Table 310.15(C)(1). + options: + - 10-20 current-carrying conductors — 50% + - 4-6 current-carrying conductors — 80% + - 7-9 current-carrying conductors — 70% + correct: 1,2,0 + explanation: 'Per Table 310.15(C)(1): 4-6 conductors = 80%, 7-9 conductors = 70%, 10-20 conductors = 50%. More conductors in a raceway means more derating.' + keyPrerequisite: conductor-sizing - id: exam-strategy - name: "NEC Exam Strategy — Comprehensive Review" + name: NEC Exam Strategy — Comprehensive Review difficulty: 8 estimatedMinutes: 30 - tags: [exam-strategy, capstone] - sourceRef: "NEC 2023 (all articles)" + tags: + - exam-strategy + - capstone + sourceRef: NEC 2023 (all articles) prerequisites: - dwelling-load-calculations - commercial-load-calc @@ -2549,46 +2643,47 @@ concepts: weight: 0.5 knowledgePoints: - id: exam-tips - instruction: "NEC electrician exams typically consist of open-book questions where speed is critical. Know where to find information fast. Memorize Table 310.16 ampacities for common wire sizes -- this saves 30+ seconds per question. Know the article numbers by heart: 90 (intro), 100 (definitions), 110 (general), 210 (branch circuits), 215 (feeders), 220 (load calcs), 230 (services), 240 (overcurrent), 250 (grounding), 300 (wiring methods), 310 (conductors), 314 (boxes), 334 (NM cable), 430 (motors), 680 (pools). Practice calculation questions: voltage drop, box fill, conduit fill, load calculations, and motor circuit sizing. These appear on every exam. Mark the key tables in your codebook with tabs: Table 310.16, Table 250.66, Table 250.122, Table 220.42, Table 220.55, Chapter 9 Tables 1, 4, 5." - workedExample: "Example comprehensive problem: A 2,000 sq ft dwelling has a 12 kW range, 5 kW dryer, 4.5 kW water heater, 5-ton AC (24A at 240V), and 10 kW heat strip. Calculate the service size. General lighting: 2000 x 3 = 6,000 VA. Small appliance: 3,000 VA. Laundry: 1,500 VA. Total = 10,500 VA. Demand: 3,000 at 100% = 3,000 + 7,500 at 35% = 2,625 = 5,625 VA. Range: 8,000 VA. Dryer: 5,000 VA. Water heater: 4,500 VA. AC: 24A x 240V = 5,760 VA. Heat: 10,000 VA. Use larger of AC/Heat: 10,000 VA. Total: 5,625 + 8,000 + 5,000 + 4,500 + 10,000 = 33,125 VA. Amps: 33,125 / 240 = 138A. Minimum 150A service." + instruction: 'NEC electrician exams typically consist of open-book questions where speed is critical. Know where to find information fast. Memorize Table 310.16 ampacities for common wire sizes -- this saves 30+ seconds per question. Know the article numbers by heart: 90 (intro), 100 (definitions), 110 (general), 210 (branch circuits), 215 (feeders), 220 (load calcs), 230 (services), 240 (overcurrent), 250 (grounding), 300 (wiring methods), 310 (conductors), 314 (boxes), 334 (NM cable), 430 (motors), 680 (pools). Practice calculation questions: voltage drop, box fill, conduit fill, load calculations, and motor circuit sizing. These appear on every exam. Mark the key tables in your codebook with tabs: Table 310.16, Table 250.66, Table 250.122, Table 220.42, Table 220.55, Chapter 9 Tables 1, 4, 5.' + workedExample: 'Example comprehensive problem: A 2,000 sq ft dwelling has a 12 kW range, 5 kW dryer, 4.5 kW water heater, 5-ton AC (24A at 240V), and 10 kW heat strip. Calculate the service size. General lighting: 2000 x 3 = 6,000 VA. Small appliance: 3,000 VA. Laundry: 1,500 VA. Total = 10,500 VA. Demand: 3,000 at 100% = 3,000 + 7,500 at 35% = 2,625 = 5,625 VA. Range: 8,000 VA. Dryer: 5,000 VA. Water heater: 4,500 VA. AC: 24A x 240V = 5,760 VA. Heat: 10,000 VA. Use larger of AC/Heat: 10,000 VA. Total: 5,625 + 8,000 + 5,000 + 4,500 + 10,000 = 33,125 VA. Amps: 33,125 / 240 = 138A. Minimum 150A service.' problems: - id: exam-p1 type: multiple_choice - question: "Which NEC table is used most frequently on electrician exams for conductor ampacity?" + question: Which NEC table is used most frequently on electrician exams for conductor ampacity? options: - - "Table 220.42" - - "Table 250.66" - - "Table 310.16" - - "Table 430.248" + - Table 220.42 + - Table 250.66 + - Table 310.16 + - Table 430.248 correct: 2 - explanation: "Table 310.16 (Allowable Ampacities of Insulated Conductors) is the most frequently referenced table on electrician exams. It provides ampacities for conductors at 60, 75, and 90 degree C temperature ratings." + explanation: Table 310.16 (Allowable Ampacities of Insulated Conductors) is the most frequently referenced table on electrician exams. It provides ampacities for conductors at 60, 75, and 90 degree C temperature ratings. - id: exam-p2 type: multiple_choice - question: "For a dwelling unit load calculation, the demand factor for the general lighting load above 3,000 VA is:" + question: 'For a dwelling unit load calculation, the demand factor for the general lighting load above 3,000 VA is:' options: - - "25%" - - "35%" - - "50%" - - "75%" + - 25% + - 35% + - 50% + - 75% correct: 1 - explanation: "Per Table 220.42, for dwelling units, the general lighting demand factor is 100% for the first 3,000 VA and 35% for the portion from 3,001 to 120,000 VA." + explanation: Per Table 220.42, for dwelling units, the general lighting demand factor is 100% for the first 3,000 VA and 35% for the portion from 3,001 to 120,000 VA. - id: exam-p3 type: matching - question: "Match each NEC table with what it provides." - options: - - "Table 310.16|Conductor ampacities at 60/75/90 degrees C" - - "Table 250.122|Equipment grounding conductor sizing" - - "Table 250.66|Grounding electrode conductor sizing" - - "Table 220.55|Household range demand factors" - correct: "0,1,2,3" - explanation: "Knowing which table to look up is critical for exam speed. Table 310.16 = ampacity, 250.122 = EGC sizing, 250.66 = GEC sizing, 220.55 = range demand." + question: Match each NEC table with what it provides. + options: + - Table 310.16|Conductor ampacities at 60/75/90 degrees C + - Table 250.122|Equipment grounding conductor sizing + - Table 250.66|Grounding electrode conductor sizing + - Table 220.55|Household range demand factors + correct: 0,1,2,3 + explanation: Knowing which table to look up is critical for exam speed. Table 310.16 = ampacity, 250.122 = EGC sizing, 250.66 = GEC sizing, 220.55 = range demand. - id: exam-p4 type: ordering - question: "Place these steps of a dwelling load calculation in the correct order." - options: - - "Apply Table 220.42 demand factors to general lighting total" - - "Add range (Table 220.55), dryer, water heater, and larger of AC/heat" - - "Calculate general lighting (sq ft x 3 VA), small appliance (3,000 VA), laundry (1,500 VA)" - - "Divide total VA by 240V to get service amperes" - correct: "2,0,1,3" - explanation: "Step 1: Calculate raw loads. Step 2: Apply demand factors from Table 220.42. Step 3: Add major appliances and equipment. Step 4: Divide by voltage to get amperage for service sizing." + question: Place these steps of a dwelling load calculation in the correct order. + options: + - Apply Table 220.42 demand factors to general lighting total + - Add range (Table 220.55), dryer, water heater, and larger of AC/heat + - Calculate general lighting (sq ft x 3 VA), small appliance (3,000 VA), laundry (1,500 VA) + - Divide total VA by 240V to get service amperes + correct: 2,0,1,3 + explanation: 'Step 1: Calculate raw loads. Step 2: Apply demand factors from Table 220.42. Step 3: Add major appliances and equipment. Step 4: Divide by voltage to get amperage for service sizing.' + keyPrerequisite: dwelling-load-calculations