// YOUR DELIVERABLE:
## Diagnosis
What did you observe?
How did you reproduce it?
What DevTools technique found it?
## Root Cause
Which CSS rule is broken?
Why does it only affect <1024px?
## Fix
The exact CSS change.
(Show the before and after)
## Verification
Tested on: 320px, 768px, 1024px,
1440px viewports.
Screenshot or description of each.
## Commit
git commit -m "Fix toolbar overlap
on mobile viewports (#BUG-1)
The toolbar flex container was using
flex-direction: row below 1024px
instead of column, causing it to
overflow the canvas area.
Tested: 320px, 768px, 1024px, 1440px.
Closes #BUG-1"
// YOUR DELIVERABLE:
## Diagnosis
Steps to reproduce:
1. Apply filter A
2. Apply filter B
3. Apply filter C
4. Undo (→ shows B ✅)
5. Undo (→ shows A ✅)
6. Redo (→ should show B, shows C ❌)
## Root Cause
Where is the off-by-one?
Is it in undo, redo, or pushHistory?
Show the exact line with the error.
## Fix
The corrected index logic.
Explain WHY the fix is correct.
## Verification
Tested the sequence above.
Tested: undo all → redo all.
Tested: undo 2, new edit, redo
(should have nothing to redo).
## Unit Test
Add a test that would have caught
this bug. If the test passes,
the bug can never return.
// YOUR DELIVERABLE:
## Diagnosis
Stack trace analysis:
Which line? Which variable is undefined?
Which file types trigger it?
(Hint: try uploading a .svg or .webp)
## Root Cause
The middleware accesses a property
that doesn't exist for certain
MIME types. Which property? Why does
it exist for JPEG but not SVG?
## Fix
Add a guard check or handle
the missing property. Show code.
## Verification
Tested: upload JPEG ✅
Tested: upload PNG ✅
Tested: upload SVG ✅ (was crashing)
Tested: upload WebP ✅
Tested: upload invalid file → proper
error message, no crash
// YOUR DELIVERABLE:
## Diagnosis
Reproduce: logged in as User A,
access GET /api/images/:idOfUserB
→ Returns User B's private image!
## Root Cause
The endpoint fetches by image ID
but never checks if the requesting
user is the owner.
## Fix
// BEFORE (vulnerable):
app.get('/api/images/:id', async (req, res) => {
const image = await db.collection('images')
.findOne({ _id: id });
res.json(image);
});
// AFTER (secure):
app.get('/api/images/:id', async (req, res) => {
const image = await db.collection('images')
.findOne({
_id: id,
$or: [
{ userId: req.user.id },
{ public: true },
],
});
if (!image) return res.status(404)
.json({ error: 'Not found' });
res.json(image);
});
## Verification
User A accessing own image: ✅
User A accessing User B private: 404 ✅
User A accessing public image: ✅
Unauthenticated accessing public: ✅
Unauthenticated accessing private: 404 ✅
// YOUR DELIVERABLE:
## Diagnosis
// BEFORE (N+1):
const images = await db
.collection('images')
.find({ public: true })
.limit(100).toArray();
// 100 additional queries:
for (const img of images) {
img.author = await db
.collection('users')
.findOne({ _id: img.userId });
}
// Total: 101 queries. 4 seconds.
## Fix
// AFTER (aggregation pipeline):
const images = await db
.collection('images')
.aggregate([
{ $match: { public: true } },
{ $limit: 100 },
{ $lookup: {
from: 'users',
localField: 'userId',
foreignField: '_id',
as: 'authorInfo',
}},
{ $unwind: '$authorInfo' },
{ $project: {
title: 1, url: 1,
'author': '$authorInfo.name',
}},
]).toArray();
// Total: 1 query. 50ms.
## Verification
Before: 101 queries, 4000ms
After: 1 query, 50ms
80× improvement.
// YOUR DELIVERABLE:
## Data Model
interface Bookmark {
userId: string;
imageId: string;
tags: string[];
createdAt: Date;
}
// Index: { userId: 1, imageId: 1 }
// unique compound index
## API
POST /api/bookmarks
{ imageId, tags }
DELETE /api/bookmarks/:imageId
GET /api/bookmarks
?tag=favorites
GET /api/bookmarks/tags
→ ["favorites", "inspiration", ...]
## Frontend
- Bookmark icon on each image card
- Click → toggle bookmark (filled/empty)
- Tag input: add/remove tags
- Filter bar: click a tag to filter
- "My Bookmarks" page
## Tests
- Bookmark an image ✅
- Remove a bookmark ✅
- Filter by tag ✅
- Duplicate bookmark → 409 ✅
- Bookmark other user's public image ✅
- Bookmark other user's private → 404 ✅
AI maturity: the real skill being tested.
Using AI isn't cheating. Using AI without understanding IS. The exam tests whether you can justify, verify, and take responsibility for AI-assisted solutions.