with one click
challenge-author
Write hands-on challenge lessons with verification
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Write hands-on challenge lessons with verification
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Identify deprecated Cypher syntax in code files.
Create linear issues for the GRAC (GraphAcademy) team.
Periodically review course content for accuracy, relevance, and consistency. This includes checking for deprecated Cypher syntax.
Fact-check a single lesson against Neo4j documentation using the neo4j-docs MCP. Fixes inaccurate claims inline and appends a WHY report.
Review a single lesson for US English grammar, style, voice, and Neo4j terminology. Fixes issues inline and appends a WHY report.
Review a single lesson for pedagogical structure, lesson length, opening pattern, concept delivery, and scaffolding. Fixes issues inline and appends a WHY report.
Based on SOC occupation classification
| name | challenge-author |
| description | Write hands-on challenge lessons with verification |
| allowed-tools | Read, Write, Edit, Glob, Grep |
Purpose: Write hands-on challenge lessons with automated verification.
When to use: Workshop lesson requires learners to build something hands-on.
Prerequisites:
This skill writes challenge lessons that:
Do NOT write concept lessons, quizzes, or practice lessons. This skill focuses ONLY on challenge lessons with verification.
Focus on graph databases and graph technologies.
Challenge lessons should:
Before writing anything, answer:
MUST READ:
- WORKSHOP-PLAN.md (for challenge details)
- Source course lesson (for challenge content)
- Previous concept lesson (for context)
- CONTENT_GUIDELINES.md (for style rules)
REFERENCE:
- modules/2-foundation/lessons/4-import-products/ (example challenge)
- verify.cypher, solution.cypher, questions/verify.adoc examples
Introduction
├── Challenge statement: "You will [action]"
└── Building block: "This completes [description]"
The Data
├── CSV structure table
└── Download button
Tool Reference
└── "See Module 1 Lesson 3 for tool mechanics"
Instructions
├── Step 1: [What to do]
├── Step 2: [What to do]
└── Step N: [What to do]
Configuration Details
└── Property mapping table
Snapshot Option
└── Collapsible with pre-built model
Verification
└── Include questions/verify.adoc
Every challenge MUST complete a building block. State it clearly:
This completes **Building Block 1**: "Products exist in the graph" ✓
Examples:
[.slide.discrete]
== Challenge
You will [specific action with tool].
This completes **Building Block [N]**: "[Description]" ✓
Example:
[.slide.discrete]
== Challenge
You will use Data Importer to import Product nodes from a CSV file.
This completes **Building Block 1**: "Products exist in the graph" ✓
[.slide]
== The Data
[Brief description of what the data represents]
[options="header"]
|===
| Column | Type | Description
| columnName1 | String | What this column contains
| columnName2 | Integer | What this column contains
| columnName3 | Float | What this column contains
|===
Example:
[.slide]
== The Data
The products.csv file contains information about items in the Northwind catalog.
[options="header"]
|===
| Column | Type | Description
| productId | String | Unique identifier for each product
| productName | String | Display name of the product
| unitPrice | Float | Price per unit in USD
| unitsInStock | Integer | Current inventory count
| categoryId | String | Reference to product category
|===
[.slide]
== Load Data Files
button::Download Workshop Data[role=NX_DOWNLOAD_FILE, file="data/workshop-data.zip"]
**Note:** Download once and extract. You will use these CSV files throughout the workshop.
CRITICAL: Do NOT repeat tool mechanics. Reference Module 1 Lesson 3.
[.slide]
== Using [Tool Name]
**Reference:** See Module 1 Lesson 3 for [tool name] mechanics.
**Steps for this challenge:**
1. [High-level step 1]
2. [High-level step 2]
3. [High-level step 3]
Example:
[.slide]
== Using Data Importer
**Reference:** See Module 1 Lesson 3 for Data Importer mechanics.
**Steps for this challenge:**
1. Open **Data Importer** from Aura console
2. Upload products.csv
3. Map to Product node
4. Configure properties
5. Run import
[.slide]
== Configure Properties
Map the CSV columns to node properties:
[options="header"]
|===
| CSV Column | Type | Rename To | Notes
| productId | String | id | Unique identifier
| productName | String | name | Display name
| unitPrice | Float | | Keep original name
| unitsInStock | Integer | | Keep original name
|===
**Important:** Set `id` as the unique identifier property.
[.slide]
== Run Import
Click **Run Import** to execute.
**Confirmation:** You should see "**77 Product nodes created**"
[.slide]
== Snapshot Option
[.collapsible]
.Load Pre-Built Data Model
====
**Skip ahead:** If you want to skip this challenge, load the pre-built model.
button::Download Snapshot[role=NX_DOWNLOAD_FILE, file="snapshots/module2-lesson4.zip"]
**What's included:**
* [What was built in this challenge]
* [Configuration details]
**After loading:**
1. Review the model in Data Importer
2. Connect to your instance
3. Click **Run Import**
====
Example:
[.slide]
== Snapshot Option
[.collapsible]
.Load Pre-Built Data Model
====
**Skip ahead:** If you want to skip this challenge, load the pre-built model.
button::Download Snapshot[role=NX_DOWNLOAD_FILE, file="snapshots/module2-lesson4.zip"]
**What's included:**
* Product node mapping
* Property configuration (id, name, unitPrice, unitsInStock)
* Ready to import 77 products
**After loading:**
1. Review the model in Data Importer
2. Upload products.csv
3. Click **Run Import**
====
outcome and reasonlesson-folder/
├── lesson.adoc
├── verify.cypher (automated check)
├── solution.cypher (minimal passing code)
└── questions/
└── verify.adoc (UI integration)
CRITICAL: Must return exactly two columns: outcome (boolean) and reason (string)
// verify.cypher
RETURN COUNT { (:NodeLabel) } > 0 AS outcome,
CASE
WHEN COUNT { (:NodeLabel) } = 0
THEN 'No [NodeLabel] nodes found. Check that you imported the data.'
WHEN COUNT { (:NodeLabel) } < [expected]
THEN 'Only ' + COUNT { (:NodeLabel) } + ' [NodeLabel] nodes found. Expected [expected].'
ELSE 'Success! You imported ' + COUNT { (:NodeLabel) } + ' [NodeLabel] nodes.'
END AS reason;
Example (verify.cypher):
// Verify Product nodes were imported
RETURN COUNT { (:Product) } > 0 AS outcome,
CASE
WHEN COUNT { (:Product) } = 0
THEN 'No Product nodes found. Make sure you ran the import in Data Importer.'
WHEN COUNT { (:Product) } < 77
THEN 'Only ' + COUNT { (:Product) } + ' Product nodes found. Expected 77.'
ELSE 'Success! You imported ' + COUNT { (:Product) } + ' Product nodes.'
END AS reason;
CRITICAL: Minimal code that passes verification, NOT full solution
// solution.cypher - minimal passing example
CREATE (:NodeLabel {id: "1", name: "Test Item"});
Example (solution.cypher):
// Minimal solution that passes verification
// This is NOT the recommended approach - use Data Importer instead
CREATE (:Product {id: "1", name: "Test Product"});
CREATE (:Product {id: "2", name: "Another Product"});
[.verify.slide]
== Validate Results
Once you have [completed the challenge/imported the data/created the relationships], verify your results.
verify::[]
[TIP,role=hint]
.Hint
====
[Guidance toward solution without giving it away]
**Check:**
* [Thing to verify 1]
* [Thing to verify 2]
====
[TIP,role=solution]
.Solution
====
[Manual validation query]
[source,cypher]
.Check imported nodes
----
MATCH (n:NodeLabel)
RETURN count(n) AS total;
----
You should see [expected result].
**If verification fails:**
* [Troubleshooting step 1]
* [Troubleshooting step 2]
====
Example (questions/verify.adoc):
[.verify.slide]
== Validate Results
Once you have imported Product nodes, verify your results.
verify::[]
[TIP,role=hint]
.Hint
====
Make sure you completed all steps in Data Importer:
**Check:**
* CSV file uploaded
* Product node mapped
* Properties configured (id, name, unitPrice, unitsInStock)
* Import executed successfully
====
[TIP,role=solution]
.Solution
====
Run this query to check your Product nodes:
[source,cypher]
.Check Product nodes
----
MATCH (p:Product)
RETURN count(p) AS total,
collect(p.name)[0..5] AS sampleNames;
----
You should see 77 total products with names like "Chai", "Chang", "Aniseed Syrup".
**If verification fails:**
* Verify the CSV file was uploaded correctly
* Check that property names match (id, name not productId, productName)
* Ensure you clicked "Run Import"
* Try reloading the Data Importer page
====
[.summary]
== Summary
You imported [Entity] nodes:
* [N] nodes created
* Properties: [list properties]
* **Building Block [N]**: "[Description]" ✓
In the next lesson, you will [what comes next].
Example:
[.summary]
== Summary
You imported Product nodes using Data Importer:
* 77 Product nodes created
* Properties: id, name, unitPrice, unitsInStock
* **Building Block 1**: "Products exist in the graph" ✓
In the next lesson, you will write queries to explore the products you imported.
// <1> not // (1)At the end of instructions, before summary:
include::questions/verify.adoc[leveloffset=+1]
[.summary]
== Summary
Before completing:
Test verify.cypher:
outcome (boolean) and reason (string)?Test solution.cypher:
Test questions/verify.adoc:
See these real files:
modules/2-foundation/lessons/4-import-products/
modules/3-modeling-relationships/lessons/2-import-customers-orders/
modules/4-many-to-many/lessons/2-create-orders-relationships/
4-import-products/lesson.adoc:
verify.cypher:
outcome and reasonCOUNT {(:Product)} > 0solution.cypher:
CREATE (:Product {id: "1", name: "Test"})questions/verify.adoc:
[.verify.slide] markerverify::[] macro for system integrationBefore marking challenge complete, verify:
lesson.adoc existsverify.cypher exists and testedsolution.cypher exists and testedquestions/verify.adoc exists:type: challenge, :order: X, :duration: 7-12