VA Springboard is a case-management application for Vision Aid. It includes:
- Google authentication and role-based access
- Student, beneficiary, device, school, grant, and training management
- Reporting and bulk import workflows
- Automated staging and production deployments through Coolify
-
Make sure you have the following setup and configured on your computer:
-
Clone the repo using either SSH, HTTPS, or Github Desktop
SSH
git clone git@github.com:C4G/va-springboard.git
HTTPS
git clone https://github.com/C4G/va-springboard.git
-
Copy
.env.exampleto.envand replace its placeholder credentials. -
Install all of the node dependencies with the following command
pnpm install
-
Make sure you have docker running and run the following command to initialize the database, apply all database schema, and seed some test users:
pnpm run init
Troubleshooting tips: Users have had success updating the following components in
docker-compose.yaml, within theva-springboard-dbsection: ports: - "${DATABASE_PORT:-5432}:5432" volumes: - va-springboard-db-data:/var/lib/postgresql -
If all is well up to this point your terminal should look like this:

-
Next, run the development server
pnpm dev
Open http://localhost:3000 with your browser to see the result.
-
Ask a C4G administrator to add your Google account to the application before signing in. See the section below if you are configuring a development account manually.
-
To access the database you can run the following command in a new terminal:
pnpm exec prisma studioIt should open the browser automatically or you can open http://localhost:5555/ to see the database tables.
You can start editing the page by modifying
src/app/page.tsx. The page auto-updates as you edit the file.This project uses
next/fontto automatically optimize and load Geist, a new font family for Vercel.
- Go to the User table using prisma studio.
- Click Add Record.
- Fill in the following fields:
- id – Enter a unique ID.
- name – Enter a name for the user.
- email – Enter your Google (Gmail) email address.
- emailVerified – Copy a value from an existing record.
- role – Copy a value from an existing record.
- Copy the id you created (you’ll need it for the next step).
- Save the record.
-
Go to the Account table using prisma studio.
-
Click Add Record.
-
Fill in the following fields:
- userId – Paste the
idfrom the User table. - id – Create a new unique ID.
- type – Copy from an existing record.
- provider – Copy from an existing record.
- token_type – Copy from an existing record.
- scope – Copy from an existing record.
- expires_at – Copy from an existing record.
- userId – Paste the
-
Leave the following fields blank for now:
- providerAccountId
- access_token
These will be populated using the Google OAuth Playground.
-
Go to the Google OAuth 2.0 Playground.
-
Under Google OAuth2 API v2, check the following scopes:
emailprofile
-
Click Authorize APIs and log in with your Gmail account.
-
Click Exchange authorization code for tokens.
-
In the right-hand panel:
- Copy the access_token.
- Paste it into the
access_tokenfield in the Account table.
-
In the Request URI field, enter: https://www.googleapis.com/oauth2/v2/userinfo
-
Click Send the Request.
-
In the response panel, locate the
idfield:- Copy this value.
- Paste it into the
providerAccountIdfield in the Account table.
-
Save the record.
-
Go back to the main application page and sign in again
This project uses trunk-based development. main is the only long-lived branch; work is merged through short-lived pull request branches.
Every push to main publishes two references for the same image:
ghcr.io/c4g/va-springboard:latestghcr.io/c4g/va-springboard:<commit-sha>
After the immutable image passes its smoke test, GitHub Actions automatically deploys latest to staging at https://va-springboard-staging.c4g.dev. Production is never triggered by GitHub Actions. To promote a tested build, set production's IMAGE_TAG to that build's commit SHA in Coolify and deploy it manually. This keeps promotion and rollback explicit without maintaining a release branch.
Staging and production must remain separate Coolify resources with separate databases, volumes, credentials, and OAuth callback URLs.
Create a staging environment in the public C4G/va-springboard repository and configure it with:
- Secret
COOLIFY_TOKEN: a Coolify API token (this may instead be an organization or repository secret). - Variable
COOLIFY_APP_UUID: the UUID of the staging Coolify Compose resource.
Give GitHub Actions read/write package permission. The package is published publicly with this repository, allowing Coolify to pull it without registry credentials. Protect main and require the pull-request validation workflow before merging.
Create two Docker Compose resources from this repository and set COMPOSE_PROFILES=production on each. Configure these values independently:
IMAGE_TAG: uselatestfor staging; use the promoted commit SHA for productionDATABASE_PW,DATABASE_USER, andDATABASE_NAMEDATABASE_PORT: leave empty unless the database must be exposed on the hostAPP_PORT: leave empty when using the Coolify proxyAUTH_SECRET,AUTH_GOOGLE_ID, andAUTH_GOOGLE_SECRETRESEND_API_KEYif email delivery is enabledAUTH_URLandNEXTAUTH_URL: the environment's public HTTPS URLAUTH_TRUST_HOST=trueBACKUP_MODE=requiredandBACKUP_KEEP=10
Disable Coolify's Git push auto-deployment for both resources. Staging is triggered through the Coolify API only after the published image passes its smoke test; production can then only be deployed manually.
Point each Coolify domain at port 3000 on va-springboard-app. Add both environment callback URLs to the Google OAuth client. The Compose stack takes and verifies a database dump before applying Prisma migrations; the backup volume is local to each environment.
To change this clone's remote after creating the public repository:
git remote set-url origin git@github.com:C4G/va-springboard.git- Nextjs - framework
- Typescript
- Tailwind - css atomic classes
- Prisma - db type ORM system
- Prettier - formatter
- ESLint - enforce rules / policies for maintable code
- Husky - allows for code changes during local commit
- Lint-Staged - lints code on only staged files with auto-fix
- Docker - containers
- Postgres - database
- Github Actions - ci/cd process
- Coolify - application deployment and routing
- Shadcn - UI component library
- RadixUI - UI component library
- Lucide-React - UI icons
- Next-Auth - authentication with google
- Ag-Grid - grid / table component
Use short-lived branches and pull requests for changes to VA Springboard. Keep main deployable at all times.