express-js/skills/skills/public-endpoint-builder/SKILL.md
Create public (unauthenticated) API endpoints for existing Express.js + MongoDB resources. Generates list and detail controllers with aggregation pipelines, and wires them into the public routes file. Use this skill whenever the user wants to add a public endpoint, create a storefront/frontend API, expose a resource publicly, add a public route, or says things like "I need a public page for products" or "create a frontend API for articles" or "add a public list endpoint for reviews".
npx skillsauth add spuneiartur/claude-agent-specs public-endpoint-builderInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Creates public (unauthenticated) read endpoints for existing resources. Public endpoints live in controllers/public/ and routes/public.js, separate from admin CRUD. They often use aggregation pipelines, populate related data, and have different response shapes than admin endpoints.
| Aspect | Admin CRUD | Public Endpoints |
|--------|-----------|-----------------|
| Auth | Protected by middleware.authenticate | No auth (under /public/ prefix which gets speed limiter) |
| Location | controllers/{resource}/ | controllers/public/ |
| Routes | routes/{resource}.js | routes/public.js |
| Operations | Full CRUD | Read-only (GET) |
| Data shape | Direct model queries | Often aggregation pipelines with $lookup |
| Filtering | Admin filters | May add isActive: true or similar |
Read references/naming-guide.md for full details.
get-{resources}.js — lightweight list endpoint (for dropdowns, selectors, simple lists)view-page-{resources}.js — full list page with pagination, filtering, complex dataview-page-{resource}.js — single resource detail page (by slug, with populated relations)Gather from the user:
view-page-{resources} or get-{resources}view-page-{resource}Read references/public-patterns.md for complete examples.
controllers/public/get-{resources}.jsFor lightweight lists (dropdowns, simple lists). Uses basic .find():
import { {Resource} } from '@models';
export default async (req, res) => {
const documents = await {Resource}.find({ isActive: true }).select('name slug').lean();
return res.status(200).json(documents);
};
controllers/public/view-page-{resources}.jsFor paginated list pages with filtering. Uses aggregation pipeline:
import { applyFilters{Resource} } from '@filters';
import { {Resource} } from '@models';
export default async (req, res) => {
const page = parseInt(req.query.page, 10) || 1;
const perPage = parseInt(req.query.perPage, 10) || 10;
const filters = {
...applyFilters{Resource}(req.query),
isActive: true,
};
const totalCount = await {Resource}.countDocuments(filters);
const documents = await {Resource}.aggregate([
{ $match: filters },
// Add $lookup stages for related data if needed
{ $skip: (page - 1) * perPage },
{ $limit: perPage },
]);
const pageParams = {
count: totalCount,
hasNext: page * perPage < totalCount,
page,
perPage,
};
return res.status(200).json({ pageParams, pages: documents });
};
controllers/public/view-page-{resource}.jsFor single resource pages (by slug). Uses aggregation to populate relations:
import { error } from '@functions';
import { {Resource} } from '@models';
export default async (req, res) => {
const { slug } = req.params;
if (!slug) {
throw error(400, 'Slug is required');
}
const result = await {Resource}.aggregate([
{ $match: { slug } },
// Add $lookup stages for related data
// Add $addFields for computed fields
// Add $project to exclude temporary fields
]);
if (result.length === 0) {
throw error(404, '{Resource} not found');
}
return res.status(200).json(result[0]);
};
$lookup{
$lookup: {
from: '{collection_name}', // MongoDB collection name (usually plural + underscore)
localField: '{refField}._id',
foreignField: '_id',
as: '{refField}Data',
},
},
{
$addFields: {
{refField}: {
$mergeObjects: ['${refField}', { $arrayElemAt: ['${refField}Data', 0] }],
},
},
},
{
$project: {
{refField}Data: 0,
},
},
In controllers/public/index.js, add the new exports in A-Z order:
export { default as get{Resources} } from './get-{resources}';
export { default as viewPage{Resource} } from './view-page-{resource}';
export { default as viewPage{Resources} } from './view-page-{resources}';
In routes/public.js, add routes under a comment section for the resource:
// {Resources}
router.get('/public/get-{resources}', Public.get{Resources});
router.get('/public/view-page-{resources}', diacriticInsensitive(['search']), Public.viewPage{Resources});
router.get('/public/view-page-{resource}/:slug', Public.viewPage{Resource});
Add diacriticInsensitive(['search']) to list endpoints that support text search.
/public/ prefixisActive: true filter when the model has an isActive field'{Resource} not found', 'Slug is required'references/public-patterns.md — Real public controller examples from the codebasereferences/naming-guide.md — When to use get-X vs view-page-X namingtools
Replace with description of the skill and when Claude should use it.
tools
Comprehensive website performance audit and optimization skill. Identifies and automatically fixes performance issues including image optimization, video compression, lazy loading, Core Web Vitals, bundle size, and rendering strategy. Uses Lighthouse (via CLI or MCP when available), ffmpeg for media processing, and the project's existing Image component with blur-up lazy loading. Use this skill whenever the user mentions: website speed, page load time, performance audit, Core Web Vitals, Lighthouse, optimize images, compress videos, lazy loading, LCP, CLS, FID, INP, slow website, speed up, performance optimization, image compression, video optimization, blur placeholder, WebP conversion, media audit, bundle size, or wants to improve their website's loading performance. Also trigger when the user says "my site is slow", "optimize for speed", "reduce load time", "improve performance", or asks about image/video optimization in any context.
tools
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
tools
Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn/ui). Use for complex artifacts requiring state management, routing, or shadcn/ui components - not for simple single-file HTML/JSX artifacts.