The Mutation Pit Stop
Welcome to the Garage
Section titled “Welcome to the Garage”Alright, you’ve seen the blueprints for safe mutations and you’ve watched me build an admin console. Now it’s your turn to pick up the tools.
Data destruction and modification are powerful capabilities. If you get it wrong in the real world, you don’t just get a broken page—you lose user data. T.A. Watts is standing by with a clipboard, ready to fail you if you try using a GET request to delete something. Treat every exercise here as if it were a production database.
Tier 1: Maintenance (Easy)
Section titled “Tier 1: Maintenance (Easy)”The Objective: Implement a missing delete route.
Your team has built a frontend fetch() call that sends an HTTP DELETE to /admin/logs/:id. Your job is to catch that request, delete the log from Mongoose, and send a JSON response back.
- Open your
adminRouter.js. - Write the
router.delete()endpoint for/logs/:id. - Use the
Logmodel and callfindByIdAndDelete(). - If the document is null, respond with a
404status. Otherwise, respond with a JSON success message.
Student-to-AI Concept Prompt:
“I built the delete route, but how can I verify that my Mongoose
findByIdAndDelete()method is actually working without building a whole frontend to test it? Explain how I can act as the client using a tool or script.”
Tier 2: The Custom Job (Medium)
Section titled “Tier 2: The Custom Job (Medium)”The Objective: Expand the dual-purpose form.
Your project needs an internal “Notes” field that only admins can see. It shouldn’t be publicly visible, but it needs to be updatable from the project creation/edit form.
- Add a
adminNotesString field to your Mongoose Project schema. - Update your
project-form.ejsto include a new<textarea>for these notes. Ensure it properly uses optional chaining (?.) so it doesn’t crash on the Create view. - Update your POST routes (both create and update) to capture
req.body.adminNotesand pass it to your Ops layer.
Student-to-AI Refactor Prompt:
“I have added three new fields to my EJS form and my Express POST route is getting very long because I am manually mapping
req.body.fieldOne,req.body.fieldTwo, etc. How can I refactor my route handler to cleanly capture all form data while still being safe about what gets saved to the database?”
Tier 3: The Solo Special (Hard)
Section titled “Tier 3: The Solo Special (Hard)”The Objective: The “Soft Delete” Refactor.
Deleting data permanently is dangerous. In many enterprise systems, we don’t actually delete records; we just hide them. This is called a “Soft Delete.”
- Add an
isArchivedBoolean field to your Contact schema (default:false). - Refactor your Delete Button front-end logic. Instead of sending a
DELETErequest, have it send aPOSTrequest to/admin/contacts/:id/archive. - Refactor your Ops layer. Do NOT use
findByIdAndDelete(). Instead, use the Load → Modify → Save pattern to changeisArchivedtotrue. - Update your Admin Inbox view to only display contacts where
isArchivedisfalse.
If you use a GET request for the archive button, I will personally revoke
your admin access. State changes require POST (or PUT/PATCH/DELETE).
Student-to-AI Debug Prompt:
“I refactored my delete logic to perform a ‘Soft Delete’ by updating an
isArchivedboolean. When I click the button, the terminal shows the database updated, but the contact submission doesn’t disappear from my screen until I manually refresh the page. Why did my oldfetch()delete code instantly remove the item, but this new code doesn’t?”
Extra Bits & Bytes
Section titled “Extra Bits & Bytes”Mongoose Docs: Queries
⏭ Next: The Mongoose Codex
Section titled “⏭ Next: The Mongoose Codex”Time to check your gear. Proceed to the Codex for a high-density technical reference of everything we just built.