cleanup phase 1
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
# Git and the quality gates
|
||||
|
||||
What must pass before work is done, and what the repo refuses to let you commit.
|
||||
|
||||
> Last verified: 2026-07-30 against commit `d3ec723`.
|
||||
|
||||
---
|
||||
|
||||
## 1. The gates
|
||||
|
||||
Each project is built, linted, and tested **on its own**. There is no root-level build, package, or
|
||||
solution, so there is no single command that gates the repo. Run the gate for the side you edited.
|
||||
|
||||
### Client — `cd client`
|
||||
|
||||
| Command | What it runs |
|
||||
| --- | --- |
|
||||
| `npm run check` | **The gate.** `type` → `lint` → `lint:copy`, in that order |
|
||||
| `npm run type` | `tsc --noEmit` (`strict` on) |
|
||||
| `npm run lint` | `eslint .` (flat config) |
|
||||
| `npm run lint:copy` | `node scripts/check-copy.mjs` — greps `fa.json` for banned Persian orthography variants |
|
||||
| `npm run test:ci` | `jest --ci` — **also required** when you touched a component with a co-located `*.test.tsx` |
|
||||
|
||||
`npm run check` must be green. `en.json` and `fa.json` must be in sync.
|
||||
|
||||
> `lint:copy` is part of `check`, not a separate step you can forget. It is what stops a copy regression
|
||||
> — a hamza-less «تایید», a space in the brand name — from needing to be re-discovered by a human. The
|
||||
> rules it enforces are in [client/i18n.md](../client/i18n.md).
|
||||
|
||||
### Server — `cd server`
|
||||
|
||||
| Command | What it runs |
|
||||
| --- | --- |
|
||||
| `dotnet build Baya.sln` | **Zero new warnings.** Unused usings, locals, parameters, private fields or members count as failures — delete them, don't suppress them |
|
||||
| `dotnet test Baya.sln` | All tests pass, including the ones your change adds |
|
||||
|
||||
A reachable SQL Server is required to run the API (not to build or unit-test it).
|
||||
|
||||
### Both
|
||||
|
||||
Read your own diff as if you were reviewing the PR: **would a senior engineer approve it without
|
||||
comment?** A change that passes the mechanical gate and fails that question is not done.
|
||||
|
||||
---
|
||||
|
||||
## 2. What "done" means
|
||||
|
||||
A change is done when all of these hold:
|
||||
|
||||
- [ ] The full scope is implemented. No `// TODO: implement later`, no stub that returns fake data.
|
||||
Anything not real is behind a **DI-registered seam** and recorded (see [code-quality.md](code-quality.md)).
|
||||
- [ ] It follows the rules for that project — the relevant `CLAUDE.md` plus the one reference file for the
|
||||
area you touched.
|
||||
- [ ] No dead code. Comments explain *why*, not *what*.
|
||||
- [ ] The project's own gate above is green.
|
||||
- [ ] If the structure changed, the matching **architecture section** is updated in the same change
|
||||
(see [documentation.md](../documentation.md) §3).
|
||||
- [ ] If a business rule was discovered or decided, `product/` reflects it — recorded, not invented.
|
||||
- [ ] If a new reusable pattern or seam landed, the reference file for that area names it, so the next
|
||||
change reuses it instead of reinventing it.
|
||||
|
||||
A change that doesn't pass its own gate is **not done**, regardless of how complete the code looks.
|
||||
|
||||
---
|
||||
|
||||
## 3. The pre-commit secret scan
|
||||
|
||||
Repo-managed hooks live in `.githooks/` (in version control, unlike `.git/hooks`). **Enable them once per
|
||||
clone:**
|
||||
|
||||
```bash
|
||||
git config core.hooksPath .githooks
|
||||
```
|
||||
|
||||
`pre-commit` is a fast, dependency-free backstop against a credential leaking into a file that shouldn't
|
||||
hold one. It scans **only staged additions**, so it is quick. It rejects a commit that stages:
|
||||
|
||||
- the retired hardcoded admin password `qw123321`, anywhere;
|
||||
- private-key material or an AWS access-key id, anywhere;
|
||||
- the deployment's SQL Server host `87.107.152.16` **outside the declared config files**;
|
||||
- a **real** connection-string password in any `appsettings*.json` **outside the declared config files**
|
||||
(elsewhere only the `SET_VIA_USER_SECRETS_OR_ENV` placeholder is allowed).
|
||||
|
||||
### The declared-config allow-list
|
||||
|
||||
The pre-launch demo deployment configures itself from committed files rather than a secret store (see
|
||||
[`DEPLOY.md`](../../../DEPLOY.md)), so a short allow-list is exempt from the last two checks:
|
||||
|
||||
`appsettings.Development.json` · `docker-compose.yml` · `telegram-otp-bot/.env.example` · `DEPLOY.md`
|
||||
|
||||
It is maintained in the `declared_config` function in the hook, and it is **the honest record of where
|
||||
this repo's secrets are**. **Shrink it, never grow it.** Once real users exist, those values must be
|
||||
rotated and moved out of git.
|
||||
|
||||
### Limits
|
||||
|
||||
This is the local first line of defence, **not** a replacement for a full scanner (gitleaks, trufflehog)
|
||||
in CI. Bypass a false positive with `git commit --no-verify` — sparingly, and only when you are certain
|
||||
the flagged line is not a secret.
|
||||
|
||||
---
|
||||
|
||||
## 4. Branches and commits
|
||||
|
||||
`main` is the default branch and the base for PRs.
|
||||
|
||||
- **Commit or push only when asked.** If you are on `main` and about to commit, branch first.
|
||||
- One coherent change per commit. The repo's history reads as a sequence of completed units of work
|
||||
(`ui phase 11`, `remove user-secrets approach & prepare a pilot deploy`) — keep that.
|
||||
- Never skip hooks (`--no-verify`) or bypass signing unless explicitly asked. If a hook fails,
|
||||
fix the underlying issue.
|
||||
- Prefer a new commit over amending an existing one.
|
||||
- Before a destructive git operation (`reset --hard`, `push --force`, `checkout --`), consider whether a
|
||||
safer route reaches the same place.
|
||||
|
||||
---
|
||||
|
||||
## 5. Known pre-existing warnings
|
||||
|
||||
These are expected and **must not be "fixed"** unless a task says so — a change that touches them is
|
||||
scope creep, and one that silences them is worse.
|
||||
|
||||
| Warning | Project | Note |
|
||||
| --- | --- | --- |
|
||||
| `NU1510` on `Microsoft.Extensions.Logging.Debug` | `Baya.Web.Api` | Redundant transitive reference, harmless |
|
||||
| `NETSDK1057` (preview SDK) | all server projects | The .NET 10 SDK is preview on this machine |
|
||||
|
||||
On the client, `import/no-cycle` is disabled in `eslint.config.mjs` (its TypeScript resolver has an
|
||||
interface mismatch with this toolchain), and **ESLint is pinned to 9** — ESLint 10 crashes against this
|
||||
Next 16 toolchain with `scopeManager.addGlobals is not a function`. See
|
||||
[client/testing.md](../client/testing.md).
|
||||
Reference in New Issue
Block a user