Skip to content
Open
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
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ TW_SERVER_PORT=3000
# TW_OTPAAS_NAMESPACE=
# TW_OTPAAS_SECRET=
# TW_OTPAAS_TIMEOUT=10s

# Database configuration
# TW_DATABASE_URL=postgres://user:pass@localhost:5432/tw
# TW_DATABASE_SSL_MODE=disable
32 changes: 32 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ pnpm format # oxfmt check
pnpm build # production bundle
```

Database:

```bash
make sqlc # regenerate Go code from SQL queries
make migrate # apply migrations to local database
make db-reset # nuke local DB and re-apply migrations
```

## Project Structure

The repo is a monorepo with two top-level workspaces:
Expand All @@ -85,6 +93,30 @@ A few conventions worth knowing:
- **`web/components/` vs `web/containers/`**: containers are route-level (mounted by routes); components are smaller, reusable, and route-agnostic.
- **`web/helpers/`**: pure functions only (no React imports, no side effects). If it touches state or hooks, it belongs in `hooks/` or a component.

## Database

The server uses [pgx](https://github.com/jackc/pgx) as the PostgreSQL driver, [sqlc](https://sqlc.dev) for type-safe query generation, and [Atlas](https://atlasgo.io) for schema migrations.

### Prerequisites

- Docker (runs PostgreSQL and is required by Atlas for schema diffing)

sqlc is managed as a Go tool dependency and Atlas is installed via `make tools`; neither requires separate installation.

### Adding a new query

1. Add or edit a `.sql` file in `server/sql/queries/`
2. Run `make sqlc`
3. Use the generated functions from `server/internal/db/` in your handlers

### Changing the schema

1. Edit `server/schema.hcl`
2. Run `make migrate-diff` to generate the migration file
3. Run `make migrate` to apply it locally
4. Run `make sqlc` to regenerate query code against the new schema
5. Commit the schema, migration file, and regenerated Go code

## Branching & Workflow

Work happens on short-lived feature branches off `main`. Open a pull request back to `main` when ready.
Expand Down
28 changes: 27 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
SHELL := /bin/bash
BIN := $(CURDIR)/bin

include .env
export

GOLANGCI_VERSION := v2.11.4
GOLANGCI_LINT := $(BIN)/golangci-lint-$(GOLANGCI_VERSION)
ATLAS_VERSION := v1.1.0
ATLAS := $(BIN)/atlas-$(ATLAS_VERSION)

$(BIN):
mkdir -p $(BIN)
Expand All @@ -11,9 +16,30 @@ $(GOLANGCI_LINT): | $(BIN)
curl -sSfL https://golangci-lint.run/install.sh | sh -s -- -b $(BIN) $(GOLANGCI_VERSION)
mv $(BIN)/golangci-lint $@

$(ATLAS): | $(BIN)
ATLAS_VERSION=$(ATLAS_VERSION) curl -sSf https://atlasgo.sh | sh -s -- -y -o $@

.PHONY: tools
tools: $(GOLANGCI_LINT)
tools: $(GOLANGCI_LINT) $(ATLAS)

.PHONY: lint
lint: $(GOLANGCI_LINT)
$(GOLANGCI_LINT) run

.PHONY: sqlc
sqlc:
cd server && go tool sqlc generate

.PHONY: migrate-diff
migrate-diff: $(ATLAS)
@read -p "Migration name: " name && cd server && $(ATLAS) migrate diff $$name --env local

.PHONY: migrate
migrate: $(ATLAS)
cd server && $(ATLAS) migrate hash && $(ATLAS) migrate apply --env local

.PHONY: db-reset
db-reset:
docker compose exec postgres dropdb -U user --if-exists --force tw
docker compose exec postgres createdb -U user tw
$(MAKE) migrate
15 changes: 15 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
services:
postgres:
image: postgres:17
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we check if AWS supports Postgres version 18? IIRC, v18 has built in UUIDv7 function.

container_name: tw-postgres
environment:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we add container_name: tw-postgres above environment?

POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: tw
ports:
- '5432:5432'
volumes:
- postgres_data:/var/lib/postgresql/data

volumes:
postgres_data:
53 changes: 48 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,73 @@ go 1.26.1

require (
github.com/go-viper/mapstructure/v2 v2.5.0
golang.org/x/sync v0.19.0
github.com/jackc/pgx/v5 v5.9.2
golang.org/x/sync v0.20.0
)

require (
cel.dev/expr v0.25.1 // indirect
dario.cat/mergo v1.0.2 // indirect
filippo.io/edwards25519 v1.1.1 // indirect
github.com/air-verse/air v1.65.1 // indirect
github.com/andybalholm/brotli v1.2.0 // indirect
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
github.com/bep/godartsass/v2 v2.5.0 // indirect
github.com/bep/golibsass v1.2.0 // indirect
github.com/coreos/go-semver v0.3.1 // indirect
github.com/cubicdaiya/gonp v1.0.4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/fatih/structtag v1.2.0 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/go-sql-driver/mysql v1.9.3 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gohugoio/hugo v0.149.1 // indirect
github.com/google/cel-go v0.28.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/ncruces/go-sqlite3 v0.32.0 // indirect
github.com/ncruces/julianday v1.0.0 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/pganalyze/pg_query_go/v6 v6.2.2 // indirect
github.com/pingcap/errors v0.11.5-0.20250523034308-74f78ae071ee // indirect
github.com/pingcap/failpoint v0.0.0-20240528011301-b51a646c7c86 // indirect
github.com/pingcap/log v1.1.0 // indirect
github.com/pingcap/tidb/pkg/parser v0.0.0-20260418072757-ce92298d1124 // indirect
github.com/riza-io/grpc-go v0.2.0 // indirect
github.com/spf13/afero v1.14.0 // indirect
github.com/spf13/cast v1.9.2 // indirect
github.com/spf13/cobra v1.10.2 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/sqlc-dev/doubleclick v1.0.0 // indirect
github.com/sqlc-dev/sqlc v1.31.1 // indirect
github.com/tdewolff/parse/v2 v2.8.3 // indirect
golang.org/x/sys v0.35.0 // indirect
golang.org/x/text v0.28.0 // indirect
google.golang.org/protobuf v1.36.8 // indirect
github.com/tetratelabs/wazero v1.11.0 // indirect
github.com/wasilibs/go-pgquery v0.0.0-20250409022910-10ac41983c07 // indirect
github.com/wasilibs/wazero-helpers v0.0.0-20240620070341-3dff1577cd52 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b // indirect
golang.org/x/net v0.49.0 // indirect
golang.org/x/sys v0.43.0 // indirect
golang.org/x/text v0.36.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 // indirect
google.golang.org/grpc v1.80.0 // indirect
google.golang.org/protobuf v1.36.11 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

tool github.com/air-verse/air
tool (
github.com/air-verse/air
github.com/sqlc-dev/sqlc/cmd/sqlc
)
Loading
Loading