# Contributing to pqp Thanks for wanting to. pqp is built in our spare time, so a good bug report is worth as much as a patch, and telling us something is confusing is worth more than both. > **[Leia em português](./CONTRIBUTING.pt-BR.md)** se preferir. Pode abrir issue > e PR em português tranquilamente, a gente responde nos dois idiomas. ## Before you write code **Small and obvious?** Send the PR. A typo, a broken link, a clear bug with a clear fix. No need to ask first. **Bigger than that?** Open an issue and talk to us first. Not for ceremony: this project has opinions that are not obvious from the outside, and we would rather disagree with you before you spend a weekend than after. A feature that works fine but pulls the product somewhere we do not want to go is the worst outcome for everybody, and it is our fault if we let you build it. **Reporting instead of fixing is a real contribution.** If you used pqp with friends and something annoyed you, tell us. We have very little of that kind of feedback and it is the hardest thing to get. **Check [the open issues](https://github.com/rafaelcg/pqp/issues) first.** They are the ranked version of what we actually want next, taken from [`docs/DISCORD_GAPS.md`](./docs/DISCORD_GAPS.md), which measures pqp against Discord feature by feature. Anything labelled `good first issue` is small, self-contained and hard to get wrong. Picking from there means you already have a yes before you start. ## Setup ```bash pnpm install cp .env.example .env cp .env.example client/.env docker compose up -d postgres pnpm dev ``` Client on http://localhost:5173, server on http://localhost:3001. You do not need Clerk keys to work on most things. Set `DEV_AUTH_BYPASS=true` in the root `.env` and `VITE_DEV_AUTH_BYPASS=true` in `client/.env`, then restart the server. The bypass is ignored when `NODE_ENV=production`. For attachments or the e2e suite you also need MinIO: ```bash docker compose --profile storage up -d postgres minio minio-init ``` ## Four things that will waste your time if nobody tells you These are not style preferences. Each one has cost somebody an hour. **1. Build `@pqp/shared` before you run tests.** ```bash pnpm --filter @pqp/shared build ``` A stale build of the shared package produces test failures in the client that have nothing to do with your change. If tests fail in files you never touched, run this first and try again before you start debugging. **2. The e2e suite needs MinIO running.** Without it you get failures that look like application bugs and are not. **3. Copy lives in two catalogues, and there are no em dashes.** `client/src/locales/en/translation.json` and `client/src/locales/pt-BR/translation.json` must both carry every key. A test fails the build if an em dash, en dash or horizontal bar appears in either. This is deliberate: they are not in the voice the product is written in. Use a comma, a full stop, or restructure the sentence. See [`docs/I18N.md`](./docs/I18N.md). Some copy is duplicated in `client/src/lib/marketing-meta.ts`, because the Cloudflare Pages middleware that injects SEO tags cannot read the i18n catalogue. A test pins the two copies together, so if you edit marketing copy in one place and CI complains, that is why. **4. Touching `server/` or `packages/shared` is `restarts-api`, not a voice hangup.** The server compiles `@pqp/shared` into itself, so a change there is a server change even when the feature is entirely client-side. Fly redeploys `pqp-api` and every `/ws` closes. After #162, refreshed web and Electron resume the same peer id; iOS, Android, failed resume, and tabs that have not refreshed still drop out of voice. Put the `restarts-api` label on the PR so it can be merged at a sensible hour. Apply `drops-voice` only when the change itself will hang up a live call even after resume. Details in [`docs/DEPLOY.md`](./docs/DEPLOY.md). ## Before you open the PR ```bash pnpm --filter @pqp/shared build pnpm -r typecheck pnpm --filter @pqp/client test pnpm --filter @pqp/client i18n:check pnpm lint ``` There are some pre-existing `react-hooks/exhaustive-deps` warnings about `t`. They are not yours; leave them. ## On tests Write one when the thing you fixed could come back. Do not write one to make a number go up. The specific failure worth naming: a test that asserts a property rather than the behaviour. Video is the classic. A `