CONTRIBUTING.md
Rama main · réplica de lectura del repositorio original.
# Contributing to WeGrocery
Thanks for your interest in WeGrocery. This is a real product: it handles the
money of real buying groups every week, and every merge reaches each
deployment. This guide explains how to propose a change so that it can be
reviewed and shipped safely.
By taking part you agree to follow the [Code of Conduct](CODE_OF_CONDUCT.md).
## Contents
- [Ways to contribute](#ways-to-contribute)
- [Before you start](#before-you-start)
- [Ground rules](#ground-rules)
- [Development setup](#development-setup)
- [Making a change](#making-a-change)
- [Pull requests](#pull-requests)
- [Review and release](#review-and-release)
- [Security issues](#security-issues)
- [License](#license)
## Ways to contribute
- **Report a bug**: open a [bug report](https://github.com/flylabs-ai/wegrocery/issues/new?template=bug_report.yml).
Reproduce it on the [public demo](https://wegrocery-demo.vercel.app) if you
can: it runs the same code on fake data.
- **Suggest a feature**: open a [feature request](https://github.com/flylabs-ai/wegrocery/issues/new?template=feature_request.yml)
that describes the problem your group has, not only the solution.
- **Improve the docs**: typos, unclear steps in [SETUP.md](SETUP.md) or
[docs/self-hosting.md](docs/self-hosting.md), missing explanations.
- **Translate**: the UI ships in Italian and English (`lib/i18n/`). A new
language is a new pack typed against the Italian one.
- **Write code**: fix a bug or build something agreed on in an issue.
- **Run it for your group**: tell us about your setup in an issue. Real usage
is the most useful feedback there is.
Look for issues labelled `good first issue` or `help wanted` if you want a
place to start.
## Before you start
- **Small fixes** (a typo, an obvious bug, a missing test): open a pull
request directly.
- **Anything larger** (a new feature, a schema change, a new environment
variable, a change to how money moves): open an issue first and wait for
agreement on the approach. A short written plan saves you from rewriting a
PR that cannot be merged as is.
- Check the open [issues](https://github.com/flylabs-ai/wegrocery/issues)
and [pull requests](https://github.com/flylabs-ai/wegrocery/pulls) so
you do not duplicate work, and comment on an issue to say you are taking it.
## Ground rules
These are the rules a change is reviewed against. They exist because the app
runs in production with real members and real money.
1. **White-label, always.** One codebase serves every group. Nothing specific
to one group goes into the code: differences live only in environment
variables (secrets and integrations), in the database (settings an admin
changes from the app) and in the brand JSON (`NEXT_PUBLIC_BRAND_JSON`:
name, logo, colours, language, currency). Every feature must work with the
optional integrations off (Stripe, Google sign-in, the membership-card
check, Sentry): the demo is exactly that case.
2. **Money is append-only.** `ledger_entries` refuses UPDATE and DELETE at the
database level. A correction is a reversal plus, for an edit, a
replacement (`lib/ledger-reversal.ts`); any filter by entry type goes
through `liveLedger` (`lib/db/ledger-live.ts`). A new money rule gets a
read-only check in `lib/invariants.ts` and a case in
`lib/invariants.integration.test.ts`; those checks run every night on production.
3. **No secrets or personal data, anywhere.** The repository and its CI logs
are public. Never commit `.env*` files, connection strings, API keys, or
real names, emails or balances, and do not paste them into issues, PRs or
logs. Tests, fixtures and seeds use invented data only. A script that
writes to a database must refuse a production host unless an explicit
flag is passed.
4. **Migrations are additive and run from zero.** A schema change is a new
`drizzle/NNNN_*.sql` file (idempotent, additive where possible), also
listed in `lib/migrations.ts`. CI applies every migration to an empty
database, so it must work from `0000` too.
5. **Accessible by construction.** Colours come from brand tokens, never
hard-coded; every text and background pair reaches WCAG AA; no text under
12 px. `lib/brand/design-guard.test.ts` enforces most of it.
6. **Languages.** Code, identifiers, comments, commit messages, PR
descriptions and docs are in English. UI strings live in the language
packs (`lib/i18n/it.ts` is the source, `en.ts` is type-checked against it),
never inline in components.
[AGENTS.md](AGENTS.md) is the full reference: architecture, data model,
business rules and what to update with each kind of change. Read the sections
that touch your change before writing code.
## Development setup
Follow [SETUP.md](SETUP.md): Node.js 24, a free Postgres database on
[Neon](https://neon.tech), `.env.local` from `.env.example`, `npm run
db:migrate`, then `npm run dev`. `AUTH_DEV_LOGIN_EMAIL` gives you a sign-in
button in development, so you need neither email nor Google.
Use a database of your own with fake data (`npm run db:seed:demo` fills one).
Never point a development environment at a real group's database.
## Making a change
1. **Fork** the repository and create a branch from `staging` (not `main`):
```bash
git checkout -b fix/short-description origin/staging
```
Branch names are free; `fix/…`, `feat/…` and `docs/…` read well.
2. **Keep it focused.** One change per PR. A bug fix is a bug fix, not a
refactor of the surrounding code.
3. **Match the code around you**: naming, comment density, file layout. Reads
happen in Server Components (`lib/db/queries.ts`), writes in Server
Actions guarded by `requireActiveMember()` / `requireAdmin()`, followed by
`revalidatePath()`. Expected refusals are returned as values, not thrown
(see "Key Business Rules" in AGENTS.md).
4. **Test it.**
- Pure logic gets a unit test next to the source (`*.test.ts`, Vitest,
no database). Unit tests import `.ts` files only.
- Queries, guarded writes and migrations get an integration test
(`*.integration.test.ts`) when a unit test cannot show the behaviour; build rows
with `makeScope()` from `test/int/fixtures.ts`.
- UI changes: check them in the browser, on a phone width (375 px) as well
as a desktop one, and include screenshots in the PR.
5. **Run what CI runs** before pushing:
```bash
npx tsc --noEmit && npm run lint && npm test
```
Lint runs with zero warnings allowed. Integration tests need a test
database (see SETUP.md); if you cannot run them, say so in the PR and CI
will on the maintainer's side.
6. **Update what goes with the change**:
- user-visible behaviour: an entry under `## [Unreleased]` in
[CHANGELOG.md](CHANGELOG.md) and the same entry in
[CHANGELOG.it.md](CHANGELOG.it.md), in plain words for members and
admins (house style in AGENTS.md). If you do not write Italian, add the
English one and say so in the PR: the maintainer translates it;
- a new environment variable: `.env.example`, `lib/config-status.ts` and
`docs/upgrading.md`, plus `docs/self-hosting.md` if a new installation
needs it;
- a new migration: `lib/migrations.ts`.
7. **Commit** with clear messages in the imperative mood ("Fix the shipping
split on a cancelled order"), explaining why when it is not obvious.
## Pull requests
- Open the PR against **`staging`**. PRs against `main` are reserved for
releases.
- Fill in the template: what changes for the user, how you tested it, and
the checklist.
- Link the issue it resolves (`Closes #123`).
- Keep the PR up to date with `staging` by merging it in; there is no need to
rewrite history.
- Draft PRs are welcome for early feedback.
CI runs typecheck, lint and unit tests on every PR. The integration job needs
secrets that forks do not have, so it is skipped on your PR and runs before
the release instead.
## Review and release
- The maintainer reviews PRs as time allows; expect questions, and feel free
to ping after a week of silence.
- Accepted PRs are **squash-merged into `staging`**, tested on the staging
deployment, then released to `main` with the other changes of that version
(every deployment updates from `main`).
- A PR may be closed if it conflicts with the ground rules above or with the
direction of the project; an issue first avoids that.
## Security issues
Do **not** open a public issue for a vulnerability. Follow
[SECURITY.md](SECURITY.md) and report it privately.
## License
WeGrocery is [MIT licensed](LICENSE). By contributing you agree that your
contribution is licensed under the same terms. The Porta Moneta name and logo
are not part of the license and must not be used in contributions.