Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .claude/skills/ci-pipeline/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ fails, the check is red and the PR can't merge cleanly.

### `backend-audit` job (Go)

Go version **1.24.x**. Steps, in order — each is a gate:
Go version **1.27.x**. Steps, in order — each is a gate:

1. **Check gofmt** — `gofmt -l .`; fails if any file is unformatted. Fix with
`gofmt -w .`.
2. **Verify Dependencies** — `go mod verify`.
3. **Build** — `go build -v ./...`.
4. **go vet** — `go vet ./...`.
5. **staticcheck** — installs `honnef.co/go/tools/cmd/staticcheck@v0.6.1`, then
5. **staticcheck** — installs `honnef.co/go/tools/cmd/staticcheck@v0.8.1`, then
`staticcheck ./...`.
6. **Tests** — `go test -race ./...` (race detector on).

Expand Down Expand Up @@ -134,7 +134,7 @@ Multi-stage, producing a tiny `scratch` image:

1. **Stage `frontend`** (`node:22-alpine`): `npm ci` then `npm run build` in
`client/portal`. Takes a build arg `VITE_GOOGLE_AUTH_ENABLED` (default `true`).
2. **Stage `builder`** (`golang:1.24`): `go mod download`, then a static build
2. **Stage `builder`** (`golang:1.27`): `go mod download`, then a static build
`CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags="-s -w" -o /app/api ./cmd/api`.
3. **Stage final** (`scratch`): copies CA certs, the `api` binary, and the built
frontend into `./static`. `EXPOSE 8080`, `CMD ["./api"]`.
Expand Down
20 changes: 20 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,12 @@ VAPID_PRIVATE_KEY=
# Contact address for push services, used if a provider needs to reach you.
VAPID_SUBJECT=noreply@example.com

# Comma-separated push-service hosts (exact or any subdomain) that browser
# subscription endpoints must point at. The server POSTs to these URLs, so
# anything else is rejected. Leave empty for the built-in list covering
# Chrome/Edge (FCM), Firefox, Safari, Windows (WNS) and Samsung Internet.
PUSH_ENDPOINT_ALLOWED_HOSTS=


# ── Rate limiting ────────────────────────────────────────────────────────────

Expand All @@ -160,6 +166,20 @@ RATELIMITER_REQUESTS_COUNT=20
# at the venue typically shares one IP.
RATELIMITER_IP_REQUESTS_COUNT=200

# How the per-IP limiter learns the client address. Forwarded headers are
# never trusted by default because any client can send them.
#
# CLIENT_IP_HEADER: a single-IP header your edge proxy OVERWRITES on every
# request (Cloudflare: CF-Connecting-IP, nginx realip: X-Real-IP). Leave
# empty if no such proxy exists.
# CLIENT_IP_TRUSTED_PROXIES: used only when CLIENT_IP_HEADER is empty; the
# number of reverse proxies between the internet and this server; the
# X-Forwarded-For entry that many hops from the right is the client (one load
# balancer: 1). Verify with a request from a known IP. 0 means the TCP peer
# address is used as-is.
CLIENT_IP_HEADER=CF-Connecting-IP
CLIENT_IP_TRUSTED_PROXIES=0


# ── Apple Wallet passes (optional) ───────────────────────────────────────────

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/audit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: "1.24.x"
go-version: "1.27.x"

- name: Check gofmt
run: |
Expand All @@ -42,7 +42,7 @@ jobs:
run: go vet ./...

- name: Install staticcheck
run: go install honnef.co/go/tools/cmd/staticcheck@v0.6.1
run: go install honnef.co/go/tools/cmd/staticcheck@v0.8.1

- name: Run staticcheck
run: staticcheck ./...
Expand Down
37 changes: 37 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,42 @@
# Changelog

## [0.14.0](https://github.com/hackutd/harp/compare/v0.13.0...v0.14.0) (2026-09-08)


### Features

* public endpoint for tracks ([#159](https://github.com/hackutd/harp/issues/159)) ([4228aef](https://github.com/hackutd/harp/commit/4228aefeb92f130c42b114c5612e28c18c548c65))


### Bug Fixes

* (sa): form unwanted scroll ([e216a57](https://github.com/hackutd/harp/commit/e216a57ee85175925565ed87c17960b1d5ee4519))
* a more balanced review process & confirmation dialogs ([#156](https://github.com/hackutd/harp/issues/156)) ([831806d](https://github.com/hackutd/harp/commit/831806d40248085e2401573020ce16ed5f197d20))
* error messaging on applications ([#157](https://github.com/hackutd/harp/issues/157)) ([72533ac](https://github.com/hackutd/harp/commit/72533acfa7073884e53c9dfbaf3271e37abff1b9))
* **notifications:** restrict push endpoints to known push services and bound dispatcher requests ([#153](https://github.com/hackutd/harp/issues/153)) ([9ca9dff](https://github.com/hackutd/harp/commit/9ca9dffe513669c2d355689a613faed4c95e7c94))
* **ratelimiter:** atomic fixed-window counting and explicit client-IP trust ([#155](https://github.com/hackutd/harp/issues/155)) ([dd215e6](https://github.com/hackutd/harp/commit/dd215e69f45b9a34eddddf81b086d12a8b3145ad))
* required conditional check against application form ([95030e0](https://github.com/hackutd/harp/commit/95030e07918e629bce96e23d8ab823f91001ed55))

## [0.13.0](https://github.com/hackutd/harp/compare/v0.12.0...v0.13.0) (2026-09-02)


### Features

* "Add to Home Screen" wording + "Get Notified" push dialog ([#142](https://github.com/hackutd/harp/issues/142)) ([db20740](https://github.com/hackutd/harp/commit/db20740136e4917f4252c849e1422f098939d6f9))
* auto-open install walkthrough on mobile browsers instead of toast ([#144](https://github.com/hackutd/harp/issues/144)) ([74598c5](https://github.com/hackutd/harp/commit/74598c58fe3ce771adaa667fe4c47b17f8ee3937))
* hide hacker information from admins ([#140](https://github.com/hackutd/harp/issues/140)) ([f9ec8d0](https://github.com/hackutd/harp/commit/f9ec8d09e6533372ab8a95ca1f3013047c50d513))
* install walkthrough slideshow + push notification dialog ([#138](https://github.com/hackutd/harp/issues/138)) ([67c84cc](https://github.com/hackutd/harp/commit/67c84cc7754d25f3cbfcfd44d186e1e11bb24eae))
* many frontend improvements & delete user ([#151](https://github.com/hackutd/harp/issues/151)) ([7bf35b0](https://github.com/hackutd/harp/commit/7bf35b0078d6f7930efdbcb31b5a7dd252e664b9))
* performance optimizations ([#149](https://github.com/hackutd/harp/issues/149)) ([ae11579](https://github.com/hackutd/harp/commit/ae115796032c1f1df0a55b8261ce12c4791a07b2))
* rsvp and travel ([#145](https://github.com/hackutd/harp/issues/145)) ([49ba0e8](https://github.com/hackutd/harp/commit/49ba0e892e90e61ae4dffd9134e18e71ec52dc19))
* superadmin-configurable Hacker Links shown as cards on hacker home ([#143](https://github.com/hackutd/harp/issues/143)) ([f3d6a1c](https://github.com/hackutd/harp/commit/f3d6a1c7cfd60f37cbb82efa97ed0c75fda94640))
* surface hacker meal group in portal UI ([#139](https://github.com/hackutd/harp/issues/139)) ([4a20ee8](https://github.com/hackutd/harp/commit/4a20ee82d79960ee24f0f46f7ef0e2dd11252c60))


### Bug Fixes

* key rate limiter by session user with per-IP fallback ([#152](https://github.com/hackutd/harp/issues/152)) ([cca2761](https://github.com/hackutd/harp/commit/cca2761f4e9f855ffbe9c60c2d0ae038da4378f0))

## [0.12.0](https://github.com/hackutd/harp/compare/v0.11.0...v0.12.0) (2026-08-27)


Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ ENV VITE_GOOGLE_AUTH_ENABLED=$VITE_GOOGLE_AUTH_ENABLED
RUN npm run build

# Stage 2: Build backend
FROM golang:1.24.13 AS builder
FROM golang:1.27.1 AS builder
WORKDIR /app

COPY go.mod go.sum ./
Expand Down
5 changes: 5 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ tasks:
cmds:
- go run cmd/migrate/seed/main.go

reset-schema:
desc: Restore form schemas to the shipped defaults (task reset-schema -- -all -dry-run)
cmds:
- go run ./cmd/resetschema {{.CLI_ARGS}}

gen-docs:
desc: Generate Swagger docs
cmds:
Expand Down
4 changes: 2 additions & 2 deletions claude.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ Note: `air` runs `task gen-docs` as a pre-command on every rebuild, so `swag` CL
- **Entry point:** `cmd/api/main.go` — loads config, `cmd/api/api.go` — Chi router setup in `mount()`
- **Database:** PostgreSQL 16.3, raw SQL (no ORM), repository pattern in `internal/store/`
- **Auth:** SuperTokens (Passwordless magic link + Google OAuth), initialized in `internal/auth/`
- **Middleware chain:** RequestID → RealIP → Logger → Recoverer → CORS → SuperTokens → RateLimiter (`/v1` only) → AuthRequired → RequireRole
- **Rate limiting:** keyed by SuperTokens user ID when the request carries a verified session (`RATELIMITER_REQUESTS_COUNT`), falling back to client IP otherwise (`RATELIMITER_IP_REQUESTS_COUNT`, larger because a whole venue shares one NAT). Static assets and `/auth/*` are never limited.
- **Middleware chain:** RequestID → ClientIP → Logger → Recoverer → CORS → SuperTokens → RateLimiter (`/v1` only) → AuthRequired → RequireRole
- **Rate limiting:** keyed by SuperTokens user ID when the request carries a verified session (`RATELIMITER_REQUESTS_COUNT`), falling back to client IP otherwise (`RATELIMITER_IP_REQUESTS_COUNT`, larger because a whole venue shares one NAT). The client IP comes from `CLIENT_IP_HEADER` (default `CF-Connecting-IP`) or `CLIENT_IP_TRUSTED_PROXIES` hops into `X-Forwarded-For`; other forwarded headers are ignored. Static assets and `/auth/*` are never limited.
- **Roles (hierarchical):** `hacker` (1) < `admin` (2) < `super_admin` (3)
- **JSON envelope:** Success: `{"data": ...}`, Error: `{"error": "..."}`
- **Pagination:** Cursor-based with base64-encoded JSON cursors
Expand Down
1 change: 1 addition & 0 deletions client/portal/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion client/portal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"lint": "eslint .",
"format": "prettier --write \"{src,branding}/**/*.{ts,tsx,css,json}\"",
"format:check": "prettier --check \"{src,branding}/**/*.{ts,tsx,css,json}\"",
"preview": "vite preview"
"preview": "vite preview",
"test:reviews": "node --test scripts/review-regressions.test.mjs"
},
"dependencies": {
"@hookform/resolvers": "^5.2.2",
Expand Down Expand Up @@ -74,6 +75,7 @@
"@types/react": "^19.2.5",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.1",
"esbuild": "0.27.3",
"eslint": "^9.39.1",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-boundaries": "^6.0.2",
Expand Down
Loading
Loading