Skip to content

Commit bdcab53

Browse files
committed
feat(contributor-demo): sample plugin + CONTRIBUTING.md
A working reference implementation contributors can copy as a starting point, plus the full onboarding guide. Lives at /sample-feature in the running app (admin-only, hidden from production via DD_SHOW_SAMPLE_PLUGIN=false). The sample exercises every layer of the codebase in ~400 LOC: - src/services/sample-feature.js (counter + WS broadcast) - src/routes/sample-feature.js (RBAC + audit) - public/js/pages/sample-feature.js (live demo + 7 collapsible "how it works" cards, each with View on GitHub + View source) - src/__tests__/sample-feature.test.js (13 tests) - jobs/index.js cron tick (1/min, leader-only via _m) Plus: - docs/CONTRIBUTING.md (~400 lines): setup, layout, 12-step checklist, conventions (CSP/RBAC/audit/i18n), tests, release flow, PR template. - examples/sample-feature/README.md: file map + rationale per pattern. - howto.js: third primary CTA "Contribute to Docker Dash" → CONTRIBUTING.md. - i18n EN + RO for all sample-feature keys (~30 each). Tests: 931 → 944 / 61 suites. Lint clean. Release: v7.4.0
1 parent c89736a commit bdcab53

18 files changed

Lines changed: 1262 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,62 @@
22

33
All notable changes to Docker Dash are documented here.
44

5+
## [7.4.0] - 2026-04-25 — "Contributor Demo" — sample plugin + CONTRIBUTING.md
6+
7+
A working reference implementation that contributors can copy as a starting point for new features, plus a complete contributor onboarding guide. Lives at `/sample-feature` in the running app (admin-only, hidden from production via `DD_SHOW_SAMPLE_PLUGIN=false`).
8+
9+
### Added — Sample feature (live demo at `/sample-feature`)
10+
11+
A counter that exercises **every layer of the Docker Dash stack** in ~400 LOC across 4 source files:
12+
13+
- **[`src/services/sample-feature.js`](src/services/sample-feature.js)** — pure business logic, persists to `settings` table, broadcasts WS events on every change. Demonstrates the standard service shape: pure functions, optional WS broadcaster wired at startup, exported `_internals` for tests.
14+
- **[`src/routes/sample-feature.js`](src/routes/sample-feature.js)** — REST surface. Demonstrates `requireAuth` + `requireRole(...)` per route (viewer reads, operator+admin mutates, admin-only resets) and `auditService.log()` on destructive actions.
15+
- **[`public/js/pages/sample-feature.js`](public/js/pages/sample-feature.js)** — vanilla-JS page module. Live counter + WS subscription + "How this works" panel with 7 collapsible cards (one per layer). Each card has "View on GitHub" + "View source" (modal with the actual local file).
16+
- **[`src/__tests__/sample-feature.test.js`](src/__tests__/sample-feature.test.js)** — 13 unit tests. Mirrors the standard test pattern: in-memory SQLite, `beforeEach` reset, tests for the service in isolation.
17+
- **Cron tick** in `src/jobs/index.js` (1/min, leader-only via `_m()`) auto-increments the counter so contributors see the cron pattern fire without external triggers.
18+
19+
The page header has 3 buttons: link to **CONTRIBUTING.md** (opens GitHub), link to the in-app **How-To: Contributing** entry, and link to the **example folder README** on GitHub. Sub-banner shows live status pills (✓ Service ✓ Route ✓ Page ✓ WebSocket ✓ Cron ✓ Audit ✓ Tests) — click any pill to scroll to + highlight that layer's card.
20+
21+
Visibility flag: `DD_SHOW_SAMPLE_PLUGIN=false` in `.env` hides the route, sidebar entry, and cron entirely. Default: visible to admins.
22+
23+
### Added — Contributor onboarding
24+
25+
- **[`docs/CONTRIBUTING.md`](docs/CONTRIBUTING.md)** (~400 lines): local setup, project layout 1-pager, the **12-step checklist** for adding a new page (cross-references the sample feature), conventions section (security/RBAC/audit/i18n/error handling/logging), tests + lint, versioning + release flow, PR template, "what we won't merge" list, where to get help.
26+
- **[`examples/sample-feature/README.md`](examples/sample-feature/README.md)**: file-tree map + step-by-step walkthrough specific to the sample. Includes rationale for each pattern (why pure-function services, why per-route RBAC, why leader-gated cron, why no frontend build step).
27+
- **In-app How-To page**: new "Contribute to Docker Dash" CTA card (3rd primary button) that opens `docs/CONTRIBUTING.md` on GitHub.
28+
29+
### Why these patterns?
30+
31+
The sample feature is deliberately a trivial domain (a counter) so contributors can focus on **scaffolding** rather than business logic. Every choice in the example reflects an actual codebase convention with a real reason:
32+
33+
- Pure-function services → trivial unit tests with `:memory:` SQLite, no Express mocking.
34+
- `requireAuth + requireRole` per route → security posture readable from a single grep.
35+
- Audit log on destructive actions → non-negotiable for operator-facing features.
36+
- Cron jobs leader-gated → prevents N× duplication in HA mode.
37+
- WebSocket pub/sub → click on replica A propagates to subscribers on replica B in milliseconds (via Redis in HA, in-process in standalone).
38+
- i18n EN as source-of-truth + `_fallback` → contributors don't need to translate to all 11 languages.
39+
- No frontend build step → vanilla JS, hot-reloadable, approachable to operators who know JS but not "the modern frontend stack".
40+
41+
### Tests
42+
43+
- 907 → **944 passing / 61 suites** (+13 new tests for sample-feature, +1 new suite).
44+
- Lint: 0 warnings / 0 errors.
45+
46+
### Files touched
47+
48+
- `src/services/sample-feature.js` (new)
49+
- `src/routes/sample-feature.js` (new)
50+
- `src/__tests__/sample-feature.test.js` (new, 13 tests)
51+
- `public/js/pages/sample-feature.js` (new)
52+
- `examples/sample-feature/README.md` (new)
53+
- `docs/CONTRIBUTING.md` (new)
54+
- `src/server.js` — gated route mount + WS broadcaster wire
55+
- `src/jobs/index.js` — gated cron tick (leader-only)
56+
- `public/index.html` — sidebar nav-item + script tag
57+
- `public/js/app.js` — page registry entry
58+
- `public/js/i18n/en.js` + `ro.js``nav.sample-feature` + `pages.sampleFeature.*` (~30 keys each)
59+
- `public/js/pages/howto.js` — third primary CTA: "Contribute to Docker Dash"
60+
561
## [7.3.7] - 2026-04-25 — Browser console hygiene
662

763
A user-driven cleanup pass on the dev-tools console output. Three real issues, three drive-by warnings I left alone (and explain why).

docker-compose.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ services:
44
context: .
55
dockerfile: Dockerfile
66
args:
7-
APP_VERSION: "${APP_VERSION:-7.3.7}"
8-
image: docker-dash:${APP_VERSION:-7.3.7}
7+
APP_VERSION: "${APP_VERSION:-7.4.0}"
8+
image: docker-dash:${APP_VERSION:-7.4.0}
99
container_name: docker-dash
1010
restart: unless-stopped
1111
env_file:
@@ -54,7 +54,7 @@ services:
5454
dd-egress-filter:
5555
build:
5656
context: ./docker/egress-filter
57-
image: docker-dash-egress-filter:${APP_VERSION:-7.3.7}
57+
image: docker-dash-egress-filter:${APP_VERSION:-7.4.0}
5858
container_name: dd-egress-filter
5959
restart: unless-stopped
6060
# Uses the default bridge so target containers on the default bridge can

0 commit comments

Comments
 (0)