Files
member-console/CONTRIBUTING.md
T
cgalo5758 0c78d5f425 Move issue tracking to the forge tracker
Replace status/issues.md and status/milestones.md with the Gitea forge
tracker, add issue templates, and archive pre-forge issues as YAML.
2026-09-21 02:35:27 -05:00

5.0 KiB

Contributing to member-console

Thanks for your interest in improving the member console. This project is developed by and for the Wiki Cafe MSC multi-stakeholder co-operative, and contributions from the wider community are welcome.

The canonical repository lives on Gitea at git.coopcloud.tech/wiki-cafe/member-console. Issues, discussion, and pull requests happen there. That address is also the Go module path in go.mod, so moving the canonical host rewrites every import in the tree; such a move has to land before the first release tag, never after one.

Getting set up

Follow the Quickstart in the README to bring up the test stack and run the console from source. The full stack contract (ports, secrets, teardown, running multiple worktrees at once) is documented in test/AGENTS.md.

Building and testing

Compile the binary to ./member-console:

make build

Run the unit tests — database- and Stripe-backed tests self-skip without a database:

go test ./...

For the full suite, point TEST_DATABASE_URL at a migrated Postgres (the test stack works). docs/testing.md covers what each kind of test exercises and how to run them. After a schema change, regenerate the sqlc query code with make sqlc-generate (see docs/database-management.md).

How changes are made

  1. Open an issue first for anything non-trivial, so the approach can be discussed before code is written. Pick the form that matches what closes the issue (a bug, an enhancement, debt, a design question, or docs) and answer its fields; the tracker refuses a blank issue. Write it for someone who has never opened this repository: a title that reads on its own, the console's own terms explained once where they first appear, and no internal shorthand (milestone codes, decision numbers, change names as explanations, dates as narrative) and no deployment's counts or names. Questions go to the forum, not the tracker.
  2. Substantial or behavioral changes go through OpenSpec. Proposals live under openspec/ and move through proposal → specs → design → tasks before implementation, then are archived once shipped. Docs-only and small mechanical fixes don't need a proposal.
  3. Branch, implement, and open a pull request against main. Keep each PR focused on one change.

Conventions

These are enforced by review and, where possible, by tooling. Please run the checks below before opening a PR.

  • Strict CSP. The app runs under script-src 'self' / style-src 'self' with no unsafe-inline. Never add inline <script> blocks or style= attributes — put JavaScript and CSS in internal/embeds/static/ and reference it via <script defer src> / <link>.
  • Template rendering must go through h.Templates.Render(). Handlers must not write to the http.ResponseWriter directly or call .ExecuteTemplate(w, …). make lint-templates enforces this.
  • Every routed URL needs a handler, and every operator mutation route needs a walkthrough claim. go run . lint checks both (dead-route and walkthrough-coverage).
  • Database. Schemas are owned per module under internal/<module>/. Write migrations (goose) and queries, then regenerate with make sqlc-generate. See docs/database-management.md.
  • Match the surrounding code — naming, structure, comment density, and idiom.

Before you push

go test ./...          # unit tests (DB/Stripe tests self-skip without a database)
make lint-templates    # template-safety guard
go run . lint          # dead-route + walkthrough-coverage guard
gofmt -l .             # formatting (only your own changes need to be clean)

Commit messages

Write clear, imperative-mood subject lines that describe the change ("Add operator plan-topology view", not "changes"). Keep the body focused on why.

License and the CLA

member-console is dual-licensed: AGPL-3.0-only for everyone, plus commercial licenses that fund development (see COMMERCIAL.md). Keeping that possible requires a Contributor License Agreement from every contributor before their work can be merged.

The CLA leaves the copyright in your contribution with you while granting Christian Galo the right to license it under the AGPLv3 and under separate commercial terms. That grant is what lets the project offer a commercial option while staying open source by default. A Developer Certificate of Origin would not do the same job: it attests provenance and grants no relicensing right.

The agreement is CLA.md. To sign it, add one line to CLA-SIGNATORIES.md in a pull request from your own account: full legal name, email, date, and the CLA version. That commit is your signature, and it can travel in the same pull request as your first change. Nothing is merged from an unsigned contributor.