Tool Build SOP

Tool Build SOP

Standards derived from the Hermes (Social Poster) audit: 41 bugs found, 34 fixed. These are now non-negotiable for all Artemis Netlify tools.

Backend Non-Negotiables

v2 Function Format

All serverless functions must use the Netlify v2 function format. Legacy v1 format is not permitted.

Environment Variables

Use Netlify.env.get() — never process.env. The latter does not reliably resolve in Netlify's v2 runtime.

CORS on Every Response Path

CORS headers must be present on every response, including error responses, 404s, and catch blocks. A missing CORS header on an error path produces a silent browser failure with no useful error message.

Auth Gate First

Authentication check must be the first operation in every function. No database reads, no API calls, no business logic before auth is verified.

Request Parsing

Wrap req.json() in try/catch. Malformed request bodies must return a 400 with a descriptive message, not crash the function.

Sentry in All Catch Blocks

Every catch block must report to Sentry. Untracked errors are invisible errors. Include context (function name, input parameters where safe) in the Sentry payload.

Frontend Non-Negotiables

XSS Prevention

Never use innerHTML with user-supplied data. Escape all dynamic content or use DOM APIs (.textContent, .value).

Textarea Values

Read textarea content with .value, not .textContent or .innerHTML. The latter returns stale or empty data.

Confirmation Modals

Any destructive action (delete, overwrite, publish) requires a confirmation modal. No single-click destructive operations.

Rate Limiting

Minimum 8-second cooldown between repeated API calls from the frontend. Prevents accidental double-submissions and protects API quotas.

Storage Standards

Netlify Blobs

  • Seed with sensible defaults on first access
  • Save after each mutation, not in batches
  • Handle missing/corrupt blob data gracefully (fall back to defaults)

Cloudinary

Use Cloudinary for all permanent image URLs. Netlify Blobs are not a CDN — images stored there will have inconsistent availability. Cloud: dbxz8xmbr, preset: artemis_social (unsigned).

Testing & Deployment

Health Endpoint

Every tool must expose a /api/health endpoint that checks connectivity to all external APIs (Cloudinary, Sentry, any third-party service). Returns 200 with service status or 503 with failure details.

Smoke Test Script

A post-deploy smoke test script must exist and run after every deployment. Tests: health endpoint, auth flow, one happy-path operation, one error-path operation.

Deploy Command

Always use npm_config_cache=/tmp/npm-cache to avoid Netlify permission errors.

Checklist Summary

Before any tool ships or passes audit:

  • v2 function format
  • Netlify.env.get() everywhere
  • CORS on all response paths
  • Auth gate first in every function
  • try/catch on req.json()
  • Sentry in all catch blocks
  • No innerHTML with user data
  • .value for textareas
  • Confirmation modals on destructive actions
  • 8s+ rate limiting
  • Blobs seeded with defaults
  • Cloudinary for permanent images
  • Health endpoint live
  • Smoke test passes post-deploy

See listing-marketing-engine for the next tool build applying these standards.