The vcassist backend.
- Install atlas.
- Run
go run ./devat the root of the repo, this starts grafana and some other telemetry stuff in a docker-compose. cd cmd/vc-serverandgo run . -v.
docs/- additional documentationproto/- protobuf definitions for servicescmd/- gRPC services: entrypoint + configuration loading + telemetry initvc-server/- a single binary monolith for Valley Christian Schools that strings together all the services underservices/vcmoodle-test/- a testing utility to scrape all the moodle courseslinker-cli/- the CLI tool for viewing and editing data linker behavior
services/- gRPC services: actual logicauth/- handles the authentication flow, issuing of tokens, and verification codesverifier/- exposes utilities to verify authentication tokens
keychain/- handles storing, retrieving, and refreshing user credentialslinker/- does data linkingvcsis/- implementation of a SIS service (fancy name for PowerSchool) for Valley Christian Schoolsvcmoodle/- stuff that powers quick moodleserver/- the service that provides an API for reading moodle datascraper/- a library that makes it easy to scrape moodle data
lib/- shared librariesscrapers/- bootleg APIs for various platforms.moodle/- moodlepowerschool/- powerschoolvcsnet/- vcs.net
configutil/- additional utilities for reading and resolving configuration.gradestore/- a simple time-series store for grade data.htmlutil/- additional utilities for working with HTML.oauth/- shared utils for working with oauth.restyutil/- utilities for therestyHTTP client wrapper.serviceutil/- additional utilities that are commonly used in service entrypoints.sqliteutil/- utilities for opening up and migrating sqlite databasestelemetry/- telemetry setup/teardown as well as misc. instrumentation utilitiestextutil/- utilities for cleaning and processing text.timezone/-time.Now()always in the correct timezone, instead of system time. (because sometimes servers are hosted outside of PDT)
dev/- go scripts for setting up the development environmentlocal_stack/- docker compose stuff for setting up grafana and other things locally
buf.yaml- buf.yamlbuf.gen-go.yaml- buf.gen.yaml for golang codebuf.gen-ts.yaml- buf.gen.yaml for typescript codesqlc.yaml- sqlc.yamltelemetry.json5- configuration of telemetry for development
Here are some commands relating to linting and code generation that will probably be useful.
go vet ./...- typecheck all go packagessqlc generate- generate sql wrapper code with sqlcconnectrpc-otel-gen .- generates opentelemetry wrapper code for all gRPC services (you should run this every time you change.protofiles)buf lint- lint protobuf files with bufbuf format -w- format protobuf filesbuf generate --template buf.gen-go.yaml- generate golang protobuf code with bufbuf generate --template buf.gen-ts.yaml- generate typescript protobuf code with bufprotogetter --fix ./...- makes sure you useGetmethods on protobufs to prevent nil pointer dereference when chaining stuff together
Note
To use these commands you'll need to install their respective CLI binaries.
go install github.com/sqlc-dev/sqlc/cmd/sqlc@latestgo install github.com/bufbuild/buf/cmd/buf@v1.33.0go install github.com/ghostiam/protogetter/cmd/protogetter@latestgo install github.com/LQR471814/connectrpc-otel-gen@latest- atlas
go test ./lib/... ./services/auth- runs all tests that don't require manual interactiongo test -v ./services/vcsis- runs the tests for powerschool scraping, this is kept separately from the rest of the tests because it requires you to sign in with powerschool manually which doesn't work out that well if you're testing everything all at oncego clean -testcache- cleans test cache, may be useful if telemetry isn't working
Note
It is not a good idea to run tests from a directory other than root, this is because many temporary and local files are resolved relative to the current working directory so you may find unexpected issues!
We use sqlc as a code generation tool to generate the "data layer" (the part that's only concerned with interfacing with the database which provides a high-level api to insert/delete/create for the rest of the code) of the backend.
As such, there's a specific way you must setup your database schema/operations so that sqlc can generate the code for it properly, that is as follows.
- Create a
dbdirectory (usually in the directory of the service/package using it). - Create a file called
schema.sqland a file calledquery.sqlinside thedbdirectory. - The
schema.sqlfile will contain all yourcreate table ...statements forming your database schema while thequery.sqlfile will contain all the operations that need to have wrappers code-generated for them. - Then, in the
sqlc.yamldirectory, add another entry alongside the existing entries whereengine: "sqlite"with thequeriesandschemafield changed to the correct paths. - When you have added at least 1 table to
schema.sqland 1 operation toquery.sql, you can runsqlc generateand obtain your generated wrapper code.
Creating a new service at a high level, involves 3 steps.
- Defining gRPC shape.
- Creating a protobuf definition of the service under
/proto/vcassist/services/<service_name>/v1/<...>.proto. - Running
buf generate --template buf.gen-go.yaml. - Running
buf generate --template buf.gen-ts.yaml(you don't need to do this if the service is internal, that is, if the frontend will not directly call your service).
- Creating a protobuf definition of the service under
- Setting up service logic.
- Creating a directory for your service logic under
/services/<service_name>. - Adding a
/services/<service_name>/dbsubdirectory to hold yourschema.sqlandquery.sql(don't do this if you do not need a DB).
- Creating a directory for your service logic under