Run ReputeCast from source
This guide is the ReputeCast development setup: it runs the app from its source code with live reload, loads the demo workspace and shows the commands that test and build it. Use it to fix a bug, build a feature or try an adapter against a real server. To run ReputeCast for your own mail, install a release instead (Install with Docker Compose).
Before you begin
Section titled “Before you begin”- Go 1.27.
go.modasks for Go 1.27.2; a recent Go downloads that toolchain by itself. - Node.js 24 (LTS) with pnpm 12 for the web app. The web app’s
package.jsonpins pnpm 12.11.0. - Docker with Compose, for PostgreSQL 18 and Mailpit (a local mail catcher).
- golangci-lint v2, only to run the Go linters (
make lint). - Free ports 5432 (PostgreSQL), 1025 and 8025 (Mailpit), 8080 (API) and 5173 (web app).
Run it locally
Section titled “Run it locally”-
Get the source and install the Go modules and web dependencies:
Terminal git clone https://github.com/hostrepute/reputecast.gitcd reputecastmake deps -
Start everything:
Terminal make devThis starts PostgreSQL and Mailpit with Docker Compose, then the API with live reload on http://localhost:8080 and the web app (Vite) on http://localhost:5173. The API applies database migrations when it starts. Stop both with Ctrl C.
-
In a second terminal, load the demo data, the Acme workspaces:
Terminal make seed -
Open http://localhost:5173 and sign in with a demo account. Every email the app sends lands in Mailpit at http://localhost:8025.
| Account | Password | Role | Notes |
|---|---|---|---|
[email protected] |
reputecast-demo |
Owner, instance admin | Authenticator secret JBSWY3DPEHPK3PXP, recovery code b4xk-9q2m-7hdn |
[email protected] |
reputecast-demo |
Viewer | Password only (two-factor grace period) |
Watch a live send
Section titled “Watch a live send”The demo’s sending providers are simulated: nothing they send leaves your machine. reputecast demo send starts a
campaign’s send through them, and the running server keeps sending in real time, with deliveries, bounces,
complaints, opens and clicks, so the live monitor has something to show:
export REPUTECAST_ENV=development # the command refuses to run otherwisego run ./cmd/reputecast demo send "Weekly Digest #142" --elapsed 20mgo run ./cmd/reputecast demo send "Weekly Digest #142" --scenario outlook-complaints --elapsed 20m --resetgo run ./cmd/reputecast demo send "Weekly Digest #142" --scenario postal-outage --elapsed 17m --reset--elapsedstarts the send that long ago and fast-forwards it, so the monitor opens mid-send.--scenario outlook-complaintsmakes lapsed Outlook readers complain until the Outlook share is auto-paused;--scenario postal-outagemakes Postal refuse connections 14 minutes in, so its share is held.--resetclears an earlier send of the campaign first, including what it changed elsewhere (provider statistics, suppressions from its bounces). It runs only in a workspace whose providers are all demo providers.
The flags are listed in the CLI reference.
Test, lint and build
Section titled “Test, lint and build”| Task | Command |
|---|---|
| All tests: Go unit and integration tests on real PostgreSQL, web unit tests | make test |
| Linters: golangci-lint, ESLint and TypeScript | make lint |
| Regenerate sqlc code, the OpenAPI document and the web API types | make generate |
Production build: one binary with the web app embedded, in bin/reputecast |
make build |
| Docker image | make docker |
| Browser tests (Playwright) against the running dev stack | make e2e |
| The reputecast.com landing site: build, or live reload on :5288 | make site, make site-dev |
| Adapter SDK and template: build and test, then run through the Go runtime | make sdk |
| Accessibility sweep of the app’s screens (axe-core, WCAG 2.0–2.2 A and AA) | cd web && pnpm a11y |
| Every task with a one-line description | make help |
Integration tests start PostgreSQL 18 with Testcontainers, or reuse the Compose database when it runs; make test
picks automatically. CI runs the Go suite on Go 1.27 against PostgreSQL 16, 17 and 18. When several test runs share
one database server, go test -p 4 ./... keeps the connection count within PostgreSQL’s limits.
After you change an API operation, regenerate the OpenAPI document and the web types, and commit both:
go run ./cmd/reputecast openapi > web/openapi.jsoncd web && pnpm api:typesConventions
Section titled “Conventions”Read docs/dev/CONVENTIONS.md before
your first change. It explains how a screen is built end to end. In short:
- Each domain is a Go package under
internal/with aServiceand aRegisterfunction for its API operations. Every operation declares who may call it and which permission it needs, and every change writes an audit log entry in the same transaction. - Errors are RFC 9457 problem documents with a sentence that says what to do (Errors). Secrets are write-only.
- SQL lives in
internal/store/queries/and goes through sqlc; migrations are goose files inmigrations/, with aDownfor each, and must run on PostgreSQL 16 to 18. - The web app calls the API only through the client generated from
web/openapi.json. - Screens follow the design boards in
design/boards/at 1440, 834 and 390 px. - Interface text goes into message files so it can be translated (Translate ReputeCast).
Open a pull request
Section titled “Open a pull request”- Keep
make test,make lintandmake buildpassing, and add tests with your change. - Write commit messages as Conventional Commits:
type(scope): description, for examplefix(campaigns): count only blocking issues for a blocked draft. The first line is at most 100 characters, imperative and lower case after the colon, with no full stop. - Never add paywalls or license checks: every feature in the repository is free.
Check that it worked
Section titled “Check that it worked”make devprintsAPI http://localhost:8080 Web http://localhost:5173 Mail http://localhost:8025.curl http://localhost:8080/readyzanswers200.- You can sign in as
[email protected]and see the Acme Newsletter workspace.
Troubleshooting
Section titled “Troubleshooting”make devfails on a port: another PostgreSQL or Mailpit is running. Stop it, or set other ports in.env.- “too many clients” in tests: run
go test -p 4 ./.... make lintsays golangci-lint is missing: install golangci-lint v2.demo sendrefuses to run: setREPUTECAST_ENV=developmentin that terminal.