| name | api-websocket-routes |
| description | Add, refactor, or debug backend WebSocket routes, handlers, router, queue logic, and report PDF generation. Use when implementing new WS routes in api/app.js or updating the document generation helper in api/helpers/document-builder.js. |
API WebSocket Routes
Use this skill when adding or refactoring API communication routes, handling task queuing, or building generated PDF documents.
Scope
Core Rules
- Use the Route Helper: Never listen directly on the WebSocket server. Always register endpoints by constructing a
new Route(name, handler) instance in api/app.js.
- WebSocket Message Schema: Messages must conform to the JSON contract:
- Client sends:
{ id, method, payload }
- Server returns:
{ id, data }
- Queue Awareness: Every
Route handler automatically runs inside the static task Queue. The queue handles:
- Reporting
'in queue' status and line position back to the client immediately.
- Reporting
'processing' status when execution starts.
- Catching runtime exceptions and responding with standard JSON error shapes (
{ error: 'message' }).
- Data Isolation inside Models: Route callbacks should keep business logic focused. Instantiation and heavy lifting (like scraping or parsing) must be deferred to model classes (e.g.
Professor, Book, Report).
- Document Building: To generate teaching certificates, feed extracted model records to
DocumentBuilder to map placeholders like {{professorName}} against templates in api/template/. Convert compilation results to base64 PDFs using SUAPScraper.generatePDF(html).
- TDD & Native Testing: When implementing, modifying, or refactoring WebSocket routes, the queue logic, or the document builder, you MUST write the test cases first under
api/test/ using the native Node.js test runner.
Guardrails
- Never write route logic that returns naked text; always return structured JSON objects containing requested keys or status codes.
- Do not let route tasks block indefinitely; if downstream scraper fails, handle errors gracefully inside the router try/catch block.
- Keep
DocumentBuilder variables structured; nested objects in templates are formatted as {{prefix.property}}.
- Testing Guardrail: A task is only complete when all tests pass. Never declare a feature done without running tests first. Run the API test suite with:
docker compose exec api npm test.
Review Checklist
- Is the new route instantiated using the
new Route pattern?
- Are inputs validated before being passed to models?
- Does the return statement return a structured object?
- Are HTML document variables correctly registered and mapped in
api/helpers/document-builder.js?
- Testing: Have unit/integration tests been created/updated for the modified or new logic?
- Execution: Did you run
docker compose exec api npm test and verify all tests passed successfully?