Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
a5a2e80
feat: Add Java problems, questions, and chunks for the hallway, and i…
Saannddy Mar 21, 2026
81fb52a
feat: refactor chunk processing to improve template handling and snip…
Saannddy Mar 23, 2026
5eb0e6d
feat: Add Java problems, questions, and chunks for the hallway, and i…
Saannddy Mar 21, 2026
7d93589
Merge branch 'update-hallway-seeder' of https://github.com/Saannddy/C…
Saannddy Mar 29, 2026
d36e25e
Merge pull request #48 from Saannddy/update-hallway-seeder
Saannddy Apr 3, 2026
5688e4d
fix: Sort snippet keys in chunk_service.py
Saannddy Apr 3, 2026
b703c7d
chore: remove mandate comments on sorting snippets dictionary keys
Saannddy Apr 3, 2026
cf72739
refactor: update Java snippet descriptions to use descriptive, human-…
Saannddy Apr 3, 2026
7315d89
refactor: update Java chunk schema to use object-based templates and …
Saannddy Apr 3, 2026
a450c84
feat: add category support to chunk retrieval and implement Elevator …
Saannddy Apr 3, 2026
070823e
refactor: update seeder imports to avoid circular dependency warnings…
Saannddy Apr 3, 2026
85a6140
chore: remove package initialization comment from scripts module
Saannddy Apr 3, 2026
8519a77
feat: add level 4 Java coding challenges and update chunk retrieval c…
Saannddy Apr 5, 2026
3eb3fd8
Merge pull request #57 from Saannddy/add-data-elevator-hallway-and-ca…
Saannddy Apr 6, 2026
cbe4363
Merge pull request #56 from Saannddy/debug-the-always-pass-condition-…
Saannddy Apr 6, 2026
07157f4
Merge pull request #55 from Saannddy/update-chunks-data-add-clue-for-…
Saannddy Apr 6, 2026
a35fbf7
Merge pull request #54 from Saannddy/critical-bug-fix-on-non-sorted-s…
Saannddy Apr 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions bruno/local/Chunk/Execute Java Chunk.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
meta {
name: Execute Java Chunk
type: http
seq: 8
}

post {
url: http://localhost:3000/chunk/execute/22e04d50-3aea-43ac-9a89-32daea0cc9f8?lang=java
body: json
auth: none
}

params:query {
lang: java
}

body:json {
{
"snippets": {
"logic": "return x * y"
}
}
}
5 changes: 3 additions & 2 deletions bruno/local/Chunk/Get Random Chunks.bru
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ meta {
}

get {
url: {{base_url}}/chunk/random?tags=JAV_LOCKERROOM
url: {{base_url}}/chunk/random?tags=JAV_ELVHALL&category=ELV-P5
body: none
auth: none
}

params:query {
tags: JAV_LOCKERROOM
tags: JAV_ELVHALL
category: ELV-P5
}
3 changes: 2 additions & 1 deletion src/handlers/chunk_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ def get_chunk(self, chunk_id):
def get_random_chunks(self):
limit = request.args.get('limit', default=1, type=int)
lang = request.args.get('lang')
category = request.args.get('category')
tags = request.args.get('tags')
if tags:
tags = [tag.strip() for tag in tags.split(',')]

chunks = self.service.get_random_chunks(limit=limit, lang=lang, tags=tags)
chunks = self.service.get_random_chunks(limit=limit, lang=lang, tags=tags, category=category)
return jsonify(status="success", data=chunks), 200
27 changes: 18 additions & 9 deletions src/repositories/chunk_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,23 +78,22 @@ def get_details(self, chunk_id, lang=None):

return self._serialize_chunk(chunk, lang)

def find_random(self, limit=1, lang=None, tags=None):
"""Fetch random N chunks with their implementation details. Filters by language and tags if provided."""
def find_random(self, limit=1, lang=None, tags=None, category=None):
"""Fetch random N chunks with their implementation details. Filters by language, tags, and category if provided."""
with self._get_session() as session:
statement = select(Chunk).options(
joinedload(Chunk.templates).joinedload(ChunkTemplate.snippets),
joinedload(Chunk.tags)
joinedload(Chunk.tags),
joinedload(Chunk.categories)
).order_by(func.random())

# If language is specified, filter chunks that HAVE at least one template in that language
if lang:
statement = statement.join(Chunk.templates).where(ChunkTemplate.language == lang)

# If tags are specified, we need chunks that have ALL specified tags
if tags:
from models import Tag
# For simplicity, fetch more and filter in Python
fetch_limit = limit * 10 # Fetch more to account for filtering
# If tags or category are specified, we might need more to filter in Python
if tags or category:
fetch_limit = limit * 20 # Fetch more to account for filtering
statement = statement.limit(fetch_limit)
else:
statement = statement.limit(limit * 2) # Some buffer
Expand All @@ -105,12 +104,22 @@ def find_random(self, limit=1, lang=None, tags=None):

chunks = []
for chunk in results:
if lang and lang not in chunk.config.get("templates", {}):
# Basic language check (redundant but safe)
if lang and lang not in [t.language for t in chunk.templates]:
continue

# Tag check
if tags:
chunk_tag_names = [t.name for t in chunk.tags]
if not all(tag in chunk_tag_names for tag in tags):
continue

# Category check
if category:
chunk_category_names = [c.name for c in chunk.categories]
if category not in chunk_category_names:
continue

chunks.append(self._serialize_chunk(chunk, lang))
if len(chunks) >= limit:
break
Expand Down
1 change: 0 additions & 1 deletion src/scripts/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
# This file makes the folder a Python package.
162 changes: 162 additions & 0 deletions src/scripts/data/java/elevatorhall/chunks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
[
{
"title": "ELV-P4-CHUNK-001",
"difficulty": "Medium",
"category": "ELV-P4",
"templates": {
"java": {
"name": "Java Implementation",
"template_code": "// [NULL] stripped the exception handling from the ID scanner.\n// It now crashes on any non-integer input and floods the audit log with errors.\n// Restore the three blocks. Every scan must be logged, pass or fail.\n\npublic class CheckpointScanner {\n\n public static String parseStudentID(String input) {\n try {\n // TASK 1: Parse input. Return \"VALID:\" + id if 10000\u201399999, else \"INVALID:OUT_OF_RANGE\".\n {{{snippet_1}}}\n } catch (NumberFormatException e) {\n // TASK 2: Return \"INVALID:NOT_A_NUMBER\".\n {{{snippet_2}}}\n } finally {\n // TASK 3: Always print \"scan attempt logged\".\n {{{snippet_3}}}\n }\n }\n}",
"snippets": {
"snippet_1": "None to be shown here",
"snippet_2": "None to be shown here",
"snippet_3": "None to be shown here"
}
}
},
"expectation": {
"input": "12345",
"output": "VALID:12345"
}
},
{
"title": "ELV-P4-CHUNK-002",
"difficulty": "Medium",
"category": "ELV-P4",
"templates": {
"java": {
"name": "Java Implementation",
"template_code": "// The room code scanner is throwing unhandled exceptions on every bad input.\n// [NULL] knew exactly which lines to delete to break the audit trail.\n// Restore all three exception blocks.\n\npublic class CheckpointScanner {\n\n public static String parseRoomCode(String input) {\n try {\n // TASK 1: Parse input. Return \"ROOM:\" + code if 100\u2013999, else \"INVALID:NOT_A_ROOM\".\n {{{snippet_1}}}\n } catch (NumberFormatException e) {\n // TASK 2: Return \"INVALID:FORMAT_ERROR\".\n {{{snippet_2}}}\n } finally {\n // TASK 3: Always print \"door scan logged\".\n {{{snippet_3}}}\n }\n }\n}",
"snippets": {
"snippet_1": "None to be shown here",
"snippet_2": "None to be shown here",
"snippet_3": "None to be shown here"
}
}
},
"expectation": {
"input": "123",
"output": "ROOM:123"
}
},
{
"title": "ELV-P4-CHUNK-003",
"difficulty": "Medium",
"category": "ELV-P4",
"templates": {
"java": {
"name": "Java Implementation",
"template_code": "// The port scanner crashes on anything that is not a clean integer.\n// Without proper exception handling the network audit trail is blind.\n// Restore it.\n\npublic class CheckpointScanner {\n\n public static String parsePort(String input) {\n try {\n // TASK 1: Parse input. Return \"PORT:\" + number if 1\u201365535, else \"INVALID:PORT_OUT_OF_RANGE\".\n {{{snippet_1}}}\n } catch (NumberFormatException e) {\n // TASK 2: Return \"INVALID:NOT_A_PORT\".\n {{{snippet_2}}}\n } finally {\n // TASK 3: Always print \"connection attempt logged\".\n {{{snippet_3}}}\n }\n }\n}",
"snippets": {
"snippet_1": "None to be shown here",
"snippet_2": "None to be shown here",
"snippet_3": "None to be shown here"
}
}
},
"expectation": {
"input": "80",
"output": "PORT:80"
}
},
{
"title": "ELV-P4-CHUNK-004",
"difficulty": "Medium",
"category": "ELV-P4",
"templates": {
"java": {
"name": "Java Implementation",
"template_code": "// The elevator rejects every floor request because the parser throws on bad input.\n// [NULL] removed the safety net. Restore the exception blocks.\n// The finally block is not optional \u2014 the lift log must always write.\n\npublic class CheckpointScanner {\n\n public static String parseFloor(String input) {\n try {\n // TASK 1: Parse input. Return \"FLOOR:\" + number if 1\u201310, else \"INVALID:NO_SUCH_FLOOR\".\n {{{snippet_1}}}\n } catch (NumberFormatException e) {\n // TASK 2: Return \"INVALID:NOT_A_NUMBER\".\n {{{snippet_2}}}\n } finally {\n // TASK 3: Always print \"elevator request logged\".\n {{{snippet_3}}}\n }\n }\n}",
"snippets": {
"snippet_1": "None to be shown here",
"snippet_2": "None to be shown here",
"snippet_3": "None to be shown here"
}
}
},
"expectation": {
"input": "5",
"output": "FLOOR:5"
}
},
{
"title": "ELV-P5-CHUNK-001",
"difficulty": "Medium",
"category": "ELV-P5",
"templates": {
"java": {
"name": "Java Implementation",
"template_code": "// 4,847 log entries. The threat filter is gone \u2014 [NULL] deleted it first.\n// Without it the emergency system cannot assess severity.\n// Find the threats. The building needs this report before it can act.\n\nimport java.util.ArrayList;\n\npublic class ThreatAnalyser {\n\n public static String analyzeLogs(ArrayList<String> logs) {\n\n // TASK 1: Declare a counter and an ArrayList<String> for threat descriptions.\n {{{snippet_1}}}\n\n for (String entry : logs) {\n // TASK 2: If entry starts with \"THREAT:\", increment and collect the description (after 8 chars).\n {{{snippet_2}}}\n }\n\n // TASK 3: Return \"THREATS:0|none\" if clean, else \"THREATS:\" + count + \"|\" + descriptions joined by \",\".\n {{{snippet_3}}}\n }\n\n public static void main(String[] args) {\n ArrayList<String> logs1 = new ArrayList<>();\n logs1.add(\"INFO: door opened\");\n logs1.add(\"THREAT: brute force\");\n logs1.add(\"INFO: scan ok\");\n logs1.add(\"THREAT: port scan\");\n logs1.add(\"THREAT: login fail\");\n System.out.println(analyzeLogs(logs1));\n\n ArrayList<String> logs2 = new ArrayList<>();\n logs2.add(\"INFO: all clear\");\n System.out.println(analyzeLogs(logs2));\n }\n}",
"snippets": {
"snippet_1": "None to be shown here",
"snippet_2": "None to be shown here",
"snippet_3": "None to be shown here"
}
}
},
"expectation": {
"input": "",
"output": ""
}
},
{
"title": "ELV-P5-CHUNK-002",
"difficulty": "Medium",
"category": "ELV-P5",
"templates": {
"java": {
"name": "Java Implementation",
"template_code": "// The server error filter was wiped along with the intrusion logs.\n// Critical errors are invisible to the monitoring system.\n// Restore the filter \u2014 find every ERROR entry and report the count.\n\nimport java.util.ArrayList;\n\npublic class ThreatAnalyser {\n\n public static String filterErrors(ArrayList<String> logs) {\n\n // TASK 1: Declare a counter and an ArrayList<String> for error messages.\n {{{snippet_1}}}\n\n for (String entry : logs) {\n // TASK 2: If entry starts with \"ERROR:\", increment and collect the message (after 7 chars).\n {{{snippet_2}}}\n }\n\n // TASK 3: Return \"ERRORS:0|none\" if clean, else \"ERRORS:\" + count + \"|\" + messages joined by \",\".\n {{{snippet_3}}}\n }\n\n public static void main(String[] args) {\n ArrayList<String> logs1 = new ArrayList<>();\n logs1.add(\"INFO: server started\");\n logs1.add(\"ERROR: disk full\");\n logs1.add(\"ERROR: null pointer\");\n logs1.add(\"INFO: backup ok\");\n System.out.println(filterErrors(logs1));\n\n ArrayList<String> logs2 = new ArrayList<>();\n logs2.add(\"INFO: running\");\n System.out.println(filterErrors(logs2));\n }\n}",
"snippets": {
"snippet_1": "None to be shown here",
"snippet_2": "None to be shown here",
"snippet_3": "None to be shown here"
}
}
},
"expectation": {
"input": "",
"output": ""
}
},
{
"title": "ELV-P5-CHUNK-003",
"difficulty": "Medium",
"category": "ELV-P5",
"templates": {
"java": {
"name": "Java Implementation",
"template_code": "// The badge access log is full of denied entries \u2014 someone was probing every door.\n// The scanner that should have flagged them is offline.\n// Find every DENIED entry before [NULL] makes another move.\n\nimport java.util.ArrayList;\n\npublic class ThreatAnalyser {\n\n public static String findDenied(ArrayList<String> entries) {\n\n // TASK 1: Declare a counter and an ArrayList<String> for denied entries.\n {{{snippet_1}}}\n\n for (String entry : entries) {\n // TASK 2: If entry contains \"DENIED\" anywhere, increment and collect the full entry.\n {{{snippet_2}}}\n }\n\n // TASK 3: Return \"DENIED:0|none\" if none, else \"DENIED:\" + count + \"|\" + entries joined by \",\".\n {{{snippet_3}}}\n }\n\n public static void main(String[] args) {\n ArrayList<String> e1 = new ArrayList<>();\n e1.add(\"Student 001: GRANTED\");\n e1.add(\"Student 002: DENIED low clearance\");\n e1.add(\"Student 003: GRANTED\");\n e1.add(\"Visitor 01: DENIED no badge\");\n System.out.println(findDenied(e1));\n\n ArrayList<String> e2 = new ArrayList<>();\n e2.add(\"Staff 001: GRANTED\");\n System.out.println(findDenied(e2));\n }\n}",
"snippets": {
"snippet_1": "None to be shown here",
"snippet_2": "None to be shown here",
"snippet_3": "None to be shown here"
}
}
},
"expectation": {
"input": "",
"output": ""
}
},
{
"title": "ELV-P5-CHUNK-004",
"difficulty": "Medium",
"category": "ELV-P5",
"templates": {
"java": {
"name": "Java Implementation",
"template_code": "// Elevator requests are piling up but the floor filter is down.\n// Security needs to know exactly how many calls are going to each floor.\n// Restore the filter \u2014 match by floor number, report the count.\n\nimport java.util.ArrayList;\n\npublic class ThreatAnalyser {\n\n public static String findFloorRequests(ArrayList<String> logs, int floor) {\n\n // TASK 1: Declare a counter and an ArrayList<String> for matching requests.\n {{{snippet_1}}}\n\n for (String entry : logs) {\n // TASK 2: If entry ends with \":\" + floor, increment and collect the full entry.\n {{{snippet_2}}}\n }\n\n // TASK 3: Return \"FLOOR\" + floor + \":0|none\" if none,\n // else \"FLOOR\" + floor + \":\" + count + \"|\" + entries joined by \",\".\n {{{snippet_3}}}\n }\n\n public static void main(String[] args) {\n ArrayList<String> logs = new ArrayList<>();\n logs.add(\"User A requested floor:2\");\n logs.add(\"User B requested floor:3\");\n logs.add(\"User C requested floor:2\");\n logs.add(\"User D requested floor:1\");\n System.out.println(findFloorRequests(logs, 2));\n System.out.println(findFloorRequests(logs, 5));\n }\n}",
"snippets": {
"snippet_1": "None to be shown here",
"snippet_2": "None to be shown here",
"snippet_3": "None to be shown here"
}
}
},
"expectation": {
"input": "",
"output": ""
}
}
]
Loading