-
Notifications
You must be signed in to change notification settings - Fork 1
Code Quality Bar
This page states the quality bar a change has to clear, and how to check each part of it locally. It is for anyone preparing a pull request.
The short version, from the README: nothing merges on a green tick alone. The bar is a clean board.
| Dimension | Target | Enforced by |
|---|---|---|
| Lint | Zero errors, zero warnings | ESLint 9 flat config, per workspace, and CI |
| Types | Zero errors under strict mode |
tsc, per workspace, and CI |
| Formatting | Prettier clean | The pre-commit hook and pnpm format:check
|
| Coverage | Per-app floors, moving to 95 | CI, on the merged coverage map |
| Sonar issues | Zero new issues, zero new code smells | Sonar quality gate, when enabled |
| Security hotspots | Zero unreviewed | Sonar, CodeQL |
| Duplication | No new duplication | Sonar |
| React health | 95 or above |
pnpm doctor, by hand |
| Secrets | Zero | secretlint locally, Gitleaks in CI |
| Dependencies | No new advisory at moderate or above | Dependency review, grype |
| Licences | Allow list only | grant |
Lint and types. Scope them:
pnpm --filter <workspace> lint
pnpm --filter <workspace> type-checkThe base TypeScript config turns on strict, noUncheckedIndexedAccess, noImplicitOverride, noFallthroughCasesInSwitch, forceConsistentCasingInFileNames, isolatedModules, and verbatimModuleSyntax. noUncheckedIndexedAccess in particular means array and record access yields a possibly-undefined type. That is deliberate: silently trusting rows[0] exists is how a clinical list renders the wrong patient.
No eslint-disable comments. Fix the root cause. If a rule is genuinely wrong for this repository, change it in the flat config with a justification in the pull request. A disable comment moves the problem out of sight without solving it.
Formatting.
pnpm format # write
pnpm format:check # verifyPrettier owns formatting entirely; ESLint owns correctness. The pre-commit hook formats staged files, so this rarely comes up.
Coverage. See Testing strategy for the floors and the reasoning. Locally:
pnpm --filter <workspace> testReact health.
pnpm doctorRuns react-doctor over the repository. doctor.config.json sets ignore paths only: coverage output, build output, .next, static Storybook, and the generated Prisma client. It sets no score threshold, and no CI job runs it. The 95 bar is a team convention checked by hand, not a gate. If you want it enforced, that is a pull request against .github/workflows/.
Secrets.
pnpm check:secretsSupply chain. The commands are on Security and supply chain. They need syft, grype, and grant installed at the versions the workflow pins.
Everything at once.
pnpm verify # lint + type-check + test + buildTwo projects, yosemitecrew_openrunic_Web and yosemitecrew_openrunic_Api, configured through sonar-project.properties in each app directory.
The Sonar stage is currently skipped. The repository variable
DISABLE_SONARis set totruebecause the projects do not exist yet. The aggregate check counts a skipped stage as a pass, so a green pull request today has not been Sonar-scanned.
Turning it on takes more than deleting the variable: create the projects, name each project's main branch main, add sonar-project.properties for each app, add the SONAR_TOKEN_WEB and SONAR_TOKEN_API secrets, and only then remove the variable. Naming a project's main branch dev produces the mirror-image failure of the others, which is a confusing hour to debug.
Two structural notes for when it is on. The scan runs with -Dsonar.qualitygate.wait=true, so a red gate reds the job and therefore the aggregate required check. And the scan job does no install, so rules needing type resolution from node_modules see less than they would. If that gap starts to matter, the documented answer is a scheduled full analysis as a type-aware backstop, not reinstalling on every scan.
These are not tool-enforced but are expected in review.
Comments explain why, not what. The existing codebase is unusually heavily commented, and the comments carry decisions: why lcov is not merged directly, why the React plugin is absent from the vitest config, why _offset must be a multiple of _count, why createdAt is excluded from the audit hash. Match that. A comment that restates the code is noise; a comment that records a rejected alternative saves the next person an afternoon.
Order that matters is declared as data. The middleware chain is an exported array so the suite asserts it directly. Do the same when the correctness of a sequence is the point.
Fail closed. The CI aggregate treats a cancelled dependency as a failure. The coverage merge fails on a missing floor. The audit sink throws rather than falling back to a non-transactional write. The tenant client throws rather than passing raw SQL through. When you add a guard, make its failure mode loud.
No silent drops. A rejected search parameter is an error, not a shrug. A wrongly-shaped promoted form value throws rather than being skipped. A mapper that does not carry a field lists it in a *_DROPPED_FIELDS export.
Synthetic data only, everywhere. Tests, fixtures, seeds, screenshots, logs. This is a hard rule, not a preference.
openrunic is an open-source operating system for human health. Pre-alpha: do not run it in production, and never put real patient data into it.
Repository · Licence (AGPL-3.0-only) · Security policy · Contributing · Code of conduct
Where this wiki and the repository disagree, the repository is right.