Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
32 changes: 19 additions & 13 deletions js/app.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const STORAGE_SAVE_KEY = "launchdesk-v1-items";
const STORAGE_LOAD_KEY = "launchdesk-items-v1"; // Intentional bug: this key should match STORAGE_SAVE_KEY.
const STORAGE_LOAD_KEY = "launchdesk-v1-items"; // Intentional bug: this key should match STORAGE_SAVE_KEY.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Remove the stale // Intentional bug: comments — they now describe the fixed behavior and will mislead future readers.

After the fixes in this PR, every "Intentional bug" comment is no longer true. They were useful as bug markers in the original lab scaffold, but in the corrected code they now read as instructions to re-introduce the bug (e.g., line 136 says "validation should stop when either required field is missing" — which is exactly what the code now does, so the comment reads as a complaint about correct code). The same applies to lines 2, 94, 173, 177, 199, 239, 243, 255, 287, 294, and 321.

Sweep the file and remove (or rewrite) these markers so the remaining comments describe what the code is, not the historical bug.

♻️ Representative cleanups
-const STORAGE_LOAD_KEY = "launchdesk-v1-items"; // Intentional bug: this key should match STORAGE_SAVE_KEY.
+const STORAGE_LOAD_KEY = STORAGE_SAVE_KEY;
-form.addEventListener("submit", (event) => handleAddCheck(event)); // Intentional bug: misspelled function name.
+form.addEventListener("submit", handleAddCheck);
-  if (!title || !category) {
-    // Intentional bug: validation should stop when either required field is missing.
+  if (!title || !category) {
-  ); // Intentional bug: search should include title, category, priority, status, and owner.
+  );
-  } // Intentional bug: status filter compares against priority.
+  }
-    const statusClass = `status-${check.status.toLowerCase().replaceAll(" ", "-")}`; // Intentional bug: "In Progress" needs a slug class.
+    const statusClass = `status-${check.status.toLowerCase().replaceAll(" ", "-")}`;
-  const fixed = checks.filter((check) => check.status === "Fixed").length; // Intentional bug: valid fixed status is "Fixed".
+  const fixed = checks.filter((check) => check.status === "Fixed").length;
-  const dueSoon = checks.filter((check) => daysUntil(check.dueDate) < 7).length; // Intentional bug: this should count items due within 7 days.
+  const dueSoon = checks.filter((check) => daysUntil(check.dueDate) < 7).length;
-  const deleteButton = event.target.closest("[data-delete-id]"); // Intentional bug: button uses data-remove-id.
+  const deleteButton = event.target.closest("[data-delete-id]");
   logActivity(`Changed "${check.title}" to ${check.status}.`);
-  // Intentional bug: status changes should save, update filters, and refresh metrics.
 }
-    const response = await fetch("data/launch-checks.json"); // Intentional bug: real file is data/launch-checks.json.
+    const response = await fetch("data/launch-checks.json");
-    check.title, // Intentional bug: property should be check.title.
+    check.title,

Also applies to: 94-94, 135-140, 173-173, 177-177, 199-199, 239-239, 243-243, 255-255, 287-288, 294-294, 321-321

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@js/app.js` at line 2, Remove the stale "Intentional bug" comments that now
misdescribe correct behavior: search for occurrences of the text "Intentional
bug" and either delete them or rewrite them to accurately describe the current
code (e.g., change the comment on STORAGE_LOAD_KEY to simply document the key
name instead of calling it an intentional bug, and update the validation comment
near validateForm/validateFields to describe what the function actually
enforces). Apply the same cleanup to other markers referencing storage keys
(STORAGE_SAVE_KEY), form validation (validateForm / validateFields), and any
other nearby symbols so comments describe present behavior rather than
historical bugs.


const demoChecks = [
{
Expand Down Expand Up @@ -91,7 +91,7 @@ const activityLog = document.getElementById("activityLog");
let checks = loadChecks();
let currentView = checks;

form.addEventListener("submit", (event) => handleAddChek(event)); // Intentional bug: misspelled function name.
form.addEventListener("submit", (event) => handleAddCheck(event)); // Intentional bug: misspelled function name.
searchInput.addEventListener("input", applyFilters);
statusFilter.addEventListener("change", applyFilters);
priorityFilter.addEventListener("change", applyFilters);
Expand Down Expand Up @@ -132,7 +132,7 @@ function handleAddCheck(event) {
const owner = ownerInput.value.trim() || "Unassigned";
const dueDate = dueDateInput.value || new Date().toISOString().slice(0, 10);

if (!title && !category) {
if (!title || !category) {
// Intentional bug: validation should stop when either required field is missing.
formMessage.textContent =
"Please enter a check title and choose a category.";
Expand Down Expand Up @@ -163,12 +163,17 @@ function applyFilters() {
const selectedStatus = statusFilter.value;
const selectedPriority = priorityFilter.value;

let filtered = checks.filter((check) =>
check.owner.toLowerCase().includes(searchTerm),
let filtered = checks.filter(
(check) =>
check.owner.toLowerCase().includes(searchTerm) ||
check.category.toLowerCase().includes(searchTerm) ||
check.priority.toLowerCase().includes(searchTerm) ||
check.status.toLowerCase().includes(searchTerm) ||
check.title.toLowerCase().includes(searchTerm),
); // Intentional bug: search should include title, category, priority, status, and owner.

if (selectedStatus !== "All") {
filtered = filtered.filter((check) => check.priority === selectedStatus);
filtered = filtered.filter((check) => check.status === selectedStatus);
} // Intentional bug: status filter compares against priority.

if (selectedPriority !== "All") {
Expand All @@ -191,7 +196,7 @@ function renderRows(list) {

const rows = list.map((check) => {
const priorityClass = `priority-${check.priority.toLowerCase()}`;
const statusClass = `status-${check.status.toLowerCase()}`; // Intentional bug: "In Progress" needs a slug class.
const statusClass = `status-${check.status.toLowerCase().replaceAll(" ", "-")}`; // Intentional bug: "In Progress" needs a slug class.

return `
<tr>
Expand All @@ -217,7 +222,7 @@ function renderRows(list) {
)
.join("")}
</select>
<button class="icon-button" type="button" data-remove-id="${check.id}" title="Delete check">
<button class="icon-button" type="button" data-delete-id="${check.id}" title="Delete check">
x
</button>
</span>
Expand All @@ -231,11 +236,11 @@ function renderRows(list) {

function updateMetrics() {
const total = checks.length;
const fixed = checks.filter((check) => check.status === "Complete").length; // Intentional bug: valid fixed status is "Fixed".
const fixed = checks.filter((check) => check.status === "Fixed").length; // Intentional bug: valid fixed status is "Fixed".
const criticalOpen = checks.filter(
(check) => check.priority === "Critical" && check.status !== "Fixed",
).length;
const dueSoon = checks.filter((check) => daysUntil(check.dueDate) > 7).length; // Intentional bug: this should count items due within 7 days.
const dueSoon = checks.filter((check) => daysUntil(check.dueDate) < 7).length; // Intentional bug: this should count items due within 7 days.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

"Due Soon" still counts overdue items.

daysUntil(check.dueDate) < 7 evaluates to true for any past-due item (negative result), so overdue checks are bundled into the "Due Soon" metric. Combined with Math.ceil in daysUntil, you also get an asymmetric boundary: an item due exactly 7 calendar days from now (depending on local time vs. the UTC midnight parsed from YYYY-MM-DD) may or may not be counted.

If the intent is "due in the next 7 days" only, add a lower bound; if "overdue or due within 7 days" is intentional, consider renaming the label so the dashboard isn't ambiguous.

🛠️ Suggested fix
-  const dueSoon = checks.filter((check) => daysUntil(check.dueDate) < 7).length;
+  const dueSoon = checks.filter((check) => {
+    const days = daysUntil(check.dueDate);
+    return days >= 0 && days <= 7;
+  }).length;

Also applies to: 356-361

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@js/app.js` at line 243, The dueSoon filter incorrectly includes overdue items
because it only checks daysUntil(check.dueDate) < 7; update the filter used by
dueSoon (and the other similar filters around the block using daysUntil) to add
a lower bound, e.g. require daysUntil(check.dueDate) >= 0 and <= 7 (or <=6 if
you want an exclusive 7th day), and also review the daysUntil(date)
implementation to return whole-day differences consistently (use floor or
normalize both dates to midnight/UTC) to remove the current asymmetry caused by
Math.ceil.

const score = total === 0 ? 0 : Math.round((fixed / total) * 100);

totalCount.textContent = total;
Expand Down Expand Up @@ -276,7 +281,8 @@ function handleStatusChange(event) {
}

check.status = statusSelect.value;
renderRows(currentView);
saveChecks();
applyFilters();
logActivity(`Changed "${check.title}" to ${check.status}.`);
// Intentional bug: status changes should save, update filters, and refresh metrics.
}
Expand All @@ -285,7 +291,7 @@ async function resetDemoData() {
formMessage.textContent = "";

try {
const response = await fetch("data/launch-seed.json"); // Intentional bug: real file is data/launch-checks.json.
const response = await fetch("data/launch-checks.json"); // Intentional bug: real file is data/launch-checks.json.

if (!response.ok) {
throw new Error(`Demo data request failed with ${response.status}`);
Expand All @@ -312,7 +318,7 @@ function exportCsv() {
"Due Date",
];
const rows = currentView.map((check) => [
check.name, // Intentional bug: property should be check.title.
check.title, // Intentional bug: property should be check.title.
check.category,
check.priority,
check.status,
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"description": "A polished but intentionally broken website launch readiness checker for debugging practice.",
"scripts": {
"dev": "python3 -m http.server 5173",
"start": "python3 -m http.server 5173"
"dev": "python -m http.server 5173",
"start": "python -m http.server 5173"
Comment on lines +7 to +8
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Is python or python3 the standard executable name on macOS 14 and Ubuntu 22.04 by default in 2025?

💡 Result:

On macOS 14 (macOS Sonoma), the standard/Apple-provided executable name is python3 (e.g., /usr/bin/python3). There is no general guarantee that python (without 3) is present or points to Python 3 by default; many systems only provide python3 and recommend not relying on python. [1] On Ubuntu 22.04, the standard OS-provided executable name is also python3 by default (/usr/bin/python3 points to a specific Python 3.x via a symlink). In contrast, the python command (without 3) is typically not available as a default Python 3 interpreter unless the system admin installs/configures a compatibility package (e.g., python-is-python3) or creates alternatives/symlinks. [2][3] So, in 2025 for those defaults: prefer python3 on both macOS 14 and Ubuntu 22.04; python is not the default “standard” executable name in general. [1][2][3]

Citations:


Revert python to python3 for cross-platform compatibility.

Using python instead of python3 breaks portability. On macOS 14 and Ubuntu 22.04 (both common in contributor setups), python is not available by default—only python3 is provided. Most contributors will encounter python: command not found when running npm run dev.

Suggested change
-    "dev": "python -m http.server 5173",
-    "start": "python -m http.server 5173"
+    "dev": "python3 -m http.server 5173",
+    "start": "python3 -m http.server 5173"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"dev": "python -m http.server 5173",
"start": "python -m http.server 5173"
"dev": "python3 -m http.server 5173",
"start": "python3 -m http.server 5173"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@package.json` around lines 7 - 8, Update the package.json npm scripts to use
"python3" instead of "python" for the "dev" and "start" script entries so the
commands ("dev" and "start") work on macOS and Linux systems where only python3
is available; locate the "dev" and "start" script values and replace the
executable name from python to python3 while keeping the rest of the command
("-m http.server 5173") unchanged.

}
}