From dev-agents
Coding patterns and conventions for this stack. Follow these exactly — consistency beats preference.
How this skill is triggered — by the user, by Claude, or both
Slash command
/dev-agents:php-node-conventionsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Coding patterns and conventions for this stack. Follow these exactly — consistency beats preference.
Coding patterns and conventions for this stack. Follow these exactly — consistency beats preference.
php -v)echo or var_dump in production paths — use structured loggingdisplay_errors = Off)// Throw typed exceptions, not generic ones
throw new \InvalidArgumentException("Client ID must be a positive integer, got: $id");
// Log errors with context, do not swallow them
try {
$result = $this->db->query($sql);
} catch (\PDOException $e) {
$this->logger->error('DB query failed', [
'sql' => $sql,
'error' => $e->getMessage(),
]);
throw $e; // re-throw — do not silently swallow
}
/www/wwwroot/<app>/
src/ # application code
public/ # web root (only entry point exposed to nginx)
config/ # environment-specific config (not committed)
logs/ # app-level logs (symlink or separate from nginx logs)
node -v on server)"type": "module" in package.json) for new codeconsole.log in application code — use pino exclusivelyEvery Node.js app must use pino with this base config:
import pino from 'pino';
export const logger = pino({
level: process.env.LOG_LEVEL ?? 'info',
base: {
app: process.env.APP_NAME,
env: process.env.NODE_ENV,
},
timestamp: pino.stdTimeFunctions.isoTime,
});
Log at the right level:
logger.info — normal operationslogger.warn — recoverable issues, degraded statelogger.error — failures that need attention, always include err fieldlogger.debug — development only, never leave in production paths// Always include the error object as `err` field for pino serialization
logger.error({ err }, 'Failed to process request');
// Unhandled rejection safety net — log and exit cleanly
process.on('unhandledRejection', (err) => {
logger.fatal({ err }, 'Unhandled rejection — shutting down');
process.exit(1);
});
process.env with explicit defaults, never assume variables existconst required = ['DATABASE_URL', 'APP_SECRET', 'PORT'];
for (const key of required) {
if (!process.env[key]) throw new Error(`Missing required env var: ${key}`);
}
/www/wwwroot/<app>/
src/
index.js # entry point
routes/ # route handlers
services/ # business logic
lib/ # shared utilities
config/ # env-specific config
package.json
ecosystem.config.cjs # PM2 config if applicable
Interpolating user input into SQL — always use prepared statements. "SELECT * FROM users WHERE id = $id" is an injection waiting to happen regardless of how the input looks.
Swallowing exceptions silently — catch (\Exception $e) { } hides real failures. Log and re-throw, or handle explicitly. Never catch and do nothing.
Using echo or var_dump in application paths — these leak internal state in production. Use structured logging. Remove all debug output before committing.
Cross-querying client databases — each client has its own DB. A query that joins or reads across client DBs violates data isolation. There are no exceptions.
Exposing the app root to nginx — only public/ should be the nginx web root. Pointing nginx at the app root exposes source files, config, and logs.
Using console.log in application code — pino is the logger. console.log doesn't serialize errors correctly, has no log levels, and goes to the wrong output in PM2. Replace it.
Assuming env vars exist — process.env.DATABASE_URL is undefined if the var isn't set. Validate all required vars at startup and fail fast. Silent undefineds become mysterious runtime errors.
Using CommonJS in new code — new Node.js code uses ESM (import/export). Don't introduce require() in new files unless integrating with a legacy module that forces it.
Unhandled promise rejections — an unhandled rejection that crashes PM2 silently restarts the process. Always have a process.on('unhandledRejection') handler and log before exiting.
Leaving logger.debug calls in production paths — debug logging is for development. Production log noise makes real errors harder to find.
npx claudepluginhub tiagokrebs/claude-agentic-platform --plugin dev-agentsNode.js runtime conventions, APIs, and ecosystem patterns. Invoke whenever task involves any interaction with Node.js runtime — server code, CLI tools, scripts, module system, streams, process lifecycle, or package configuration.
Provides expert Node.js backend patterns for Express, NestJS, Fastify APIs including project structures, async error handlers, custom error classes, and global error handling.
Provides 12-Factor App principles with PHP implementations, container-first patterns, and env config guidance for cloud-native architecture audits.