Skip to content

Commit 91fe403

Browse files
CryptoJonesAaron K. Clarkclaude
authored
docs(contrib): add CONTRIBUTING.md (#101)
Contributor onboarding written down. Covers: - Quick-start (clone, env setup, migrations, tests). - Pre-PR checklist: lint, test, audit, OpenAPI updates, CHANGELOG. - Commit-message conventions (conventional-commit prefixes, Co-Authored-By trailers for AI-assisted work). - What gets reviewed: auth scoping, zod input validation, soft- delete defaults, no raw SQL, logger discipline, tests. - What contributors DON'T need (no CLA, no specific IDE, etc.). - Where to start (good-first-issue label, test-file headers as the convention reference, CHANGELOG architectural rationale). Pairs with SECURITY.md (#100) to round out the open-source meta- documentation set. Co-authored-by: Aaron K. Clark <akclark@thenetwerk.net> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 21fe42e commit 91fe403

1 file changed

Lines changed: 102 additions & 0 deletions

File tree

CONTRIBUTING.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Contributing to TimeTrackerAPI
2+
3+
The project mirrors on [GitHub](https://github.com/CryptoJones/TimeTrackerAPI)
4+
and [Codeberg](https://codeberg.org/CryptoJones/TimeTrackerAPI). PRs and
5+
issues on either forge are welcome; commits are pushed to both.
6+
7+
For vulnerability reports, see [`SECURITY.md`](SECURITY.md) — those use
8+
private channels, NOT public issues.
9+
10+
## Quick start
11+
12+
```bash
13+
git clone https://github.com/CryptoJones/TimeTrackerAPI.git
14+
cd TimeTrackerAPI
15+
cp .env.example .env
16+
# edit DB_PASSWORD in .env (see .env.example for the full env knob list)
17+
18+
npm ci
19+
docker compose up -d postgres setup # local Postgres + schema bootstrap
20+
npm run migrate # apply all sequelize migrations
21+
npm test # unit + api + integration
22+
npm start # serves on PORT (default 3000)
23+
```
24+
25+
`npm test` runs the full vitest suite (45+ files, 479+ cases at this
26+
writing). The integration suite (`tests/integration/`) auto-skips when
27+
no Postgres is reachable, so a fresh `npm test` without docker still
28+
passes the unit + api tiers.
29+
30+
## Before you open a PR
31+
32+
- **`npm run lint`** — eslint flat-config (`no-unused-vars`, `eqeqeq`,
33+
`no-console`, etc.). CI gates on this.
34+
- **`npm test`** — the full suite must pass. New features that touch
35+
controllers / middleware should land with new tests covering the
36+
happy + 4xx paths.
37+
- **`npm run audit`**`npm audit --audit-level=high --omit=dev`.
38+
CI fails on any high/critical advisory affecting production deps.
39+
- **OpenAPI:** if you add or change an endpoint, update
40+
`app/config/openapi.js` (Swagger UI at `/docs` reads from it, and
41+
the Postman collection is generated from it via
42+
`openapi-to-postmanv2` — see [README.md](README.md) for the
43+
one-liner).
44+
- **CHANGELOG.md:** add a one-paragraph entry under `[Unreleased]`
45+
describing what changed and (briefly) why.
46+
47+
## Commit style
48+
49+
Conventional-commit-ish: subject begins with `feat:`, `fix:`, `chore:`,
50+
`refactor:`, `docs:`, `test:`, or `ci:` followed by a scope in parens
51+
when useful (`feat(api):`, `fix(server):`). Body explains the why,
52+
not just the what. Multi-paragraph is fine for non-trivial changes.
53+
54+
If you co-author with an AI assistant, add a `Co-Authored-By:` trailer
55+
naming the model + the tool — keeps attribution honest for downstream
56+
forks.
57+
58+
## What gets reviewed
59+
60+
- **Auth scoping.** Every new endpoint that touches a domain entity
61+
must enforce the right `getCompanyId*` helper in
62+
[`app/middleware/auth.js`](app/middleware/auth.js) — direct, customer,
63+
job, vendor, or header-scoped. Master vs non-master semantics need
64+
to be explicit in the controller.
65+
- **Input validation.** Bodies go through `zod`-strict whitelists
66+
in [`app/schemas/`](app/schemas). Unknown fields are rejected, not
67+
silently stripped.
68+
- **Soft-delete.** Models with an `*Arch` column carry
69+
`defaultScope: { where: { *Arch: false } }`. Archived rows are
70+
invisible to reads by default; ops that need to see them must
71+
`.unscoped()` explicitly.
72+
- **No raw SQL** when a model call works. The `app/middleware/auth.js`
73+
P5-M refactor is the precedent: model methods are mockable,
74+
raw `sequelize.query` is not.
75+
- **Logger.** Anything that previously called `console.*` outside
76+
startup should route through `app/config/logger.js` (`log.info`,
77+
`log.warn`, etc.) — that's what feeds the structured request log,
78+
redaction layer, and OTEL future.
79+
- **Tests.** New code lands with tests. The `_setDbForTesting` seam
80+
on `auth.js` + `idempotency.js` lets HTTP tests drive success
81+
paths without a real DB; use it instead of integration-only
82+
coverage when possible.
83+
84+
## What you DON'T need
85+
86+
- A signed CLA. The project is Apache-2.0 and contributions are
87+
accepted under the same terms.
88+
- A particular Node version, beyond the engines pin
89+
(`>=20.0.0`). The CI matrix tests against Node 20 and 22.
90+
- A particular IDE / editor. Just match the existing whitespace
91+
conventions (4-space indent in JS, 2-space in YAML).
92+
93+
## Where to start
94+
95+
- Look at issues labelled `good first issue` on either forge.
96+
- Run the test suite locally and read the test file headers — they
97+
document the conventions used across the codebase (vi.mock
98+
caveats, how master-vs-scoped is exercised, etc.).
99+
- Skim [`CHANGELOG.md`](CHANGELOG.md) — every architectural decision
100+
has a short rationale paragraph.
101+
102+
Proudly Made in Nebraska. Go Big Red! 🌽 https://xkcd.com/2347/

0 commit comments

Comments
 (0)