# Development guide IMPORTANT: Read README.md, aip.md, and commits.md ## Best practices Do not read generated files, except for debugging purposes. After making a change, check the project for diagostnics, and if applicable, run related build and test commands. Before committing changes, run `make test`. The tests must pass. ## Backend/Golang Do not alter go.mod directly, instead, use the CLI tools `go mod tidy`, `go mod init`, and so forth. Write tests for all public APIs. Never test a private API; if it feels like we need to do that, refactor the code to make the difficult-to-test part a new package. Prefer to write clear function and variables names over comments. In general, avoid writing comments when the same logic can be communicated with code. Follow https://github.com/golang-standards/project-layout/blob/master/README.md for layout The main function should be very small. Prefer to test with real implementations rather than mocks. For example, bring up a real HTTP server to test. Generally conform to resource-oriented design describe in https://google.aip.dev/general. Read aip.md for a summary. All proto service methods should be annotated with google.api.http hints and path variables. When writing tests, always split the error cases into a different test. For example: ```go func TestThing(t *testing.T) { for _, tc := range []struct{ name string }{ {"test1"}, } { t.Run(tc.name, func() { got, err := Thing() if err != nil { t.Fatalf("Got err=%v; want nil", err)} }) } } func TestThingErrors(t *testing.T) { for _, tc := range []struct{ name string }{ {"test1"}, } { t.Run(tc.name, func() { _, err := Thing() if err == nil { t.Fatalf("Got nil err; want err")} // Test thing }) } } ``` ## Frontend/Typescript Do not alter package.json directly, instead, use the CLI tool `npm`. Write unit tests for all exported APIs. Never test private APIs. If it feels like we need to test private methods, refactor the code to make the difficult-to-test part of a new package. Prefer to keep the front-end code minimal. If there is a need to transform data, do that on the backend, and add a new API to load the transformed data.