Ctrl K
ComunidadGuías…

CONTRIBUTING.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Contributing to InfraNet Pro

Welcome. This project is intentionally **low-tooling**: vanilla JS, Node-only,
with a *lightweight* esbuild bundle for the frontend (introduced by the ESM
migration). You can be productive in minutes. Read
`ARCHITECTURE.md` first for the mental model.

## Setup & run

```bash
npm install          # runtime (Express, net-snmp, pdfkit, esbuild…) + dev (eslint, typescript, playwright-core)
npm start            # build the frontend bundle + serve → http://localhost:8421
```

On first launch a default **`admin` / `admin`** account is created — change the
password immediately. The login page is required to reach the app (and the preview
tooling).

## The commands you'll use

```bash
npm run check        # syntax-check every source .js (tools/check-syntax.js)
npm run lint         # ESLint gate — no-undef as a safety net (eslint.config.js)
npm test             # run all tests (node --test, zero dependencies)
npm start            # serve the app
```

`check`, `lint` and `test` must all be green before you commit (the same three
run in CI). `npm run lint:fix` applies the auto-fixable subset. The lint gate is
deliberately scoped: `no-undef` is enforced where the module system is explicit
(Node/CommonJS + the UMD `lib/`), and **off on `src/`** for now (the bundle's
`window` bridge resolves bare names at runtime — it re-enables once that bridge is
retired). Stylistic findings are warnings, not errors, so the gate stays green.

## Conventions (non-negotiable)

1. **Logic in `lib/`, presentation in glue.** Put decision logic in a pure
   UMD-lite module under `lib/` (works in Node + browser) and unit-test it. Keep
   the glue (ESM modules in `src/app-*.js`, bundled by esbuild) thin — it turns
   pure results into DOM. See `ARCHITECTURE.md` §3.
2. **No new runtime dependency** without a strong, discussed reason. The frontend
   build is esbuild-only (a dev dep); keep the pure `lib/*.js` modules UMD-lite so
   the Node tests import them unchanged.
3. **Tests are zero-dependency** — `node --test` only. New pure logic ships with a
   `test/<name>.test.js`.
4. **Manual-first**: never make discovery/SNMP overwrite a user-entered value.
5. **i18n**: any new UI string gets a key in both `it` and `en` in `lib/i18n.js`.
   Use `data-i18n` for static HTML, `t('key')` for JS templates. Never machine-
   translate; leave technical terms and vendor names alone. The key-parity test
   fails if a translation is missing on one side.
6. **Every value interpolated into HTML goes through `escapeHTML()`.** There is no
   framework doing it for you, and the input is not only your keyboard: `sysName`,
   `sysDescr`, DHCP hostnames and LLDP neighbour names come from the devices, i.e.
   from anyone on the network being documented. A static guard
   (`tools/html-escape-scan.js`) proves what it can and ratchets the rest per file,
   so a new raw `${d.sysName}` fails the build. Run
   `node tools/html-escape-scan.js --list` to see where a file's residue is.
7. **Use the design tokens, including for text size.** Sizes come from
   `--fs-2xs…--fs-2xl` in `styles/01-tokens.css` — writing `0.82rem` by hand is the
   same pixel today and a different one the day the token moves, and
   `test/type-scale-ratchet.test.js` fails on it, naming the line and the token to
   use. Same for colour: a badge's ink is derived from its background, never fixed.
   See `styles/README.md`.

## Your first change (worked example)

Add a field to a device, the right way:

1. **Pure logic (if any)** → a function in a `lib/` module + a test in `test/`.
2. **Glue** → render the field in the relevant block of `src/app-properties.js`
   (or the matching `src/app-properties-*.js`).
3. **i18n** → add the label keys to `it` and `en` in `lib/i18n.js`; tag with
   `t('...')` / `data-i18n`.
4. `npm run check && npm run lint && npm test` → all green.
5. **Verify in the browser** (`npm start`, log in): the smoke tests catch crashes
   but **not** visual issues — open the page and look. Switching the language is a
   good way to surface JS-rewritten text that bypassed i18n.

## Commit & PR

- **Commit messages**: conventional style (`feat(...)`, `fix(...)`, `refactor(...)`,
  `docs(...)`).
- **Never commit** secrets or user data — `users.json`, `.session-secret`,
  `projects/`, `.env` are git-ignored; keep it that way.
- Keep PRs focused; a green `check` + `lint` + `test` is the bar.

## Where things live (quick map)

| You want to… | Look in |
|---|---|
| Add/adjust device types | `src/app-types.js`, `src/app-properties.js`, `netmapper.html` (palette) |
| Change rendering of the rack/floor/cables | `src/app-render-core.js`, `src/app-topology-overlay.js` |
| Touch SNMP polling/discovery | `drivers/snmp.js`, `server/routes/discovery.js`, `src/app-snmp.js` |
| Classification (sysObjectID / OUI) | `engine/`, `plugins/` |
| Translations | `lib/i18n.js` |
| CSS, design tokens, the type scale | `styles/` (start from `styles/README.md`) |
| Backend routes / storage | `server/` |

Thanks for keeping it simple. The lack of tooling is a feature — please preserve it.