Code Documentation Standards
This document defines the documentation standards for inline code comments, JSDoc annotations, module documentation, and API reference formatting across the MiningOS ecosystem.
For code style and linting requirements, see Testing & Linting Guidelines.
Overview
Well-documented code is essential for maintaining a complex distributed system like MiningOS. Documentation serves multiple audiences: contributors, future maintainers, API consumers, and operators configuring deployments.
Documentation Philosophy
MiningOS follows these documentation principles:
| Principle | Description |
|---|---|
| Self-documenting code first | Clear naming and structure reduce comment needs |
| Document the "why" | Code shows "what" and "how"; comments explain "why" |
| Keep it current | Outdated documentation is worse than none |
| Audience-aware | Match detail level to the reader's needs |
When to Document
Always Document
- Public APIs (RPC methods)
- Configuration options
- Error codes and meanings (see Contribution Workflow — Error Handling)
- External integrations
Consider Documenting
- Complex algorithms
- Non-obvious decisions
- Performance optimizations
- Workarounds and edge cases
Skip Documentation
- Obvious operations
- Self-explanatory getters or setters
- Standard patterns
- Trivial utility functions
File Headers
Every JavaScript file begins with 'use strict' followed by appropriate header documentation. For the complete file structure, see Repository Structure — Standard Directory Structure.
Standard Header Pattern
'use strict'
/**
* @fileoverview Brief description of the file's purpose.
* @module module-name
*/Worker File Headers
Worker entry points include operational context:
'use strict'
/**
* @fileoverview PowerMeter Rack Worker - Manages power monitoring devices.
*
* This worker handles:
* - Device discovery and registration
* - Real-time data (RTD) collection at 5-second intervals
* - Snapshot aggregation at 60-second intervals
* - Modbus communication with power meters
*
* @module rack.powermeter.wrk
* @extends miningos-tpl-wrk-powermeter
* @see {@link https://github.com/tetherto/miningos-tpl-wrk-powermeter}
*/
const WrkPowerMeterRack = require('miningos-tpl-wrk-powermeter')
// ...For supported power meter models and specifications, see Supported Devices — Power Meters.
Library File Headers
Library modules document their exports and dependencies:
'use strict'
/**
* @fileoverview Device controller for Schneider PM5340 power meters.
*
* Implements Modbus TCP communication for:
* - Voltage, current, power readings
* - Energy counters (import/export)
* - Power quality metrics (THD, power factor)
*
* @module lib/schneider-pm5340
* @requires modbus-tcp
*/JSDoc Annotations
MiningOS uses JSDoc for function and class documentation. While Standard.js doesn't enforce JSDoc, consistent usage improves code navigation and IDE support.
Function Documentation
/**
* Collects a snapshot from the specified device.
*
* @async
* @param {Object} thg - The thing (device) object
* @param {string} thg.id - Unique device identifier
* @param {Object} thg.ctrl - Device controller instance
* @param {Object} [thg.opts] - Device-specific options
* @returns {Promise<Object>} Snapshot containing stats and config
* @throws {Error} ERR_THING_NOTFOUND if device does not exist
*
* @example
* const snap = await worker.collectThingSnap(device)
* // Returns: { stats: {...}, config: {...}, timestamp: 1234567890 }
*/
async collectThingSnap(thg) {
// Implementation
}For error code conventions, see Contribution Workflow — Error Handling.
Class Documentation
/**
* Represents a Whatsminer M56S miner controller.
*
* Handles communication with Whatsminer devices via the
* proprietary API protocol (TCP port 4028).
*
* @class
* @extends BaseMiner
*
* @property {string} address - Device IP address
* @property {number} port - API port (default: 4028)
* @property {number} timeout - Connection timeout in ms
*
* @example
* const miner = new WhatsminerMiner({
* address: '192.168.1.100',
* port: 4028,
* password: 'admin'
* })
* await miner.connect()
*/
class WhatsminerMiner extends BaseMiner {
// Implementation
}For Whatsminer specifications, see Supported Devices — MicroBT Whatsminer.
Type Definitions
Define complex types for reuse across documentation:
/**
* @typedef {Object} MinerStats
* @property {number} hashrate_mhs - Current hashrate in MH/s
* @property {number} power_w - Power consumption in watts
* @property {Object} temperature_c - Temperature readings
* @property {number} temperature_c.board - Board temperature
* @property {number} temperature_c.chip - Chip temperature
* @property {string} status - Operating status ('mining', 'idle', 'offline')
*/
/**
* @typedef {Object} PoolConfig
* @property {string} url - Pool URL (stratum+tcp://...)
* @property {string} user - Pool username/worker
* @property {string} [pass='x'] - Pool password
*/For pool configuration in production, see Operator Manual — Pool Manager Module.
Common JSDoc Tags
| Tag | Usage | Example |
|---|---|---|
@async* | Async functions | @async |
@param | Function parameters | @param \{string\} id - Device ID |
@returns | Return value | @returns \{Promise<Object>\} |
@throws | Possible errors | @throws \{Error\} ERR_INVALID_SOMETHING |
@example | Usage examples | See above |
@private | Internal methods | @private |
@deprecated | Deprecated features | @deprecated Use newMethod instead |
@see | Related resources | @see \{@link otherFunction\} |
@since | Version introduced | @since 1.2.0 |
*Available in JSDoc 3.5.0 and later
For more information and to learn about custom tags, check out the JSDoc official website.
Inline Comments
Inline comments explain non-obvious code behavior. They should add value beyond what the code already communicates.
When to Use Inline Comments
Use comments for:
The examples below highlight application of doctrine stated in Overview:
// Whatsminer requires a 200ms delay between commands
// to prevent API rate limiting
await sleep(200)
// MongoDB aggregation: group by container, sum hashrates
// $unwind expands the workers array for individual matching
const pipeline = [
{ $unwind: '$workers' },
{ $group: { _id: '$container', total: { $sum: '$hashrate' } } }
]
// Edge case: some S19 firmware returns temperature as string
const temp = typeof raw.temp === 'string' ? parseFloat(raw.temp) : raw.tempComment Style Guidelines
// GOOD: Explains why, not what
// Retry with exponential backoff to handle temporary network issues
for (let i = 0; i < 3; i++) {
await sleep(Math.pow(2, i) * 1000)
}
// BAD: States the obvious
// Increment counter by 1
counter++
// BAD: Outdated comment (code changed, comment did not)
// Check if device is online
if (device.status === 'mining') { // Actually checks mining status nowSection Markers
Use section markers for long files to improve navigation:
// =============================================================================
// RPC Methods
// =============================================================================
async listThings(req) { /* ... */ }
async queryThing(req) { /* ... */ }
// =============================================================================
// Internal Helpers
// =============================================================================
_validateRequest(req) { /* ... */ }
_formatResponse(data) { /* ... */ }
// =============================================================================
// Lifecycle Methods
// =============================================================================
async _start(cb) { /* ... */ }
async _stop(cb) { /* ... */ }Anti-Patterns to Avoid
| Anti-Pattern | Example | Problem |
|---|---|---|
| Commented-out code | // await oldMethod() | Use version control instead |
| Journal comments | // Fixed bug - John 2024-01-15 | Use git history (see Branching & PR Conventions |
| Noise comments | // End of function | Adds no value |
| Lying comments | Comment says X, code does Y | Misleads readers |
| Excessive comments | Every line commented | Obscures the code |
Constants Documentation
Constants files serve as authoritative references for magic values throughout the codebase.
Constant Object Documentation
'use strict'
/**
* @fileoverview Mining operation constants and configuration values.
* @module lib/constants
*/
/**
* Default nominal efficiency ratings by miner model (W/TH).
* Used for power estimation when actual readings are unavailable.
*
* Values sourced from manufacturer specifications:
* - Bitmain: https://shop.bitmain.com/
* - MicroBT: https://www.microbt.com/
*
* @type {Object.<string, number>}
*/
const DEFAULT_NOMINAL_EFFICIENCY_WTHS = {
'miner-am-s19xp_h': 20.8, // Antminer S19 XP Hyd
'miner-am-s19xp': 21, // Antminer S19 XP
'miner-am-s21': 17.5, // Antminer S21
'miner-am-s21pro': 17, // Antminer S21 Pro
'miner-wm-m56s': 22, // Whatsminer M56S
'miner-av-a1346': 30 // Avalon A1346
}For the complete list of supported models and specifications, see Supported Devices.
Enumeration-Style Constants
/**
* Device operational states.
* These values are used across all device types for status reporting.
*
* @readonly
* @enum {string}
*/
const MINER_STATUS = {
/** Miner is unreachable or not responding */
OFFLINE: 'offline',
/** Miner is in low-power sleep mode */
SLEEPING: 'sleeping',
/** Miner is actively mining/operating */
MINING: 'mining',
/** Miner reported an error condition */
ERROR: 'error',
/** Miner is powered but not operating */
NOT_MINING: 'not_mining'
}For how these statuses appear in the UI, see Operator Manual — Explorer.
Configuration Constants
/**
* Time intervals used throughout the system.
* All values are in milliseconds unless otherwise noted.
* @namespace
*/
const intervals = {
/** Snapshot collection interval (60 seconds) */
collectSnapMs: 60 * 1000,
/** RTD collection interval (5 seconds) - power meters only */
collectRTDMS: 5 * 1000,
/** Log rotation check interval (2 minutes) */
rotateLogsMs: 2 * 60 * 1000,
/** Action timeout for voting system (24 hours) */
actionTimeoutMs: 24 * 60 * 60 * 1000
}README Documentation
Every repository requires a README.md with standardized sections. For the complete repository structure, see Repository Structure.
README Structure
# repository-name
Brief description of the worker's purpose.
## Overview
Extended description including:
- Position in inheritance hierarchy (see [Architecture](../about-miningos/architecture)
- Key responsibilities
- Supported device types/models (see [Supported Devices](../about-miningos/supported-devices)
## Dependencies
- Parent worker: `miningos-tpl-wrk-<type>`
- External services: List any APIs, protocols
- System requirements: Node.js version, OS
## Installation
[Installation steps - see Installation Guide](../install-miningos)
## Configuration
[Configuration file documentation]
## Usage
[Startup commands, CLI examples]
## RPC API Reference
[Full RPC method documentation]
## Development
[Test commands, adding features - see Testing & Linting Guidelines](./testing-and-linting-guidelines)
## Troubleshooting
[Common issues and solutions]
## License
[License information - see License Section below]API Reference Sections
Structure RPC documentation consistently. Example with a single method:
## RPC API Reference
### Read Operations
#### `listThings`
Returns all registered device IDs.
**Operation:** Read
**Request:**
```json
\{\}
```
**Response:**
```json
["miner-001", "miner-002", "miner-003"]
```
**Errors:** NoneCode Examples in README
Provide practical, copy-paste-ready examples:
### Example: Register and Query a Miner
```bash
# 1. Register the miner
hp-rpc-cli -s $WORKER_PUBKEY -m registerThing -d '\{
"id": "s19-rack1-01",
"addrIPv4": "192.168.1.100",
"opts": \{ "port": 4028, "password": "admin" \},
"info": \{ "position": "rack-1-slot-1", "container": "container-a" \},
"tags": ["production", "building-1"]
\}'
# 2. Verify registration
hp-rpc-cli -s $WORKER_PUBKEY -m getThing -d '\{"id": "s19-rack1-01"\}'
# 3. Collect current stats
hp-rpc-cli -s $WORKER_PUBKEY -m queryThing -d '\{
"id": "s19-rack1-01",
"method": "getStats"
\}'
```For complete RPC registration examples, see Installation Guide — Register Workers.
Above, an example of Markdown syntax for copy-paste-ready excerpt for code in bash (for convenience, the example itself is in copy-paste-ready format).
License Section
All MiningOS repositories must include a License section and be released under the Apache License 2.0. This is mandatory for ecosystem consistency and legal clarity.
Required License Section Format
## License
This project is licensed under the Apache License 2.0 - see the [LICENSE](https://www.apache.org/licenses/LICENSE-2.0.html) file for details.
Copyright © [YEAR] Tether Operations LimitedThe Apache 2.0 license was chosen for MiningOS to enable broad adoption while providing patent protection and requiring attribution. All contributions to MiningOS repositories are subject to this license.
Error Message Documentation
Consistent error documentation helps operators diagnose issues quickly. For error handling patterns in code, see Contribution Workflow — Error Handling.
Error Code Registry
Maintain a central error code reference:
/**
* @fileoverview Error codes used across MiningOS workers.
*
* Error code format: ERR_{CATEGORY}_{SPECIFIC}
*
* Categories:
* - THING: Device-related errors
* - RACK: Worker registration errors
* - ACTION: Action/voting system errors
* - PARAM: Parameter validation errors
* - PERM: Permission errors
*/
/**
* Error codes and their descriptions.
* @type {Object.<string, string>}
*/
const ERROR_CODES = {
// Thing errors
ERR_THING_ID_INVALID: 'Device ID is missing or not a valid UUID',
ERR_THING_NOTFOUND: 'Device with specified ID is not registered',
ERR_THING_OFFLINE: 'Device is not responding to API requests',
// Permission errors
ERR_SLAVE_BLOCK: 'Write operations are not allowed on slave nodes',
ERR_MISSING_WRITE_PERMISSIONS: 'Client lacks write permission for this operation',
// Action errors
ERR_ACTION_NOTFOUND: 'Action ID does not exist',
}For how errors appear in the operator interface, see Operator Manual — Alerts Manual.
Error Context
When throwing errors, include helpful context:
// GOOD: Error with context
if (!this.mem.things[req.id]) {
const err = new Error('ERR_THING_NOTFOUND')
err.context = { requestedId: req.id, availableCount: Object.keys(this.mem.things).length }
throw err
}
// GOOD: Descriptive error for debugging
if (response.status !== 200) {
throw new Error(`ERR_DEVICE_API_FAILED: ${response.status} - ${response.statusText}`)
}Documentation Maintenance
Documentation Review Checklist
Before submitting a PR (see Branching & PR Conventions — PR Checklist), verify documentation is complete:
- New RPC methods have JSDoc annotations
- New RPC methods are documented in README
- Error codes are added to error registry
- Constants have descriptive comments
- Configuration options are documented
- Complex logic has explanatory comments
- No commented-out code remains
- No outdated comments exist
- Examples are tested and working
- LICENSE file present and correct