This repository hosts the frontend (React, Vite) and backend (Go) code for the website (down for maintenance) that displays data from the main repository.
- Clone this repository.
- Create a service account on Firebase, and download the service account key.
- Name this file
service-account-key.json
and place it in the project root.
- Name this file
- Rename
.env.example
to.env
, after which:- Place the GitHub API URL to create new issues inside
.env
.- This URL ends with
/issues
, which is where new GitHub issues will be posted.
- This URL ends with
- Place the GitHUB PAT with
public_repo
access inside.env
.- The PAT authorizes access to make issues from the token creator's account.
- Create a Google Analytics 4 data stream, and place the measurement ID inside
.env
.
- Place the GitHub API URL to create new issues inside
- Navigate to the root directory and run
docker-compose up --build
. - The frontend is now accessible via
http://localhost:8080
. - To remove the containers, run
docker-compose down
.
The Go backend defines a RESTful API with multiple routes. An OpenAPI specification is available in /backend/docs/openapi.yaml
. The API is documented using Swagger UI, which is accessible at http://localhost:8080/api/docs
, where requests can be made and responses viewed. This is not available on the production website.
They are:
GET /api/internships
This route fetches data from the PostgreSQL database and returns it.
Periodically, the backend automatically fetches the Markdown file from the main repository, processes the table data into a list of opportunities separated into summer and off-cycle internship roles, and returns this.
Response body:
{
"data": [
{
"internship_id": 1,
"company": "Google",
"role": "Software Engineering Intern",
"link": "https://google.com/careers",
"date_added": "20 Aug 2023",
"is_summer": true
}
]
}
POST /api/internships
This route allows users to submit an opportunity to the main repository, by connecting to the GitHub API and creating a pre-formatted issue, allowing maintainers to easily update the Markdown file.
Request body:
{
"company": "Google",
"role": "Software Engineering Intern",
"link": "https://google.com/careers",
"is_summer": true
}
Response body:
{
"status": "OK"
}
GET /api/user
This route allows users to log in to the website using their Google account, and returns user data from the PostgreSQL database.
It requires an ID token from the frontend that is verified using the Google API. This token is placed in the Authorization
header as a Bearer token.
Return format:
{
"data": {
"user_id": "ABCD",
"statuses": {
"1": ["Applied", "OA"] // internship_id: statuses
},
}
}
POST /api/user/update
This route allows users to update their application status for a particular internship role. It requires an ID token from the frontend that is verified using the Google API. This token is placed in the Authorization
header as a Bearer token.
Request body:
{
"internship_id": 1,
"statuses": ["Applied", "OA"]
}
Response body:
{
"status": "OK"
}
Additional endpoints:
GET /api/ping
- Health check endpointGET /api/docs
- Swagger UI pageGET /api/docs/openapi.json
- OpenAPI specification
The React frontend pulls data from the backend API and renders it for the viewers, allowing them to search through available roles and open up applications directly. It also contains a form that allows users to submit new internship opportunities for addition into the main repository. A HTTP proxy is used to channel API requests to the Go backend.
The frontend and backend services run as Docker containers connected through a network in Docker Compose. This itself is running as a systemd service on a personal DigitalOcean droplet, and requests to the website and API are proxied through an Nginx reverse proxy configuration.