Files
Emberfall/docs/CODING_STANDARDS.md

2.3 KiB

CODING_STANDARDS.md

Language & style

  • Node 20+, CommonJS, 'use strict' not needed in CJS modules but harmless.
  • 2-space indent, semicolons, single quotes, trailing commas in multiline literals.
  • const by default; let only if reassigned; never var.
  • Names: camelCase functions/vars, PascalCase classes, UPPER_SNAKE constants, snake_case DB columns.
  • Convert DB snake_case rows → camelCase objects at the service boundary (one small mapper per entity).
  • Functions do one thing and fit on a screen (< 40 lines). Early returns over deep nesting.
  • Comments explain why, not what. Add a one-line header comment to each file describing its purpose.

Errors

Create src/utils/errors.js:

class AppError extends Error {
  constructor(code, message, status = 400) { super(message); this.code = code; this.status = status; }
}
  • Services throw AppError for expected failures (new AppError('INSUFFICIENT_ENERGY','Not enough energy.',422)).
  • Routes use an async wrapper so thrown errors reach errorHandler:
const wrap = (fn) => (req, res, next) => Promise.resolve(fn(req, res, next)).catch(next);
  • errorHandler maps AppError → envelope; ZodError → 400 VALIDATION_ERROR; anything else → 500 generic message + server log.

Pure game code

  • src/game/* exports plain functions; no I/O; no Date.now(); no Math.random() — take rng / nowMs params.
  • Return new objects instead of mutating inputs.

Database access

  • One prepared statement per query, created once at module load (or lazily cached), not inside loops.
  • Wrap multi-write operations in db.transaction.
  • Never SELECT * in services for public output; select what you return.

Frontend JS

  • public/js/api.js exports a small api(method, path, body) wrapper that handles JSON, error envelope, and 401 → redirect to login.
  • DOM updates via textContent / createElement. No innerHTML with dynamic data.
  • One JS file per page + shared api.js and ui.js (toasts, formatting).
  • No global state beyond a single state object per page.

Logging

src/utils/logger.js: tiny wrapper over console with levels; silent in tests unless LOG=1.

Dependencies

Pinned in package.json via npm install --save-exact. No dependency without need (NOTES.md §2.3).